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/>.
31 #include "window-table.h"
33 static int button_active
;
35 static void set_button_active( struct gwm_window
*window
, int new ) {
39 if( new == button_active
)
42 n
= gwm_screens
[ window
->screen
].pixels
[ ( button_active
= new ) ?
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
,
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. */
75 if( ev
->detail
== 3 || !( window
->u
.button
.frame
->u
.frame
.child
->
77 PROTOCOL_DELETE_WINDOW
) )
78 xcb_kill_client( c
, window
->u
.button
.frame
->u
.frame
.child
->w
);
80 xcb_client_message_event_t msg
;
81 struct gwm_window
*frame
= window
->u
.button
.frame
;
83 msg
.response_type
= XCB_CLIENT_MESSAGE
;
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,
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
[] = {
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
,
136 NULL
, /* KeymapNotify */
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) */