8
8
static xcb_connection_t * dpy ;
9
9
static xcb_screen_t * scre ;
10
10
static xcb_drawable_t win ;
11
- static xcb_drawable_t winprev ;
12
- static xcb_drawable_t root ;
13
11
static uint32_t values [3 ];
14
12
15
13
static void killclient (char * * com ) {
@@ -25,7 +23,7 @@ static void closewm(char **com) {
25
23
static void spawn (char * * com ) {
26
24
if (fork () == 0 ) {
27
25
if (dpy != NULL ) {
28
- close (root );
26
+ close (scre -> root );
29
27
}
30
28
setsid ();
31
29
execvp ((char * )com [0 ], (char * * )com );
@@ -47,38 +45,46 @@ static void handleButtonPress(xcb_generic_event_t * ev) {
47
45
xcb_warp_pointer (dpy , XCB_NONE , win , 0 , 0 , 0 , 0 , geom -> width , geom -> height );
48
46
}
49
47
else {}
50
- xcb_grab_pointer (dpy , 0 , root , XCB_EVENT_MASK_BUTTON_RELEASE
48
+ xcb_grab_pointer (dpy , 0 , scre -> root , XCB_EVENT_MASK_BUTTON_RELEASE
51
49
| XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT ,
52
- XCB_GRAB_MODE_ASYNC , XCB_GRAB_MODE_ASYNC , root , XCB_NONE , XCB_CURRENT_TIME );
50
+ XCB_GRAB_MODE_ASYNC , XCB_GRAB_MODE_ASYNC , scre -> root , XCB_NONE , XCB_CURRENT_TIME );
51
+ }
52
+
53
+ static void moveWindow (xcb_query_pointer_reply_t * poin ) {
54
+ xcb_get_geometry_cookie_t geom_now = xcb_get_geometry (dpy , win );
55
+ xcb_get_geometry_reply_t * geom = xcb_get_geometry_reply (dpy , geom_now , NULL );
56
+ values [0 ] = ((poin -> root_x + geom -> width ) > scre -> width_in_pixels ) ?
57
+ (scre -> width_in_pixels - geom -> width ) : poin -> root_x ;
58
+ values [1 ] = ((poin -> root_y + geom -> height ) > scre -> height_in_pixels ) ?
59
+ (scre -> height_in_pixels - geom -> height ) : poin -> root_y ;
60
+ xcb_configure_window (dpy , win , XCB_CONFIG_WINDOW_X
61
+ | XCB_CONFIG_WINDOW_Y , values );
62
+ }
63
+
64
+ static void resizeWindow (xcb_query_pointer_reply_t * poin ) {
65
+ xcb_get_geometry_cookie_t geom_now = xcb_get_geometry (dpy , win );
66
+ xcb_get_geometry_reply_t * geom = xcb_get_geometry_reply (dpy , geom_now , NULL );
67
+ if (!((poin -> root_x <= geom -> x ) || (poin -> root_y <= geom -> y ))) {
68
+ values [0 ] = poin -> root_x - geom -> x ;
69
+ values [1 ] = poin -> root_y - geom -> y ;
70
+ uint32_t min_x = WINDOW_MIN_WIDTH ;
71
+ uint32_t min_y = WINDOW_MIN_HEIGHT ;
72
+ if ((values [0 ] >= min_x ) && (values [1 ] >= min_y )) {
73
+ xcb_configure_window (dpy , win , XCB_CONFIG_WINDOW_WIDTH
74
+ | XCB_CONFIG_WINDOW_HEIGHT , values );
75
+ }
76
+ }
53
77
}
54
78
55
79
static void handleMotionNotify (xcb_generic_event_t * ev ) {
56
- xcb_query_pointer_cookie_t coord = xcb_query_pointer (dpy , root );
80
+ xcb_query_pointer_cookie_t coord = xcb_query_pointer (dpy , scre -> root );
57
81
xcb_query_pointer_reply_t * poin = xcb_query_pointer_reply (dpy , coord , 0 );
58
82
uint32_t val [2 ] = {1 , 3 };
59
83
if ((values [2 ] == val [0 ]) && (win != 0 )) {
60
- xcb_get_geometry_cookie_t geom_now = xcb_get_geometry (dpy , win );
61
- xcb_get_geometry_reply_t * geom = xcb_get_geometry_reply (dpy , geom_now , NULL );
62
- values [0 ] = ((poin -> root_x + geom -> width ) > scre -> width_in_pixels ) ?
63
- (scre -> width_in_pixels - geom -> width ) : poin -> root_x ;
64
- values [1 ] = ((poin -> root_y + geom -> height ) > scre -> height_in_pixels ) ?
65
- (scre -> height_in_pixels - geom -> height ) : poin -> root_y ;
66
- xcb_configure_window (dpy , win , XCB_CONFIG_WINDOW_X
67
- | XCB_CONFIG_WINDOW_Y , values );
84
+ moveWindow (poin );
68
85
}
69
86
if ((values [2 ] == val [1 ]) && (win != 0 )) {
70
- xcb_get_geometry_cookie_t geom_now = xcb_get_geometry (dpy , win );
71
- xcb_get_geometry_reply_t * geom = xcb_get_geometry_reply (dpy , geom_now , NULL );
72
- if (!((poin -> root_x <= geom -> x ) || (poin -> root_y <= geom -> y ))) {
73
- values [0 ] = poin -> root_x - geom -> x ;
74
- values [1 ] = poin -> root_y - geom -> y ;
75
- uint32_t min_x = WINDOW_MIN_WIDTH ;
76
- uint32_t min_y = WINDOW_MIN_HEIGHT ;
77
- if ((values [0 ] >= min_x ) && (values [1 ] >= min_y )) {
78
- xcb_configure_window (dpy , win , XCB_CONFIG_WINDOW_WIDTH
79
- | XCB_CONFIG_WINDOW_HEIGHT , values );
80
- }
81
- }
87
+ resizeWindow (poin );
82
88
}
83
89
}
84
90
@@ -99,14 +105,10 @@ static xcb_keysym_t xcb_get_keysym(xcb_keycode_t keycode) {
99
105
}
100
106
101
107
static void setFocus (xcb_drawable_t window ) {
102
- if ((window != 0 ) && (window != root )) {
108
+ if ((window != 0 ) && (window != scre -> root )) {
103
109
xcb_set_input_focus (dpy , XCB_INPUT_FOCUS_POINTER_ROOT , window ,
104
110
XCB_CURRENT_TIME );
105
111
}
106
- setBorderColor (window , 1 );
107
- if (winprev != window ) {
108
- setBorderColor (winprev , 0 );
109
- }
110
112
}
111
113
112
114
static void setBorderColor (xcb_window_t window , int focus ) {
@@ -155,11 +157,6 @@ static void handleEnterNotify(xcb_generic_event_t * ev) {
155
157
setFocus (e -> event );
156
158
}
157
159
158
- static void handleLeaveNotify (xcb_generic_event_t * ev ) {
159
- xcb_leave_notify_event_t * e = ( xcb_leave_notify_event_t * ) ev ;
160
- winprev = e -> event ;
161
- }
162
-
163
160
static void handleButtonRelease (xcb_generic_event_t * ev ) {
164
161
xcb_ungrab_pointer (dpy , XCB_CURRENT_TIME );
165
162
}
@@ -173,12 +170,22 @@ static void handleDestroyNotify(xcb_generic_event_t * ev) {
173
170
xcb_kill_client (dpy , e -> window );
174
171
}
175
172
173
+ static void handleFocusIn (xcb_generic_event_t * ev ) {
174
+ xcb_focus_in_event_t * e = (xcb_focus_in_event_t * ) ev ;
175
+ setBorderColor (e -> event , 1 );
176
+ }
177
+
178
+ static void handleFocusOut (xcb_generic_event_t * ev ) {
179
+ xcb_focus_out_event_t * e = (xcb_focus_out_event_t * ) ev ;
180
+ setBorderColor (e -> event , 0 );
181
+ }
182
+
176
183
static void handleMapRequest (xcb_generic_event_t * ev ) {
177
184
xcb_map_request_event_t * e = (xcb_map_request_event_t * ) ev ;
178
185
xcb_map_window (dpy , e -> window );
179
186
setWindowDimensions (e -> window );
180
187
setBorderWidth (e -> window );
181
- values [0 ] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW ;
188
+ values [0 ] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE ;
182
189
xcb_change_window_attributes_checked (dpy , e -> window ,
183
190
XCB_CW_EVENT_MASK , values );
184
191
setFocus (e -> window );
@@ -188,7 +195,8 @@ static int eventHandler(void) {
188
195
int ret = xcb_connection_has_error (dpy );
189
196
if (ret == 0 ) {
190
197
xcb_generic_event_t * ev = xcb_wait_for_event (dpy );
191
- for (handler_func_t * handler = handler_funs ; handler -> func != NULL ; handler ++ ) {
198
+ handler_func_t * handler ;
199
+ for (handler = handler_funs ; handler -> func != NULL ; handler ++ ) {
192
200
if ((ev -> response_type & ~0x80 ) == handler -> request ) {
193
201
handler -> func (ev );
194
202
}
@@ -198,35 +206,32 @@ static int eventHandler(void) {
198
206
return ret ;
199
207
}
200
208
201
- static void subscribeToEvents (void ) {
209
+ static void setup (void ) {
210
+ /* subscribe to events */
202
211
values [0 ] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
203
212
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
204
213
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
205
214
| XCB_EVENT_MASK_PROPERTY_CHANGE ;
206
- xcb_change_window_attributes_checked (dpy , root ,
215
+ xcb_change_window_attributes_checked (dpy , scre -> root ,
207
216
XCB_CW_EVENT_MASK , values );
208
- }
209
-
210
- static void grabKeys (void ) {
211
- xcb_ungrab_key (dpy , XCB_GRAB_ANY , root , XCB_MOD_MASK_ANY );
217
+ /* grab keys */
218
+ xcb_ungrab_key (dpy , XCB_GRAB_ANY , scre -> root , XCB_MOD_MASK_ANY );
212
219
int key_table_size = sizeof (keys ) / sizeof (* keys );
213
220
for (int i = 0 ; i < key_table_size ; ++ i ) {
214
221
xcb_keycode_t * keycode = xcb_get_keycodes (keys [i ].keysym );
215
222
if (keycode != NULL ) {
216
- xcb_grab_key (dpy , 1 , root , keys [i ].mod , * keycode ,
223
+ xcb_grab_key (dpy , 1 , scre -> root , keys [i ].mod , * keycode ,
217
224
XCB_GRAB_MODE_ASYNC , XCB_GRAB_MODE_ASYNC );
218
225
}
219
226
}
220
227
xcb_flush (dpy );
221
- }
222
-
223
- static void grabButtons (void ) {
224
- xcb_grab_button (dpy , 0 , root , XCB_EVENT_MASK_BUTTON_PRESS |
228
+ /* grab buttons */
229
+ xcb_grab_button (dpy , 0 , scre -> root , XCB_EVENT_MASK_BUTTON_PRESS |
225
230
XCB_EVENT_MASK_BUTTON_RELEASE , XCB_GRAB_MODE_ASYNC ,
226
- XCB_GRAB_MODE_ASYNC , root , XCB_NONE , 1 , MOD1 );
227
- xcb_grab_button (dpy , 0 , root , XCB_EVENT_MASK_BUTTON_PRESS |
231
+ XCB_GRAB_MODE_ASYNC , scre -> root , XCB_NONE , 1 , MOD1 );
232
+ xcb_grab_button (dpy , 0 , scre -> root , XCB_EVENT_MASK_BUTTON_PRESS |
228
233
XCB_EVENT_MASK_BUTTON_RELEASE , XCB_GRAB_MODE_ASYNC ,
229
- XCB_GRAB_MODE_ASYNC , root , XCB_NONE , 3 , MOD1 );
234
+ XCB_GRAB_MODE_ASYNC , scre -> root , XCB_NONE , 3 , MOD1 );
230
235
xcb_flush (dpy );
231
236
}
232
237
@@ -254,7 +259,7 @@ static int strcmp_c(char * str1, char * str2) {
254
259
int main (int argc , char * argv []) {
255
260
int ret = 0 ;
256
261
if ((argc == 2 ) && (strcmp_c ("-v" , argv [1 ]) == 0 )) {
257
- ret = die ("xwm-0.0.7 , © 2020 Michael Czigler, see LICENSE for details\n" );
262
+ ret = die ("xwm-0.0.8 , © 2020 Michael Czigler, see LICENSE for details\n" );
258
263
}
259
264
if ((ret == 0 ) && (argc != 1 )) {
260
265
ret = die ("usage: xwm [-v]\n" );
@@ -268,10 +273,7 @@ int main(int argc, char * argv[]) {
268
273
}
269
274
if (ret == 0 ) {
270
275
scre = xcb_setup_roots_iterator (xcb_get_setup (dpy )).data ;
271
- root = scre -> root ;
272
- subscribeToEvents ();
273
- grabKeys ();
274
- grabButtons ();
276
+ setup ();
275
277
}
276
278
while (ret == 0 ) {
277
279
ret = eventHandler ();
0 commit comments