Add notes and placeholders for future modifications.
[gwm.git] / button.c
blob8b0d57202e815375e49b0c86e7bfa1aba0a24223
1 /*
2 * button.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 "button.h"
31 #include "window-table.h"
33 static int button_active;
35 static void set_button_active( struct gwm_window *window, int new ) {
37 uint32_t n;
39 if( new == button_active )
40 return;
42 n = gwm_screens[ window->screen ].pixels[ ( button_active = new ) ?
43 COL_BUTTON_ACTIVE :
44 COL_BUTTON_INACTIVE ];
45 xcb_change_window_attributes( c, window->w, XCB_CW_BACK_PIXEL, &n );
47 queue_window_update( window, 0, 0, FRAME_BUTTON_SIZE, FRAME_BUTTON_SIZE,
48 FALSE );
51 static void button_button_press( struct gwm_window *window,
52 xcb_button_press_event_t *ev ) {
54 if( initial_press( ev ) )
55 /* No buttons were pressed; grab initiates. */
56 set_button_active( window, TRUE );
58 if( ev->detail == 3 && ( window->u.button.frame->u.frame.child->
59 u.managed.protocols & PROTOCOL_DELETE_WINDOW ) )
60 /* Button 3 will kill the client, even if it supports WM_DELETE_WINDOW.
61 Change to CURSOR_DESTROY to indicate the distinction. */
62 xcb_change_active_pointer_grab( c, cursors[ CURSOR_DESTROY ],
63 ev->time, XCB_EVENT_MASK_BUTTON_PRESS |
64 XCB_EVENT_MASK_BUTTON_RELEASE |
65 XCB_EVENT_MASK_ENTER_WINDOW |
66 XCB_EVENT_MASK_LEAVE_WINDOW );
69 static void button_button_release( struct gwm_window *window,
70 xcb_button_release_event_t *ev ) {
72 if( final_release( ev ) ) {
73 /* Final button released; grab terminates. */
74 if( button_active ) {
75 if( ev->detail == 3 || !( window->u.button.frame->u.frame.child->
76 u.managed.protocols &
77 PROTOCOL_DELETE_WINDOW ) )
78 xcb_kill_client( c, window->u.button.frame->u.frame.child->w );
79 else {
80 xcb_client_message_event_t msg;
81 struct gwm_window *frame = window->u.button.frame;
83 msg.response_type = XCB_CLIENT_MESSAGE;
84 msg.format = 32;
85 msg.sequence = 0;
86 msg.window = frame->u.frame.child->w;
87 msg.type = atoms[ ATOM_WM_PROTOCOLS ];
88 msg.data.data32[ 0 ] = atoms[ ATOM_WM_DELETE_WINDOW ];
89 msg.data.data32[ 1 ] = ev->time;
90 msg.data.data32[ 2 ] = 0;
91 msg.data.data32[ 3 ] = 0;
92 msg.data.data32[ 4 ] = 0;
94 xcb_send_event( c, FALSE, frame->u.frame.child->w, 0,
95 (char *) &msg );
98 set_button_active( window, FALSE );
100 } else if( ev->detail == 3 && ( window->u.button.frame->u.frame.child->
101 u.managed.protocols &
102 PROTOCOL_DELETE_WINDOW ) )
103 /* Button 3 released; we'll no longer kill the client. Remove
104 the temporary CURSOR_DESTROY. */
105 xcb_change_active_pointer_grab( c, XCB_NONE, ev->time,
106 XCB_EVENT_MASK_BUTTON_PRESS |
107 XCB_EVENT_MASK_BUTTON_RELEASE |
108 XCB_EVENT_MASK_ENTER_WINDOW |
109 XCB_EVENT_MASK_LEAVE_WINDOW );
112 static void button_enter_notify( struct gwm_window *window,
113 xcb_enter_notify_event_t *ev ) {
115 set_button_active( window, TRUE );
118 static void button_leave_notify( struct gwm_window *window,
119 xcb_leave_notify_event_t *ev ) {
121 set_button_active( window, FALSE );
124 event_handler button_handlers[] = {
125 NULL, /* Error */
126 NULL, /* Reply */
127 NULL, /* KeyPress */
128 NULL, /* KeyRelease */
129 (event_handler) button_button_press,
130 (event_handler) button_button_release,
131 NULL, /* MotionNotify */
132 (event_handler) button_enter_notify,
133 (event_handler) button_leave_notify,
134 NULL, /* FocusIn */
135 NULL, /* FocusOut */
136 NULL, /* KeymapNotify */
137 NULL, /* Expose */
138 NULL, /* GraphicsExpose */
139 NULL, /* NoExposure */
140 NULL, /* VisibilityNotify */
141 NULL, /* CreateNotify */
142 NULL, /* DestroyNotify */
143 NULL, /* UnmapNotify */
144 NULL, /* MapNotify */
145 NULL, /* MapRequest */
146 NULL, /* ReparentNotify */
147 NULL, /* ConfigureNotify */
148 NULL, /* ConfigureRequest */
149 NULL, /* GravityNotify */
150 NULL, /* ResizeRequest */
151 NULL, /* CirculateNotify */
152 NULL, /* CirculateRequest */
153 NULL, /* PropertyNotify */
154 NULL, /* SelectionClear */
155 NULL, /* SelectionRequest */
156 NULL, /* SelectionNotify */
157 NULL, /* ColormapNotify */
158 NULL, /* ClientMessage */
159 NULL, /* MappingNotify */
160 NULL /* (synthetic) */