4 * Part of gwm, the Gratuitous Window Manager,
5 * by Gary Wong, <gtw@gnu.org>.
7 * Copyright (C) 2009 Gary Wong
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of version 3 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
40 #include "window-table.h"
42 static void external_command( char *name
, ... ) {
49 va_start( val
, name
);
50 for( n
= 0; va_arg( val
, char * ); n
++ )
54 args
= alloca( ( n
+ 2 ) * sizeof *args
);
58 va_start( val
, name
);
60 while( ( args
[ n
++ ] = va_arg( val
, char * ) ) )
72 extern void action_raise_lowest( struct gwm_window
*window
,
73 xcb_generic_event_t
*ev
,
74 union callback_param cp
) {
76 xcb_circulate_window( c
, XCB_CIRCULATE_RAISE_LOWEST
,
77 screens
[ window
->screen
]->root
);
80 extern void action_stack_opposite( struct gwm_window
*window
,
81 xcb_generic_event_t
*ev
,
82 union callback_param cp
) {
84 if( window
->type
== WINDOW_FRAME
) {
85 uint32_t n
= XCB_STACK_MODE_OPPOSITE
;
87 xcb_configure_window( c
, window
->w
, XCB_CONFIG_WINDOW_STACK_MODE
,
92 extern void action_root_menu( struct gwm_window
*window
,
93 xcb_generic_event_t
*ev
,
94 union callback_param cp
) {
96 /* FIXME this should be configurable, of course */
97 const struct menuitem root_menu
[] = {
98 { "Map all icons", action_map_all_icons
},
99 { "Raise lowest window", action_raise_lowest
},
100 { "xterm", action_start_xterm
},
102 { "Exit", action_exit
}
105 popup_menu( window
, ev
, sizeof root_menu
/ sizeof *root_menu
, root_menu
);
108 extern void action_iconify_window( struct gwm_window
*window
,
109 xcb_generic_event_t
*ev
,
110 union callback_param cp
) {
112 if( window
->type
== WINDOW_FRAME
)
113 window
= window
->u
.frame
.child
;
115 if( window
->type
== WINDOW_MANAGED
&&
116 window
->u
.managed
.state
== STATE_NORMAL
)
117 normal_to_iconic( window
);
120 extern void action_deiconify_window( struct gwm_window
*window
,
121 xcb_generic_event_t
*ev
,
122 union callback_param cp
) {
124 if( window
->type
== WINDOW_FRAME
)
125 window
= window
->u
.frame
.child
;
127 if( window
->type
== WINDOW_MANAGED
&&
128 window
->u
.managed
.state
== STATE_ICONIC
)
129 iconic_to_normal( window
);
132 extern void action_map_raise( struct gwm_window
*window
,
133 xcb_generic_event_t
*ev
,
134 union callback_param cp
) {
136 if( window
->type
== WINDOW_FRAME
)
137 window
= window
->u
.frame
.child
;
139 if( window
->type
== WINDOW_MANAGED
) {
142 n
= XCB_STACK_MODE_ABOVE
;
143 xcb_configure_window( c
, window
->u
.managed
.frame
->w
,
144 XCB_CONFIG_WINDOW_STACK_MODE
, &n
);
146 if( window
->u
.managed
.state
== STATE_ICONIC
)
147 iconic_to_normal( window
);
151 extern void action_map_all_icons( struct gwm_window
*window
,
152 xcb_generic_event_t
*ev
,
153 union callback_param cp
) {
157 for( i
= 0; i
< windows
.used
; i
++ )
158 if( windows
.values
[ i
]->type
== WINDOW_MANAGED
&&
159 windows
.values
[ i
]->u
.managed
.state
== STATE_ICONIC
)
160 iconic_to_normal( windows
.values
[ i
] );
163 extern void action_start_xterm( struct gwm_window
*window
,
164 xcb_generic_event_t
*ev
,
165 union callback_param cp
) {
167 external_command( "xterm", NULL
);
170 extern void action_window_menu( struct gwm_window
*window
,
171 xcb_generic_event_t
*ev
,
172 union callback_param cp
) {
174 /* FIXME this should be configurable, of course */
175 const struct menuitem window_menu
[] = {
176 { "Iconify", action_iconify_window
},
177 { "Raise/lower", action_stack_opposite
}
180 popup_menu( window
, ev
, sizeof window_menu
/ sizeof *window_menu
,
184 static void window_list_activate( struct gwm_window
*window
,
185 xcb_generic_event_t
*ev
,
186 union callback_param cp
) {
188 struct gwm_window
*window_param
;
190 if( ( window_param
= lookup_window( cp
.l
) ) ) {
191 union callback_param param
;
194 action_map_raise( window_param
, ev
, param
);
198 extern void action_window_list_menu( struct gwm_window
*window
,
199 xcb_generic_event_t
*ev
,
200 union callback_param cp
) {
203 struct menuitem
*items
;
205 for( i
= 0, num_items
= 0; i
< windows
.used
; i
++ )
206 if( windows
.values
[ i
]->type
== WINDOW_MANAGED
)
209 items
= alloca( num_items
* sizeof *items
);
211 for( i
= 0, num_items
= 0; i
< windows
.used
; i
++ )
212 if( windows
.values
[ i
]->type
== WINDOW_MANAGED
) {
213 struct gwm_window
*managed
= windows
.values
[ i
];
214 char *name
= managed
->u
.managed
.name
? managed
->u
.managed
.name
:
217 if( managed
->u
.managed
.state
== STATE_ICONIC
) {
218 int len
= strlen( name
);
219 char *new = alloca( len
+ 3 );
222 strcpy( new + 1, name
);
223 new[ len
+ 1 ] = ']';
229 items
[ num_items
].label
= name
;
230 items
[ num_items
].action
= window_list_activate
;
231 items
[ num_items
].cp
.l
= managed
->w
;
232 items
[ num_items
].icon
= managed
;
237 popup_menu( window
, ev
, num_items
, items
);
240 extern void action_exit( struct gwm_window
*window
, xcb_generic_event_t
*ev
,
241 union callback_param cp
) {
243 /* FIXME prompt for confirmation of exit */
248 /* FIXME make the current frame bindings (move, resize, close?) actions too */