Add notes and placeholders for future modifications.
[gwm.git] / root.c
bloba3d865ded80d31e7411367ac3fc060b6ace688e5
1 /*
2 * root.c
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/>.
21 * $Id$
24 #include <config.h>
26 #include <xcb/xcb.h>
28 #include "gwm.h"
30 #include "actions.h"
31 #include "keyboard.h"
32 #include "root.h"
33 #include "window-table.h"
35 static void root_key_press( struct gwm_window *window,
36 xcb_key_press_event_t *ev ) {
38 int i;
40 for( i = 0; i < NUM_KEY_ACTIONS; i++ )
41 if( keyboard_map[ ev->detail ][ 0 ] == key_actions[ i ].keysym &&
42 ( ev->state & 0xFF & key_actions[ i ].modifiers ) ==
43 key_actions[ i ].modifiers ) {
44 key_actions[ i ].handler( window, (xcb_generic_event_t *) ev );
46 break;
50 static const struct button_action {
51 int button;
52 xcb_mod_mask_t modifiers;
53 void ( *handler )( struct gwm_window *window, xcb_generic_event_t *ev );
54 } button_actions[] = {
55 /* FIXME This table should be configurable, of course. */
56 { 1, 0, action_map_all_icons },
57 { 3, 0, action_start_xterm }
60 #define NUM_BUTTON_ACTIONS ( sizeof button_actions / sizeof *button_actions )
62 static void root_button_press( struct gwm_window *window,
63 xcb_button_press_event_t *ev ) {
65 int i;
67 if( ev->child )
68 return;
70 for( i = 0; i < NUM_BUTTON_ACTIONS; i++ )
71 if( ev->detail == button_actions[ i ].button &&
72 ( ev->state & 0xFF & button_actions[ i ].modifiers ) ==
73 button_actions[ i ].modifiers ) {
74 button_actions[ i ].handler( window, (xcb_generic_event_t *) ev );
76 break;
80 static void root_enter_notify( struct gwm_window *window,
81 xcb_enter_notify_event_t *ev ) {
83 if( focus_frame && ( ev->detail == XCB_NOTIFY_DETAIL_INFERIOR ||
84 ev->detail == XCB_NOTIFY_DETAIL_NONLINEAR ) ) {
85 deactivate_focus_frame();
87 xcb_set_input_focus( c, XCB_INPUT_FOCUS_NONE,
88 XCB_INPUT_FOCUS_POINTER_ROOT, ev->time );
90 focus_frame = NULL;
93 install_window_colormap( window->screen, NULL, ev->time );
96 static void root_map_request( struct gwm_window *window,
97 xcb_map_request_event_t *ev ) {
99 manage_window( ev->window, TRUE );
102 static void root_configure_request( struct gwm_window *window,
103 xcb_configure_request_event_t *ev ) {
104 int i = 0;
105 uint32_t values[ 7 ];
107 /* Configuring an unmanaged window -- just honour the request as is. */
108 if( ev->value_mask & XCB_CONFIG_WINDOW_X )
109 values[ i++ ] = ev->x;
110 if( ev->value_mask & XCB_CONFIG_WINDOW_Y )
111 values[ i++ ] = ev->y;
112 if( ev->value_mask & XCB_CONFIG_WINDOW_WIDTH )
113 values[ i++ ] = ev->width;
114 if( ev->value_mask & XCB_CONFIG_WINDOW_HEIGHT )
115 values[ i++ ] = ev->height;
116 if( ev->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH )
117 values[ i++ ] = ev->border_width;
118 if( ev->value_mask & XCB_CONFIG_WINDOW_SIBLING )
119 values[ i++ ] = ev->sibling;
120 if( ev->value_mask & XCB_CONFIG_WINDOW_STACK_MODE )
121 values[ i++ ] = ev->stack_mode;
123 xcb_configure_window( c, ev->window, ev->value_mask, values );
126 static void root_circulate_request( struct gwm_window *window,
127 xcb_circulate_request_event_t *ev ) {
129 uint32_t value = ev->place == XCB_PLACE_ON_TOP ? XCB_STACK_MODE_ABOVE :
130 XCB_STACK_MODE_BELOW;
132 /* Circulating children of the root -- honour the request as is. */
133 xcb_configure_window( c, ev->window, XCB_CONFIG_WINDOW_STACK_MODE,
134 &value );
137 static void root_synthetic( struct gwm_window *root,
138 xcb_generic_event_t *ev ) {
140 xcb_unmap_notify_event_t *unmap = (xcb_unmap_notify_event_t *) ev;
141 xcb_configure_request_event_t *config =
142 (xcb_configure_request_event_t *) ev;
143 struct gwm_window *window;
145 switch( ev->response_type & ~SEND_EVENT_MASK ) {
146 case XCB_UNMAP_NOTIFY:
147 /* Handle a synthetic UnmapNotify request to move a window to
148 the Withdrawn state (see ICCCM 2.0, section 4.1.4). */
149 if( ( window = lookup_window( unmap->window ) ) &&
150 window->type == WINDOW_MANAGED )
151 unmanage_window( window );
153 break;
155 case XCB_CONFIGURE_REQUEST:
156 /* Handle a synthetic ConfigureRequest, which should be used
157 only to restack managed windows relative to windows which
158 were originally siblings (see ICCCM 4.1.5). */
159 if( ( config->value_mask & XCB_CONFIG_WINDOW_STACK_MODE ) &&
160 ( window = lookup_window( config->window ) ) &&
161 window->type == WINDOW_MANAGED ) {
162 struct gwm_window *sibling;
163 uint32_t values[ 2 ];
165 if( ( sibling = lookup_window( config->sibling ) ) &&
166 sibling->type == WINDOW_MANAGED )
167 sibling = sibling->u.managed.frame;
169 values[ 0 ] = sibling ? sibling->w : config->sibling;
170 values[ 1 ] = config->stack_mode;
172 handle_error_reply( xcb_configure_window(
173 c, window->u.managed.frame->w,
174 XCB_CONFIG_WINDOW_SIBLING |
175 XCB_CONFIG_WINDOW_STACK_MODE,
176 values ),
177 ERR_MASK_VALUE | ERR_MASK_WINDOW |
178 ERR_MASK_MATCH );
181 break;
185 event_handler root_handlers[] = {
186 NULL, /* Error */
187 NULL, /* Reply */
188 (event_handler) root_key_press,
189 NULL, /* KeyRelease */
190 (event_handler) root_button_press,
191 NULL, /* ButtonRelease */
192 NULL, /* MotionNotify */
193 (event_handler) root_enter_notify,
194 NULL, /* LeaveNotify */
195 NULL, /* FocusIn */
196 NULL, /* FocusOut */
197 NULL, /* KeymapNotify */
198 NULL, /* Expose */
199 NULL, /* GraphicsExpose */
200 NULL, /* NoExposure */
201 NULL, /* VisibilityNotify */
202 NULL, /* CreateNotify */
203 NULL, /* DestroyNotify */
204 NULL, /* UnmapNotify */
205 NULL, /* MapNotify */
206 (event_handler) root_map_request,
207 NULL, /* ReparentNotify */
208 NULL, /* ConfigureNotify */
209 (event_handler) root_configure_request,
210 NULL, /* GravityNotify */
211 NULL, /* ResizeRequest */
212 NULL, /* CirculateNotify */
213 (event_handler) root_circulate_request,
214 NULL, /* PropertyNotify */
215 NULL, /* SelectionClear */
216 NULL, /* SelectionRequest */
217 NULL, /* SelectionNotify */
218 NULL, /* ColormapNotify */
219 NULL, /* ClientMessage */
220 NULL, /* MappingNotify */
221 (event_handler) root_synthetic,
222 NULL /* ShapeNotify */