From f923045d6ca5f4b202070b6eed38ba63011ee2f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20=C5=A0vagelj?= Date: Fri, 12 Apr 2024 14:46:39 +0000 Subject: [PATCH] Refactor x11 event handling (#1819) Move event handling code into separate functions. --- src/display-x11.cc | 162 ++++++++++++++++++++++++++------------------- src/x11.cc | 10 --- 2 files changed, 95 insertions(+), 77 deletions(-) diff --git a/src/display-x11.cc b/src/display-x11.cc index 2217a7434..04714a7ad 100644 --- a/src/display-x11.cc +++ b/src/display-x11.cc @@ -425,15 +425,29 @@ bool display_output_x11::main_loop_wait(double t) { return true; } -#define EV_HANDLER(name) \ - bool _conky_ev_handle_##name(conky::display_output_x11 *surface, \ - Display *display, XEvent &ev, bool *consumed, \ - void **cookie) -#define NOOP_EV_HANDLER(name) \ - EV_HANDLER(name) { return false; } +enum x_event_handler { + XINPUT_MOTION, + MOUSE_INPUT, + PROPERTY_NOTIFY, + + EXPOSE, + REPARENT, + CONFIGURE, + BORDER_CROSSING, + DAMAGE, +}; + +template +bool handle_event(conky::display_output_x11 *surface, Display *display, + XEvent &ev, bool *consumed, void **cookie) { + return false; +} #ifdef OWN_WINDOW -EV_HANDLER(mouse_input) { +template <> +bool handle_event( + conky::display_output_x11 *surface, Display *display, XEvent &ev, + bool *consumed, void **cookie) { #ifdef BUILD_XINPUT if (ev.type == ButtonPress || ev.type == ButtonRelease || ev.type == MotionNotify) { @@ -650,52 +664,20 @@ EV_HANDLER(mouse_input) { return true; } -EV_HANDLER(reparent) { +template <> +bool handle_event(conky::display_output_x11 *surface, + Display *display, XEvent &ev, + bool *consumed, void **cookie) { if (ev.type != ReparentNotify) return false; if (own_window.get(*state)) { set_transparent_background(window.window); } return true; } -#else /* OWN_WINDOW */ -NOOP_EV_HANDLER(reparent) -#endif /* OWN_WINDOW */ - -EV_HANDLER(property_notify) { - if (ev.type != PropertyNotify) return false; - - if (ev.xproperty.state == PropertyNewValue) { - get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom); - } - -#ifdef USE_ARGB - if (have_argb_visual) return true; -#endif - - if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) || - ev.xproperty.atom == ATOM(_XROOTMAP_ID)) { - if (forced_redraw.get(*state)) { - draw_stuff(); - next_update_time = get_time(); - need_to_update = 1; - } - } - return true; -} - -EV_HANDLER(expose) { - if (ev.type != Expose) return false; - - XRectangle r; - r.x = ev.xexpose.x; - r.y = ev.xexpose.y; - r.width = ev.xexpose.width; - r.height = ev.xexpose.height; - XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region); - XSync(display, False); - return true; -} -EV_HANDLER(configure) { +template <> +bool handle_event( + conky::display_output_x11 *surface, Display *display, XEvent &ev, + bool *consumed, void **cookie) { if (ev.type != ConfigureNotify) return false; if (own_window.get(*state)) { @@ -739,8 +721,53 @@ EV_HANDLER(configure) { return true; } +#endif /* OWN_WINDOW */ + +template <> +bool handle_event( + conky::display_output_x11 *surface, Display *display, XEvent &ev, + bool *consumed, void **cookie) { + if (ev.type != PropertyNotify) return false; + + if (ev.xproperty.state == PropertyNewValue) { + get_x11_desktop_info(ev.xproperty.display, ev.xproperty.atom); + } + +#ifdef USE_ARGB + if (have_argb_visual) return true; +#endif + + if (ev.xproperty.atom == ATOM(_XROOTPMAP_ID) || + ev.xproperty.atom == ATOM(_XROOTMAP_ID)) { + if (forced_redraw.get(*state)) { + draw_stuff(); + next_update_time = get_time(); + need_to_update = 1; + } + } + return true; +} + +template <> +bool handle_event(conky::display_output_x11 *surface, + Display *display, XEvent &ev, + bool *consumed, void **cookie) { + if (ev.type != Expose) return false; -EV_HANDLER(border_crossing) { + XRectangle r; + r.x = ev.xexpose.x; + r.y = ev.xexpose.y; + r.width = ev.xexpose.width; + r.height = ev.xexpose.height; + XUnionRectWithRegion(&r, x11_stuff.region, x11_stuff.region); + XSync(display, False); + return true; +} + +template <> +bool handle_event( + conky::display_output_x11 *surface, Display *display, XEvent &ev, + bool *consumed, void **cookie) { if (ev.type != EnterNotify && ev.type != LeaveNotify) return false; if (window.xi_opcode != 0) return true; // handled by mouse_input already @@ -761,7 +788,10 @@ EV_HANDLER(border_crossing) { } #ifdef BUILD_XDAMAGE -EV_HANDLER(damage) { +template <> +bool handle_event(conky::display_output_x11 *surface, + Display *display, XEvent &ev, + bool *consumed, void **cookie) { if (ev.type != x11_stuff.event_base + XDamageNotify) return false; auto *dev = reinterpret_cast(&ev); @@ -771,8 +801,6 @@ EV_HANDLER(damage) { x11_stuff.part); return true; } -#else -NOOP_EV_HANDLER(damage) #endif /* BUILD_XDAMAGE */ /// Handles all events conky can receive. @@ -780,24 +808,24 @@ NOOP_EV_HANDLER(damage) /// @return true if event should move input focus to conky bool process_event(conky::display_output_x11 *surface, Display *display, XEvent ev, bool *consumed, void **cookie) { -#define HANDLE_EV(handler) \ - if (_conky_ev_handle_##handler(surface, display, ev, consumed, cookie)) \ - return true +#define HANDLE_EV(event) \ + if (handle_event(surface, display, ev, consumed, \ + cookie)) { \ + return true; \ + } -#ifdef BUILD_XINPUT - // handles enter & leave events better - HANDLE_EV(xinput_motion); -#endif /* BUILD_XINPUT */ - HANDLE_EV(mouse_input); - HANDLE_EV(property_notify); + HANDLE_EV(XINPUT_MOTION) + HANDLE_EV(MOUSE_INPUT) + HANDLE_EV(PROPERTY_NOTIFY) // only accept remaining events if they're sent to Conky. if (ev.xany.window != window.window) return false; - HANDLE_EV(expose); - HANDLE_EV(reparent); - HANDLE_EV(border_crossing); - HANDLE_EV(damage); + HANDLE_EV(EXPOSE) + HANDLE_EV(REPARENT) + HANDLE_EV(CONFIGURE) + HANDLE_EV(BORDER_CROSSING) + HANDLE_EV(DAMAGE) // event not handled return false; @@ -816,9 +844,9 @@ void process_surface_events(conky::display_output_x11 *surface, XNextEvent(display, &ev); /* - indicates whether processed event was consumed; true by default so we don't - propagate handled events unless they explicitly state they haven't been - consumed. + indicates whether processed event was consumed; true by default so we + don't propagate handled events unless they explicitly state they haven't + been consumed. */ bool consumed = true; void *cookie = nullptr; diff --git a/src/x11.cc b/src/x11.cc index 7b64f996b..0d382d2d9 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -1412,7 +1412,6 @@ int ev_to_mask(int event_type, int button) { } } -<<<<<<< HEAD #ifdef BUILD_XINPUT void propagate_xinput_event(const conky::xi_event_data *ev) { if (ev->evtype != XI_Motion && ev->evtype != XI_ButtonPress && @@ -1466,11 +1465,6 @@ void propagate_x11_event(XEvent &ev, const void *cookie) { } #endif -======= -void propagate_x11_event(XEvent &ev, const void *cookie) { - bool focus = ev.type == ButtonPress; - ->>>>>>> fix/separate-x11-events InputEvent *i_ev = xev_as_input_event(ev); if (i_ev == nullptr) { // Not a known input event; blindly propagating them causes loops and all @@ -1504,14 +1498,10 @@ void propagate_x11_event(XEvent &ev, const void *cookie) { } XUngrabPointer(display, CurrentTime); -<<<<<<< HEAD XSendEvent(display, i_ev->common.window, True, ev_to_mask(i_ev->type, ev.type == ButtonRelease ? i_ev->xbutton.button : 0), &ev); -======= - XSendEvent(display, i_ev->common.window, True, ev_to_mask(i_ev->type), &ev); ->>>>>>> fix/separate-x11-events if (focus) { XSetInputFocus(display, i_ev->common.window, RevertToParent, CurrentTime); }