aboutsummaryrefslogtreecommitdiff
path: root/src/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/connect.c')
-rw-r--r--src/connect.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/connect.c b/src/connect.c
index 9272a5c..bc45812 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -48,6 +48,62 @@ static void update_scale(Connection *con)
}
}
+static inline bool in_rect(int px, int py, int x, int y, int w, int h)
+{
+ return px >= x && px <= x + w && py >= y && py <= y + h;
+}
+
+static inline bool in_circle(int px, int py, int x, int y, int r)
+{
+ int dx = x - px;
+ int dy = y - py;
+ return (dx * dx + dy * dy) <= r * r;
+}
+
+static inline bool in_capsule(int px, int py, int x, int y, int w, int h)
+{
+ g_assert(w >= h);
+ int radius = h / 2;
+
+ // Circle case
+ if (w == h) return in_circle(px, py, x + radius, y + radius, radius);
+
+ // Capsule case
+ return in_circle(px, py, x + radius, y + radius, radius)
+ || in_circle(px, py, x + w - radius, y + radius, radius)
+ || in_rect(px, py, x + radius, y, w - 2 * radius, h);
+}
+
+static void button_action(State *state, xcb_button_release_event_t *button)
+{
+ log_debug("Button release event [x=%d, y=%d]", button->event_x, button->event_y);
+
+ for (GList *it = state->draw->layouts; it != NULL; it = it->next) {
+ Layout *layout = it->data;
+
+ // Skip
+ if (layout->x + layout->width < button->event_x) continue;
+ if (layout->x > button->event_x) break;
+
+ bool check = in_capsule(button->event_x, button->event_y,
+ layout->x, layout->y,
+ layout->width, layout->height);
+
+ log_debug("Button layout [x=%d, y=%d, w=%d, h=%d]",
+ layout->x, layout->y, layout->width, layout->height);
+
+ if (check) {
+ log_debug("Triggering action for button");
+ if (layout->btn->action != NULL) {
+ layout->btn->action(layout->btn);
+ }
+ return;
+ }
+ }
+
+ log_debug("Ignoring button release");
+}
+
typedef struct {
GSource source;
Connection *con;
@@ -115,9 +171,21 @@ static gboolean source_dispatch(GSource *source, GSourceFunc callback, gpointer
}
case XCB_BUTTON_RELEASE: {
- log_debug("Mouse event");
-
- // TODO: Handle click generically by translating the button code
+ xcb_button_release_event_t *button = (xcb_button_release_event_t *)xsource->event;
+ log_debug("Processing event 'ButtonRelease' [type=%d]", XCB_BUTTON_RELEASE);
+
+ // TODO: Handle different actions properly
+ switch (button->detail) {
+ case XCB_BUTTON_INDEX_2: // left click
+ case XCB_BUTTON_INDEX_1: // right click
+ case XCB_BUTTON_INDEX_3: // middle click
+ button_action(xsource->con->state, button);
+ break;
+
+ default:
+ log_debug("Ignoring button release [button=%d]", button->detail);
+ break;
+ }
break;
}