summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar synzr <synzr@klo.pp.ru> 2026-07-03 16:59:51 +0500
committerGravatar synzr <synzr@klo.pp.ru> 2026-07-03 16:59:51 +0500
commit43a0df3f491c17e7efe42cd126c430bd43907a86 (patch)
treef938c03e8ce561a9b5b2ec328b939fbfb6aa5608
parentdad65feb6618b1c6db9e84942d8688d95c835942 (diff)
downloadxhorse-43a0df3f491c17e7efe42cd126c430bd43907a86.tar.gz
xhorse-43a0df3f491c17e7efe42cd126c430bd43907a86.tar.bz2
xhorse-43a0df3f491c17e7efe42cd126c430bd43907a86.zip
Window is draggable now
-rw-r--r--xhorse.c70
1 files changed, 62 insertions, 8 deletions
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);