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/>.
34 #include "window-table.h"
36 static void root_key_press( struct gwm_window
*window
,
37 xcb_key_press_event_t
*ev
) {
41 for( i
= 0; i
< NUM_KEY_ACTIONS
; i
++ )
42 if( keyboard_map
[ ev
->detail
][ 0 ] == key_actions
[ i
].keysym
&&
43 ( ev
->state
& 0xFF & key_actions
[ i
].modifiers
) ==
44 key_actions
[ i
].modifiers
) {
45 key_actions
[ i
].handler( window
, (xcb_generic_event_t
*) ev
);
51 static const struct button_action
{
53 xcb_mod_mask_t modifiers
;
54 void ( *handler
)( struct gwm_window
*window
, xcb_generic_event_t
*ev
);
55 } button_actions
[] = {
56 /* FIXME This table should be configurable, of course. */
57 { 1, 0, action_map_all_icons
},
58 { 3, 0, action_start_xterm
}
61 #define NUM_BUTTON_ACTIONS ( sizeof button_actions / sizeof *button_actions )
63 static void root_button_press( struct gwm_window
*window
,
64 xcb_button_press_event_t
*ev
) {
71 for( i
= 0; i
< NUM_BUTTON_ACTIONS
; i
++ )
72 if( ev
->detail
== button_actions
[ i
].button
&&
73 ( ev
->state
& 0xFF & button_actions
[ i
].modifiers
) ==
74 button_actions
[ i
].modifiers
) {
75 button_actions
[ i
].handler( window
, (xcb_generic_event_t
*) ev
);
81 static void root_enter_notify( struct gwm_window
*window
,
82 xcb_enter_notify_event_t
*ev
) {
84 if( focus_frame
&& ( ev
->detail
== XCB_NOTIFY_DETAIL_INFERIOR
||
85 ev
->detail
== XCB_NOTIFY_DETAIL_NONLINEAR
) ) {
86 deactivate_focus_frame();
88 xcb_set_input_focus( c
, XCB_INPUT_FOCUS_NONE
,
89 XCB_INPUT_FOCUS_POINTER_ROOT
, ev
->time
);
94 install_window_colormap( window
->screen
, NULL
, ev
->time
);
97 static void root_circulate_request( struct gwm_window
*window
,
98 xcb_circulate_request_event_t
*ev
) {
100 uint32_t value
= ev
->place
== XCB_PLACE_ON_TOP
? XCB_STACK_MODE_ABOVE
:
101 XCB_STACK_MODE_BELOW
;
103 /* Circulating children of the root -- honour the request as is. */
104 xcb_configure_window( c
, ev
->window
, XCB_CONFIG_WINDOW_STACK_MODE
,
108 static void root_synthetic( struct gwm_window
*root
,
109 xcb_generic_event_t
*ev
) {
111 xcb_unmap_notify_event_t
*unmap
= (xcb_unmap_notify_event_t
*) ev
;
112 xcb_configure_request_event_t
*config
=
113 (xcb_configure_request_event_t
*) ev
;
114 struct gwm_window
*window
;
116 switch( ev
->response_type
& ~SEND_EVENT_MASK
) {
117 case XCB_UNMAP_NOTIFY
:
118 /* Handle a synthetic UnmapNotify request to move a window to
119 the Withdrawn state (see ICCCM 2.0, section 4.1.4). */
120 if( ( window
= lookup_window( unmap
->window
) ) &&
121 window
->type
== WINDOW_MANAGED
)
122 unmanage_window( window
);
126 case XCB_CONFIGURE_REQUEST
:
127 /* Handle a synthetic ConfigureRequest, which should be used
128 only to restack managed windows relative to windows which
129 were originally siblings (see ICCCM 4.1.5). */
130 if( ( config
->value_mask
& XCB_CONFIG_WINDOW_STACK_MODE
) &&
131 ( window
= lookup_window( config
->window
) ) &&
132 window
->type
== WINDOW_MANAGED
) {
133 struct gwm_window
*sibling
;
134 uint32_t values
[ 2 ];
136 if( ( sibling
= lookup_window( config
->sibling
) ) &&
137 sibling
->type
== WINDOW_MANAGED
)
138 sibling
= sibling
->u
.managed
.frame
;
140 values
[ 0 ] = sibling
? sibling
->w
: config
->sibling
;
141 values
[ 1 ] = config
->stack_mode
;
143 handle_error_reply( xcb_configure_window(
144 c
, window
->u
.managed
.frame
->w
,
145 XCB_CONFIG_WINDOW_SIBLING
|
146 XCB_CONFIG_WINDOW_STACK_MODE
,
148 ERR_MASK_VALUE
| ERR_MASK_WINDOW
|
156 event_handler root_handlers
[] = {
159 (event_handler
) root_key_press
,
160 NULL
, /* KeyRelease */
161 (event_handler
) root_button_press
,
162 NULL
, /* ButtonRelease */
163 NULL
, /* MotionNotify */
164 (event_handler
) root_enter_notify
,
165 NULL
, /* LeaveNotify */
168 NULL
, /* KeymapNotify */
170 NULL
, /* GraphicsExpose */
171 NULL
, /* NoExposure */
172 NULL
, /* VisibilityNotify */
173 NULL
, /* CreateNotify */
174 NULL
, /* DestroyNotify */
175 NULL
, /* UnmapNotify */
176 NULL
, /* MapNotify */
177 (event_handler
) withdrawn_map_request
,
178 NULL
, /* ReparentNotify */
179 NULL
, /* ConfigureNotify */
180 (event_handler
) withdrawn_configure_request
,
181 NULL
, /* GravityNotify */
182 NULL
, /* ResizeRequest */
183 NULL
, /* CirculateNotify */
184 (event_handler
) root_circulate_request
,
185 NULL
, /* PropertyNotify */
186 NULL
, /* SelectionClear */
187 NULL
, /* SelectionRequest */
188 NULL
, /* SelectionNotify */
189 NULL
, /* ColormapNotify */
190 NULL
, /* ClientMessage */
191 NULL
, /* MappingNotify */
192 (event_handler
) root_synthetic
,
193 NULL
/* ShapeNotify */