commit e3a78f835bfbd0d5f5ae4da4102703d757c1d5a4
parent 253a932027bbb9cb04b3f450ae3a2beed59a0044
Author: Kebigon <git@kebigon.xyz>
Date: Sun, 2 Aug 2020 17:02:47 +0900
Be able to switch windows by clicking on them
Diffstat:
3 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/kbgwm.c b/kbgwm.c
@@ -105,7 +105,7 @@ void debug_print_event(xcb_generic_event_t* event)
{
xcb_button_press_event_t* event2 = (xcb_button_press_event_t*) event;
printf("=======[ event: XCB_BUTTON_PRESS ]=======\n");
- printf("window=%d modifiers=%d button=%d\n", event2->child, event2->state, event2->detail);
+ printf("window=%d child=%d modifiers=%d button=%d\n", event2->event, event2->child, event2->state, event2->detail);
debug_print_globals();
break;
}
@@ -496,6 +496,35 @@ void client_unmaximize(client* client)
xcb_configure_window(c, focused_client->id, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
}
+void client_grab_buttons(client* client, bool focused)
+{
+ uint16_t modifiers[] = { 0, numlockmask, XCB_MOD_MASK_LOCK, numlockmask | XCB_MOD_MASK_LOCK };
+
+ xcb_ungrab_button(c, XCB_BUTTON_INDEX_ANY, client->id, XCB_MOD_MASK_ANY);
+
+ // The client is not the focused one -> grab everything
+ if (!focused)
+ {
+ xcb_grab_button(c, 1, client->id, BUTTON_EVENT_MASK, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
+ XCB_BUTTON_INDEX_ANY, XCB_MOD_MASK_ANY);
+ }
+
+ // The client is the focused one -> grab only the configured buttons
+ else
+ {
+ for (unsigned int i = 0; i != LENGTH(buttons); i++)
+ {
+ Button button = buttons[i];
+
+ for (unsigned int j = 0; j != LENGTH(modifiers); j++)
+ {
+ xcb_grab_button(c, 0, client->id, BUTTON_EVENT_MASK, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
+ button.keysym, button.modifiers | modifiers[j]);
+ }
+ }
+ }
+}
+
/*
* Focus
*/
@@ -514,6 +543,7 @@ void focus_apply()
// Set the keyboard on the focused window
xcb_set_input_focus(c, XCB_INPUT_FOCUS_POINTER_ROOT, workspaces[current_workspace]->id, XCB_CURRENT_TIME);
+ client_grab_buttons(workspaces[current_workspace], true);
xcb_flush(c);
printf("focus_apply: done\n");
@@ -540,13 +570,16 @@ void focus_next(const Arg* arg)
// Remove the focus from the current client
void focus_unfocus()
{
+ client* client = workspaces[current_workspace];
+
// No client are focused
- if (workspaces[current_workspace] == NULL)
+ if (client == NULL)
return; // Nothing to be done
// Change the border color to UNFOCUS_COLOR
- xcb_change_window_attributes(c, workspaces[current_workspace]->id, XCB_CW_BORDER_PIXEL, (uint32_t[] )
+ xcb_change_window_attributes(c, client->id, XCB_CW_BORDER_PIXEL, (uint32_t[] )
{ 0xFF000000 | UNFOCUS_COLOR });
+ client_grab_buttons(workspaces[current_workspace], false);
}
/*
@@ -555,16 +588,16 @@ void focus_unfocus()
void handle_button_press(xcb_button_press_event_t* event)
{
- debug_print_globals();
-
// Click on the root window
- if (event->child == 0)
+ if (event->event == event->root && event->child == 0)
return; // Nothing to be done
+ xcb_window_t window = event->event == event->root ? event->child : event->event;
+
// The window clicked is not the one in focus, we have to focus it
- if (workspaces[current_workspace] == NULL || event->child != workspaces[current_workspace]->id)
+ if (workspaces[current_workspace] == NULL || window != workspaces[current_workspace]->id)
{
- client* client = client_find(event->child);
+ client* client = client_find(window);
assert(client != NULL);
focus_unfocus();
@@ -587,7 +620,9 @@ void handle_button_press(xcb_button_press_event_t* event)
void handle_button_release(__attribute__((unused)) xcb_button_release_event_t* event)
{
- assert(moving || resizing);
+ // We were not moving or resizing the focused client
+ if (!moving && !resizing)
+ return; // Nothing to be done
xcb_ungrab_pointer(c, XCB_CURRENT_TIME);
xcb_flush(c);
@@ -714,18 +749,9 @@ void setup_events()
xcb_change_window_attributes_checked(c, root, XCB_CW_EVENT_MASK, values);
- xcb_grab_button(c, 1, root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
- XCB_BUTTON_INDEX_1, XCB_MOD_MASK_ANY);
-
- xcb_grab_button(c, 1, root, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE,
- XCB_BUTTON_INDEX_3, XCB_MOD_MASK_ANY);
-
for (uint_fast8_t i = 0; i != LENGTH(keys); i++)
xcb_register_key_events(keys[i]);
- for (uint_fast8_t i = 0; i != LENGTH(buttons); i++)
- xcb_register_button_events(buttons[i]);
-
xcb_flush(c);
}
diff --git a/xcbutils.c b/xcbutils.c
@@ -50,15 +50,6 @@ void xcb_register_key_events(Key key)
free(keycodes);
}
-void xcb_register_button_events(Button button)
-{
- uint16_t modifiers[] = { 0, numlockmask, XCB_MOD_MASK_LOCK, numlockmask | XCB_MOD_MASK_LOCK };
-
- for (int i = 0; i != LENGTH(modifiers); i++)
- xcb_grab_button(c, 0, root, BUTTON_EVENT_MASK, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, button.keysym,
- button.modifiers | modifiers[i]);
-}
-
/*
* Get keycodes from a keysym
* TODO: check if there's a way to keep keysyms
diff --git a/xcbutils.h b/xcbutils.h
@@ -16,7 +16,6 @@ void* emalloc(size_t size);
* registering events
*/
void xcb_register_key_events(Key key);
-void xcb_register_button_events(Button button);
xcb_keycode_t* xcb_get_keycodes(xcb_keysym_t);
xcb_keysym_t xcb_get_keysym(xcb_keycode_t);