return;
}
- /* Focus the output on which the user moved his cursor */
+ /* Focus the output on which the user moved their cursor */
Con *old_focused = focused;
Con *next = con_descend_focused(output_get_content(output->con));
/* Since we are switching outputs, this *must* be a different workspace, so
enter_child = true;
}
- /* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */
+ /* If not, then the user moved their cursor to the root window. In that case, we adjust c_ws */
if (con == NULL) {
DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
check_crossing_screen_boundary(event->root_x, event->root_y);
return;
}
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
+#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
+#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
+#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
+
/*
* Handle client messages (EWMH)
*
XCB_ATOM_CARDINAL, 32, 4,
&r);
xcb_flush(conn);
- } else if (event->type == A_WM_CHANGE_STATE) {
- /* http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4 */
- Con *con = con_by_window_id(event->window);
-
- if (con && event->data.data32[0] == 3) {
- /* this request is so we can play some animiation showing the
- * window physically moving to the tray before we close it (I
- * think) */
- DLOG("Client has requested iconic state. Closing this con. (con = %p)\n", con);
- tree_close(con, DONT_KILL_WINDOW, false, false);
- tree_render();
- } else {
- DLOG("Not handling WM_CHANGE_STATE request. (window = %d, state = %d)\n", event->window, event->data.data32[0]);
- }
-
} else if (event->type == A__NET_CURRENT_DESKTOP) {
/* This request is used by pagers and bars to change the current
* desktop likely as a result of some user action. We interpret this as
} else {
DLOG("Couldn't find con for _NET_CLOSE_WINDOW request. (window = %d)\n", event->window);
}
+ } else if (event->type == A__NET_WM_MOVERESIZE) {
+ /*
+ * Client-side decorated Gtk3 windows emit this signal when being
+ * dragged by their GtkHeaderBar
+ */
+ Con *con = con_by_window_id(event->window);
+ if (!con || !con_is_floating(con)) {
+ DLOG("Couldn't find con for _NET_WM_MOVERESIZE request, or con not floating (window = %d)\n", event->window);
+ return;
+ }
+ DLOG("Handling _NET_WM_MOVERESIZE request (con = %p)\n", con);
+ uint32_t direction = event->data.data32[2];
+ uint32_t x_root = event->data.data32[0];
+ uint32_t y_root = event->data.data32[1];
+ /* construct fake xcb_button_press_event_t */
+ xcb_button_press_event_t fake = {
+ .root_x = x_root,
+ .root_y = y_root,
+ .event_x = x_root - (con->rect.x),
+ .event_y = y_root - (con->rect.y)};
+ if (direction == _NET_WM_MOVERESIZE_MOVE) {
+ floating_drag_window(con->parent, &fake);
+ } else if (direction >= _NET_WM_MOVERESIZE_SIZE_TOPLEFT && direction <= _NET_WM_MOVERESIZE_SIZE_LEFT) {
+ floating_resize_window(con->parent, FALSE, &fake);
+ } else {
+ DLOG("_NET_WM_MOVERESIZE direction %d not implemented\n", direction);
+ }
} else {
DLOG("unhandled clientmessage\n");
return;
DLOG("xkb event, need to handle it.\n");
xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
- if (state->xkbType == XCB_XKB_MAP_NOTIFY) {
+ if (state->xkbType == XCB_XKB_NEW_KEYBOARD_NOTIFY) {
+ DLOG("xkb new keyboard notify, sequence %d, time %d\n", state->sequence, state->time);
+ xcb_key_symbols_free(keysyms);
+ keysyms = xcb_key_symbols_alloc(conn);
+ ungrab_all_keys(conn);
+ translate_keysyms();
+ grab_all_keys(conn, false);
+ } else if (state->xkbType == XCB_XKB_MAP_NOTIFY) {
if (event_is_ignored(event->sequence, type)) {
DLOG("Ignoring map notify event for sequence %d.\n", state->sequence);
} else {
DLOG("xkb map notify, sequence %d, time %d\n", state->sequence, state->time);
add_ignore_event(event->sequence, type);
+ xcb_key_symbols_free(keysyms);
+ keysyms = xcb_key_symbols_alloc(conn);
ungrab_all_keys(conn);
translate_keysyms();
grab_all_keys(conn, false);
/* See The XKB Extension: Library Specification, section 14.1 */
/* We check if the current group (each group contains
* two levels) has been changed. Mode_switch activates
- * group XkbGroup2Index */
+ * group XCB_XKB_GROUP_2 */
if (xkb_current_group == state->group)
return;
xkb_current_group = state->group;
grab_all_keys(conn, false);
} else {
DLOG("Mode_switch enabled\n");
- grab_all_keys(conn, false);
+ grab_all_keys(conn, true);
}
}
break;
case XCB_BUTTON_PRESS:
+ case XCB_BUTTON_RELEASE:
handle_button_press((xcb_button_press_event_t *)event);
break;
handle_motion_notify((xcb_motion_notify_event_t *)event);
break;
- /* Enter window = user moved his mouse over the window */
+ /* Enter window = user moved their mouse over the window */
case XCB_ENTER_NOTIFY:
handle_enter_notify((xcb_enter_notify_event_t *)event);
break;