Skip to content

Commit 41ba4a6

Browse files
authored
released at 0.0.8
1 parent a441697 commit 41ba4a6

File tree

4 files changed

+75
-63
lines changed

4 files changed

+75
-63
lines changed

CHANGELOG

+8
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4646
## [0.0.7] - 2020-11-13
4747
### Fixed
4848
- Border focus/unfocus when leaving a window.
49+
50+
## [0.0.8] - 2020-11-16
51+
### Fixed
52+
- Window focus/unfocus on new window creation.
53+
54+
### Removed
55+
- Global root variable.
56+
- Removed leave notify event.

config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#define WINDOW_MIN_WIDTH 60
2727
#define WINDOW_MIN_HEIGHT 40
2828
#define BORDER_WIDTH 1 /* 0 = no border effect */
29-
#define BORDER_COLOR_UNFOCUSED 0xC0C0C0 /* 0xRRGGBB */
29+
#define BORDER_COLOR_UNFOCUSED 0x696969 /* 0xRRGGBB */
3030
#define BORDER_COLOR_FOCUSED 0xFFFFFF /* 0xRRGGBB */
3131

3232
/* ALIASED COMMANDS

xwm.c

+59-57
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
static xcb_connection_t * dpy;
99
static xcb_screen_t * scre;
1010
static xcb_drawable_t win;
11-
static xcb_drawable_t winprev;
12-
static xcb_drawable_t root;
1311
static uint32_t values[3];
1412

1513
static void killclient(char **com) {
@@ -25,7 +23,7 @@ static void closewm(char **com) {
2523
static void spawn(char **com) {
2624
if (fork() == 0) {
2725
if (dpy != NULL) {
28-
close(root);
26+
close(scre->root);
2927
}
3028
setsid();
3129
execvp((char*)com[0], (char**)com);
@@ -47,38 +45,46 @@ static void handleButtonPress(xcb_generic_event_t * ev) {
4745
xcb_warp_pointer(dpy, XCB_NONE, win, 0, 0, 0, 0, geom->width, geom->height);
4846
}
4947
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
5149
| 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+
}
5377
}
5478

5579
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);
5781
xcb_query_pointer_reply_t * poin = xcb_query_pointer_reply(dpy, coord, 0);
5882
uint32_t val[2] = {1, 3};
5983
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);
6885
}
6986
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);
8288
}
8389
}
8490

@@ -99,14 +105,10 @@ static xcb_keysym_t xcb_get_keysym(xcb_keycode_t keycode) {
99105
}
100106

101107
static void setFocus(xcb_drawable_t window) {
102-
if ((window != 0) && (window != root)) {
108+
if ((window != 0) && (window != scre->root)) {
103109
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, window,
104110
XCB_CURRENT_TIME);
105111
}
106-
setBorderColor(window, 1);
107-
if (winprev != window) {
108-
setBorderColor(winprev, 0);
109-
}
110112
}
111113

112114
static void setBorderColor(xcb_window_t window, int focus) {
@@ -155,11 +157,6 @@ static void handleEnterNotify(xcb_generic_event_t * ev) {
155157
setFocus(e->event);
156158
}
157159

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-
163160
static void handleButtonRelease(xcb_generic_event_t * ev) {
164161
xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME);
165162
}
@@ -173,12 +170,22 @@ static void handleDestroyNotify(xcb_generic_event_t * ev) {
173170
xcb_kill_client(dpy, e->window);
174171
}
175172

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+
176183
static void handleMapRequest(xcb_generic_event_t * ev) {
177184
xcb_map_request_event_t * e = (xcb_map_request_event_t *) ev;
178185
xcb_map_window(dpy, e->window);
179186
setWindowDimensions(e->window);
180187
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;
182189
xcb_change_window_attributes_checked(dpy, e->window,
183190
XCB_CW_EVENT_MASK, values);
184191
setFocus(e->window);
@@ -188,7 +195,8 @@ static int eventHandler(void) {
188195
int ret = xcb_connection_has_error(dpy);
189196
if (ret == 0) {
190197
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++) {
192200
if ((ev->response_type & ~0x80) == handler->request) {
193201
handler->func(ev);
194202
}
@@ -198,35 +206,32 @@ static int eventHandler(void) {
198206
return ret;
199207
}
200208

201-
static void subscribeToEvents(void) {
209+
static void setup(void) {
210+
/* subscribe to events */
202211
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
203212
| XCB_EVENT_MASK_STRUCTURE_NOTIFY
204213
| XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY
205214
| XCB_EVENT_MASK_PROPERTY_CHANGE;
206-
xcb_change_window_attributes_checked(dpy, root,
215+
xcb_change_window_attributes_checked(dpy, scre->root,
207216
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);
212219
int key_table_size = sizeof(keys) / sizeof(*keys);
213220
for (int i = 0; i < key_table_size; ++i) {
214221
xcb_keycode_t * keycode = xcb_get_keycodes(keys[i].keysym);
215222
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,
217224
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC );
218225
}
219226
}
220227
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 |
225230
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 |
228233
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);
230235
xcb_flush(dpy);
231236
}
232237

@@ -254,7 +259,7 @@ static int strcmp_c(char * str1, char * str2) {
254259
int main(int argc, char * argv[]) {
255260
int ret = 0;
256261
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");
258263
}
259264
if ((ret == 0) && (argc != 1)) {
260265
ret = die("usage: xwm [-v]\n");
@@ -268,10 +273,7 @@ int main(int argc, char * argv[]) {
268273
}
269274
if (ret == 0) {
270275
scre = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data;
271-
root = scre->root;
272-
subscribeToEvents();
273-
grabKeys();
274-
grabButtons();
276+
setup();
275277
}
276278
while (ret == 0) {
277279
ret = eventHandler();

xwm.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -27,35 +27,37 @@ static void setFocus(xcb_drawable_t window);
2727
static void setWindowDimensions(xcb_drawable_t window);
2828
static void setBorderWidth(xcb_drawable_t window);
2929
static void setBorderColor(xcb_drawable_t window, int focus);
30+
static void moveWindow(xcb_query_pointer_reply_t * poin);
31+
static void resizeWindow(xcb_query_pointer_reply_t * poin);
3032

3133
/* event hander actions */
3234
static int eventHandler(void);
3335
static void handleMotionNotify(xcb_generic_event_t * ev);
3436
static void handleEnterNotify(xcb_generic_event_t * ev);
35-
static void handleLeaveNotify(xcb_generic_event_t * ev);
3637
static void handleDestroyNotify(xcb_generic_event_t * ev);
3738
static void handleButtonPress(xcb_generic_event_t * ev);
3839
static void handleButtonRelease(xcb_generic_event_t * ev);
3940
static void handleKeyPress(xcb_generic_event_t * ev);
4041
static void handleKeyRelease(xcb_generic_event_t * ev);
4142
static void handleMapRequest(xcb_generic_event_t * ev);
43+
static void handleFocusIn(xcb_generic_event_t * ev);
44+
static void handleFocusOut(xcb_generic_event_t * ev);
4245
static handler_func_t handler_funs[] = {
4346
{ XCB_MOTION_NOTIFY, handleMotionNotify },
4447
{ XCB_ENTER_NOTIFY, handleEnterNotify },
45-
{ XCB_LEAVE_NOTIFY, handleLeaveNotify },
4648
{ XCB_DESTROY_NOTIFY, handleDestroyNotify },
4749
{ XCB_BUTTON_PRESS, handleButtonPress },
4850
{ XCB_BUTTON_RELEASE, handleButtonRelease },
4951
{ XCB_KEY_PRESS, handleKeyPress },
5052
{ XCB_KEY_RELEASE, handleKeyRelease },
5153
{ XCB_MAP_REQUEST, handleMapRequest },
54+
{ XCB_FOCUS_IN, handleFocusIn },
55+
{ XCB_FOCUS_OUT, handleFocusOut },
5256
{ XCB_NONE, NULL }
5357
};
5458

5559
/* intialize */
56-
static void subscribeToEvents(void);
57-
static void grabKeys(void);
58-
static void grabButtons(void);
60+
static void setup(void);
5961

6062
/* error handling & misc. */
6163
static int die(char * errstr);

0 commit comments

Comments
 (0)