From 43a0df3f491c17e7efe42cd126c430bd43907a86 Mon Sep 17 00:00:00 2001 From: synzr Date: Fri, 3 Jul 2026 16:59:51 +0500 Subject: Window is draggable now --- xhorse.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 8 deletions(-) (limited to 'xhorse.c') diff --git a/xhorse.c b/xhorse.c index 8f8bb6b..2bf70ce 100644 --- a/xhorse.c +++ b/xhorse.c @@ -12,6 +12,10 @@ typedef struct xhorse xcb_connection_t *conn; xcb_screen_t *scr; xcb_window_t win; + + int16_t root_x, root_y; + int16_t win_x, win_y; + bool dragging; } xhorse_t; bool xh_connect(xhorse_t *xh) @@ -38,9 +42,16 @@ void xh_setup(xhorse_t *xh) xh->scr = xcb_setup_roots_iterator(set).data; uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - uint32_t vals[] = { xh->scr->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS }; + uint32_t vals[] = { + xh->scr->white_pixel, + XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS | + XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_BUTTON_MOTION + }; xh->win = xcb_generate_id(xh->conn); + xh->win_x = xh->win_y = 0; + xcb_void_cookie_t cookie = xcb_create_window(xh->conn, /* depth */ XCB_COPY_FROM_PARENT, xh->win, xh->scr->root, /* x */ 0, /* y */ 0, /* w */ 150, /* h */ 75, /* border width*/ 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, @@ -49,15 +60,36 @@ void xh_setup(xhorse_t *xh) xcb_map_window(xh->conn, xh->win); } -void xh_handle_expose(xhorse_t *xh, xcb_generic_event_t *generic_ev) +void xh_update_current_position(xhorse_t *xh) { - // TODO + xcb_translate_coordinates_cookie_t cookie = + xcb_translate_coordinates(xh->conn, xh->win, xh->scr->root, 0, 0); + + xcb_translate_coordinates_reply_t *reply = + xcb_translate_coordinates_reply(xh->conn, cookie, NULL); + + if (reply) + { + xh->win_x = reply->dst_x; + xh->win_y = reply->dst_y; + + free(reply); + } } -bool xh_handle_esc(xhorse_t *xh, xcb_generic_event_t *generic_ev) +void xh_handle_motion(xhorse_t *xh, xcb_generic_event_t *generic_ev) { - xcb_key_press_event_t *press_ev = (xcb_key_press_event_t *)generic_ev; - return ESC_BUTTON == press_ev->detail; + if (!xh->dragging) return; + + xcb_motion_notify_event_t *motion_ev = (xcb_motion_notify_event_t *)generic_ev; + + int32_t pos[2] = { + xh->win_x + (motion_ev->root_x - xh->root_x), + xh->win_y + (motion_ev->root_y - xh->root_y) + }; + + xcb_configure_window(xh->conn, xh->win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, pos); + xcb_flush(xh->conn); } void xh_event_loop(xhorse_t *xh) @@ -71,15 +103,37 @@ void xh_event_loop(xhorse_t *xh) switch (response_type) { case XCB_EXPOSE: - xh_handle_expose(xh, generic_ev); + case XCB_BUTTON_RELEASE: + xh->dragging = false; break; case XCB_KEY_PRESS: - if (true == xh_handle_esc(xh, generic_ev)) + { + xcb_key_press_event_t *press_ev = (xcb_key_press_event_t *)generic_ev; + + if (ESC_BUTTON == press_ev->detail) return; break; + } + + case XCB_BUTTON_PRESS: + { + xcb_button_press_event_t *mouse_ev = (xcb_button_press_event_t *)generic_ev; + + xh_update_current_position(xh); + xh->root_x = mouse_ev->root_x; + xh->root_y = mouse_ev->root_y; + xh->dragging = true; + + break; + } + case XCB_MOTION_NOTIFY: + { + xh_handle_motion(xh, generic_ev); + break; + } } free(generic_ev); -- cgit v1.3