From 3e711082e76dc52b47c89f5f82a7c670e5a1efb9 Mon Sep 17 00:00:00 2001 From: Dylan Araps Date: Sat, 11 Jul 2020 14:47:07 +0300 Subject: [PATCH] sowm2: Resizing and moving --- sowm.c | 150 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 38 deletions(-) diff --git a/sowm.c b/sowm.c index 63b4eb1..c85ef03 100644 --- a/sowm.c +++ b/sowm.c @@ -13,7 +13,10 @@ static xcb_screen_t *scr; static xcb_drawable_t root; /* required for button press, motion and release */ -static uint32_t ev_vals[3]; +static uint32_t motion_vals[3]; +static xcb_window_t motion_win; +static xcb_get_geometry_reply_t *motion_geom; +static int is_motion = 0; static void init_wm(void); static void init_input(void); @@ -23,17 +26,43 @@ static void win_add(xcb_window_t win); void event_button_press(xcb_generic_event_t *ev) { xcb_button_press_event_t *e = (xcb_button_press_event_t *)ev; - ev_vals[0] = XCB_STACK_MODE_ABOVE; - xcb_configure_window(dpy, e->child, XCB_CONFIG_WINDOW_STACK_MODE, ev_vals); + if (e->child == root) { + return; + } + + motion_vals[0] = XCB_STACK_MODE_ABOVE; + motion_win = e->child; + is_motion = 1; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_STACK_MODE, + motion_vals); + + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + /* resize */ + if (e->detail == 1) { + xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); + motion_vals[2] = 1; + + /* move */ + } else { + xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); + motion_vals[2] = 3; + } xcb_grab_pointer(dpy, 0, root, XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, XCB_CURRENT_TIME); + + xcb_flush(dpy); } void event_button_release(xcb_generic_event_t *ev) { xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME); + xcb_flush(dpy); + is_motion = 0; } void event_configure_request(xcb_generic_event_t *ev) { @@ -41,37 +70,43 @@ void event_configure_request(xcb_generic_event_t *ev) { uint32_t values[7]; int8_t i = -1; - if (e->value_mask & XCB_CONFIG_WINDOW_X) { - e->value_mask |= XCB_CONFIG_WINDOW_X; - values[++i] = e->x; - } + if (e->value_mask & XCB_CONFIG_WINDOW_X) { + e->value_mask |= XCB_CONFIG_WINDOW_X; + i++; + values[i] = e->x; + } - if (e->value_mask & XCB_CONFIG_WINDOW_Y) { - e->value_mask |= XCB_CONFIG_WINDOW_Y; - values[++i] = e->y; - } + if (e->value_mask & XCB_CONFIG_WINDOW_Y) { + e->value_mask |= XCB_CONFIG_WINDOW_Y; + i++; + values[i] = e->y; + } - if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { - e->value_mask |= XCB_CONFIG_WINDOW_WIDTH; - values[++i] = e->width; - } + if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { + e->value_mask |= XCB_CONFIG_WINDOW_WIDTH; + i++; + values[i] = e->width; + } - if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { - e->value_mask |= XCB_CONFIG_WINDOW_HEIGHT; - values[++i] = e->height; - } + if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { + e->value_mask |= XCB_CONFIG_WINDOW_HEIGHT; + i++; + values[i] = e->height; + } - if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { - e->value_mask |= XCB_CONFIG_WINDOW_SIBLING; - values[++i] = e->sibling; - } + if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { + e->value_mask |= XCB_CONFIG_WINDOW_SIBLING; + i++; + values[i] = e->sibling; + } - if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { - e->value_mask |= XCB_CONFIG_WINDOW_STACK_MODE; - values[++i] = e->stack_mode; - } + if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { + e->value_mask |= XCB_CONFIG_WINDOW_STACK_MODE; + i++; + values[i] = e->stack_mode; + } - if (i != -1) { + if (i != -1) { xcb_configure_window(dpy, e->window, e->value_mask, values); xcb_flush(dpy); } @@ -83,14 +118,13 @@ void event_key_press(xcb_generic_event_t *ev) { void event_notify_create(xcb_generic_event_t *ev) { xcb_create_notify_event_t *e = (xcb_create_notify_event_t *)ev; + uint32_t values[2]; - ev_vals[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; - ev_vals[1] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; + values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; + values[1] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; - xcb_change_window_attributes(dpy, e->window, XCB_CW_EVENT_MASK, ev_vals); + xcb_change_window_attributes(dpy, e->window, XCB_CW_EVENT_MASK, values); xcb_map_window(dpy, e->window); - xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, - e->window, XCB_CURRENT_TIME); } void event_notify_destroy(xcb_generic_event_t *ev) { @@ -100,12 +134,52 @@ void event_notify_destroy(xcb_generic_event_t *ev) { void event_notify_enter(xcb_generic_event_t *ev) { xcb_enter_notify_event_t *e = (xcb_enter_notify_event_t *)ev; - xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, + if (e->event == root || is_motion) { + return; + } + + xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, e->event, XCB_CURRENT_TIME); + + xcb_flush(dpy); } void event_notify_motion(xcb_generic_event_t *ev) { - xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *)ev; + xcb_query_pointer_reply_t *ptr; + + ptr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), 0); + + /* move */ + if (motion_vals[2] == 1) { + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + motion_vals[0] = + (ptr->root_x + motion_geom->width > scr->width_in_pixels)? + (scr->width_in_pixels - motion_geom->width):ptr->root_x; + + motion_vals[1] = + (ptr->root_y + motion_geom->height > scr->height_in_pixels)? + (scr->height_in_pixels - motion_geom->height):ptr->root_y; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_X | + XCB_CONFIG_WINDOW_Y, motion_vals); + + xcb_flush(dpy); + + /* resize */ + } else if (motion_vals[2] == 3) { + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + motion_vals[0] = ptr->root_x - motion_geom->x; + motion_vals[1] = ptr->root_y - motion_geom->y; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_WIDTH | + XCB_CONFIG_WINDOW_HEIGHT, motion_vals); + + xcb_flush(dpy); + } } void win_add(xcb_window_t win) { @@ -113,6 +187,7 @@ void win_add(xcb_window_t win) { } void init_wm(void) { + uint32_t values[2]; dpy = xcb_connect(NULL, NULL); if (xcb_connection_has_error(dpy)) { @@ -130,8 +205,8 @@ void init_wm(void) { root = scr->root; - ev_vals[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; - xcb_change_window_attributes_checked(dpy, root, XCB_CW_EVENT_MASK, ev_vals); + values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; + xcb_change_window_attributes_checked(dpy, root, XCB_CW_EVENT_MASK, values); xcb_flush(dpy); } @@ -158,7 +233,6 @@ void run_loop(void) { if (events[EVENT_MASK(ev->response_type)]) { events[EVENT_MASK(ev->response_type)](ev); - xcb_flush(dpy); } free(ev); }