diff --git a/3rdparty/toluapp/CMakeLists.txt b/3rdparty/toluapp/CMakeLists.txt index 2d79e75c..cfcb8144 100644 --- a/3rdparty/toluapp/CMakeLists.txt +++ b/3rdparty/toluapp/CMakeLists.txt @@ -5,7 +5,7 @@ # Please note that the package source code is licensed under its own license. project ( toluapp C ) -cmake_minimum_required ( VERSION 3.4 ) +cmake_minimum_required ( VERSION 3.15 ) # Disable dist stuff, we're not installing this as a lib # include ( cmake/dist.cmake ) diff --git a/cmake/ConkyPlatformChecks.cmake b/cmake/ConkyPlatformChecks.cmake index ac1cfd48..9701b1e0 100644 --- a/cmake/ConkyPlatformChecks.cmake +++ b/cmake/ConkyPlatformChecks.cmake @@ -451,7 +451,7 @@ set(conky_libs ${conky_libs} ${LUA_LIBRARIES}) set(conky_includes ${conky_includes} ${LUA_INCLUDE_DIR}) include_directories(3rdparty/toluapp/include) -if(BUILD_X11) +if(BUILD_GUI) # Check for libraries used by Lua bindings if(BUILD_LUA_CAIRO) pkg_check_modules(CAIRO REQUIRED cairo>=1.14 cairo-xlib) @@ -469,8 +469,7 @@ if(BUILD_X11) set(luaimlib2_libs ${IMLIB2_LIBS} ${IMLIB2_LDFLAGS} ${LUA_LIBRARIES}) set(luaimlib2_includes ${IMLIB2_INCLUDE_DIRS} - ${LUA_INCLUDE_DIR} - ${X11_INCLUDE_DIR}) + ${LUA_INCLUDE_DIR}) endif(BUILD_LUA_IMLIB2) if(BUILD_LUA_RSVG) @@ -478,7 +477,7 @@ if(BUILD_X11) set(luarsvg_libs ${RSVG_LIBRARIES} ${LUA_LIBRARIES}) set(luarsvg_includes ${RSVG_INCLUDE_DIRS} ${LUA_INCLUDE_DIR}) endif(BUILD_LUA_RSVG) -endif(BUILD_X11) +endif(BUILD_GUI) if(BUILD_AUDACIOUS) set(WANT_GLIB true) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9bd9bd22..cede4c2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -239,16 +239,16 @@ endif(BUILD_PORT_MONITORS) if(BUILD_X11) set(x11 x11.cc x11.h) set(optional_sources ${optional_sources} ${x11}) - - if(BUILD_MOUSE_EVENTS) - set(mouse_events mouse-events.cc mouse-events.h) - set(optional_sources ${optional_sources} ${mouse_events}) - endif(BUILD_MOUSE_EVENTS) endif(BUILD_X11) if(BUILD_GUI) set(gui fonts.cc fonts.h gui.cc gui.h) set(optional_sources ${optional_sources} ${gui}) + + if(BUILD_MOUSE_EVENTS) + set(mouse_events mouse-events.cc mouse-events.h) + set(optional_sources ${optional_sources} ${mouse_events}) + endif(BUILD_MOUSE_EVENTS) endif(BUILD_GUI) if(BUILD_WAYLAND) diff --git a/src/display-wayland.cc b/src/display-wayland.cc index 5b242ffc..7084fc62 100644 --- a/src/display-wayland.cc +++ b/src/display-wayland.cc @@ -491,7 +491,6 @@ static void on_pointer_motion(void *data, size_t abs_y = w->rectangle.y + y; mouse_move_event event { - mouse_event_t::MOUSE_MOVE, x, y, abs_x, @@ -552,7 +551,6 @@ void on_pointer_axis(void *data, size_t abs_y = w->rectangle.y + y; mouse_scroll_event event { - mouse_event_t::MOUSE_SCROLL, x, y, abs_x, diff --git a/src/display-x11.cc b/src/display-x11.cc index 6a6d37a2..16d7b41d 100644 --- a/src/display-x11.cc +++ b/src/display-x11.cc @@ -7,7 +7,7 @@ * Copyright (C) 2018-2021 François Revol et al. * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. - * (see AUTHORS) + * (see AUTHORS) * All rights reserved. * * This program is free software: you can redistribute it and/or modify @@ -24,7 +24,10 @@ * */ +#include #include +#include +#include "logging.h" #ifdef BUILD_X11 #pragma GCC diagnostic push @@ -37,7 +40,7 @@ #include "x11.h" #ifdef BUILD_XDAMAGE #include -#endif +#endif /* BUILD_XDAMAGE */ #include "fonts.h" #ifdef BUILD_IMLIB2 #include "imlib2.h" @@ -227,6 +230,29 @@ bool display_output_x11::shutdown() { return true; } +inline void propagate_unconsumed_event(XEvent &ev, bool is_consumed) { + uint32_t capture_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask; + + // SAFETY: XEvent is a union and all event types this function gets called for + // share same alignment and accessed fields share same offsets. + if (!is_consumed) { + XUngrabPointer(display, ev.xmotion.time); + + /* forward the event to the desktop window */ + ev.xmotion.window = window.desktop; + ev.xmotion.x = ev.xmotion.x_root; + ev.xmotion.y = ev.xmotion.y_root; + XSendEvent(display, window.desktop, False, capture_mask, &ev); + if (ev.type == ButtonPress) { + XSetInputFocus(display, window.desktop, RevertToNone, ev.xmotion.time); + } + } else { + XGrabPointer(display, window.window, TRUE, capture_mask, + GrabModeAsync, GrabModeAsync, window.window, None, ev.xbutton.time); + XSetInputFocus(display, window.window, RevertToParent, ev.xmotion.time); + } +} + bool display_output_x11::main_loop_wait(double t) { /* wait for X event or timeout */ if (!display || !window.gc) return true; @@ -458,10 +484,34 @@ bool display_output_x11::main_loop_wait(double t) { case ButtonPress: #ifdef BUILD_MOUSE_EVENTS - if (ev.xbutton.button == 4 || ev.xbutton.button == 5) { - consumed = llua_mouse_hook(mouse_scroll_event(&ev.xbutton)); + if (ev.xbutton.button == 4) { + consumed = llua_mouse_hook(mouse_scroll_event( + ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, ev.xbutton.y_root, + scroll_direction_t::SCROLL_UP, ev.xbutton.state + )); + } else if (ev.xbutton.button == 5) { + consumed = llua_mouse_hook(mouse_scroll_event( + ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, ev.xbutton.y_root, + scroll_direction_t::SCROLL_DOWN, ev.xbutton.state + )); } else { - consumed = llua_mouse_hook(mouse_press_event(&ev.xbutton)); + mouse_button_t button; + switch (ev.xbutton.button) { + case Button1: + button = mouse_button_t::BUTTON_LEFT; + break; + case Button2: + button = mouse_button_t::BUTTON_RIGHT; + break; + case Button3: + button = mouse_button_t::BUTTON_MIDDLE; + break; + } + consumed = llua_mouse_hook(mouse_button_event( + mouse_event_t::MOUSE_PRESS, + ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, ev.xbutton.y_root, + button, ev.xbutton.state + )); } #endif /* BUILD_MOUSE_EVENTS */ if (own_window.get(*state)) { @@ -472,16 +522,7 @@ bool display_output_x11::main_loop_wait(double t) { /* allow conky to hold input focus. */ break; } - XUngrabPointer(display, ev.xbutton.time); - if (!consumed) { - /* forward the click to the desktop window */ - ev.xbutton.window = window.desktop; - ev.xbutton.x = ev.xbutton.x_root; - ev.xbutton.y = ev.xbutton.y_root; - XSendEvent(display, ev.xbutton.window, False, ButtonPressMask, &ev); - XSetInputFocus(display, ev.xbutton.window, RevertToParent, - ev.xbutton.time); - } + propagate_unconsumed_event(ev, consumed); } break; @@ -489,7 +530,23 @@ bool display_output_x11::main_loop_wait(double t) { #ifdef BUILD_MOUSE_EVENTS /* don't report scrollwheel release events */ if (ev.xbutton.button != Button4 && ev.xbutton.button != Button5) { - llua_mouse_hook(mouse_release_event(&ev.xbutton)); + mouse_button_t button; + switch (ev.xbutton.button) { + case Button1: + button = mouse_button_t::BUTTON_LEFT; + break; + case Button2: + button = mouse_button_t::BUTTON_RIGHT; + break; + case Button3: + button = mouse_button_t::BUTTON_MIDDLE; + break; + } + consumed = llua_mouse_hook(mouse_button_event( + mouse_event_t::MOUSE_RELEASE, + ev.xbutton.x, ev.xbutton.y, ev.xbutton.x_root, ev.xbutton.y_root, + button, ev.xbutton.state + )); } #endif /* BUILD_MOUSE_EVENTS */ if (own_window.get(*state)) { @@ -499,11 +556,7 @@ bool display_output_x11::main_loop_wait(double t) { /* allow conky to hold input focus. */ break; } - /* forward the release to the desktop window */ - ev.xbutton.window = window.desktop; - ev.xbutton.x = ev.xbutton.x_root; - ev.xbutton.y = ev.xbutton.y_root; - XSendEvent(display, ev.xbutton.window, False, ButtonReleaseMask, &ev); + propagate_unconsumed_event(ev, consumed); } break; #ifdef BUILD_MOUSE_EVENTS @@ -512,13 +565,27 @@ bool display_output_x11::main_loop_wait(double t) { can't forward the event without filtering XQueryTree output. */ case MotionNotify: - llua_mouse_hook(mouse_move_event(&ev.xmotion)); - break; - case EnterNotify: - llua_mouse_hook(mouse_enter_event(&ev.xcrossing)); + consumed = llua_mouse_hook(mouse_move_event( + ev.xmotion.x, ev.xmotion.y, ev.xmotion.x_root, ev.xmotion.y_root, ev.xmotion.state + )); + propagate_unconsumed_event(ev, consumed); break; case LeaveNotify: - llua_mouse_hook(mouse_leave_event(&ev.xcrossing)); + XUngrabPointer(display, ev.xcrossing.time); + case EnterNotify: + { + bool not_over_conky = ev.xcrossing.x_root < window.x || ev.xcrossing.y_root < window.y || + ev.xcrossing.x_root > window.x + window.width || ev.xcrossing.y_root > window.y + window.height; + + if ((not_over_conky && ev.xcrossing.type == LeaveNotify) || + (!not_over_conky && ev.xcrossing.type == EnterNotify)) { + llua_mouse_hook(mouse_crossing_event( + ev.xcrossing.type == EnterNotify ? mouse_event_t::AREA_ENTER: mouse_event_t::AREA_LEAVE, + ev.xcrossing.x, ev.xcrossing.y, ev.xcrossing.x_root, ev.xcrossing.y_root + )); + // can't propagate these events in a way that makes sense + } + } break; #endif /* BUILD_MOUSE_EVENTS */ #endif diff --git a/src/mouse-events.cc b/src/mouse-events.cc index 0a8c86ae..f3daf8cf 100644 --- a/src/mouse-events.cc +++ b/src/mouse-events.cc @@ -25,10 +25,6 @@ #include #include -#ifdef BUILD_X11 -#include "X11/Xlib.h" -#endif /* BUILD_X11 */ - /* Lua helper functions */ template void push_table_value(lua_State *L, std::string key, T value); @@ -186,78 +182,20 @@ void mouse_positioned_event::push_lua_data(lua_State *L) const { push_table_value(L, "y_abs", this->y_abs); } -#ifdef BUILD_X11 -mouse_move_event::mouse_move_event(XMotionEvent *ev) { - this->type = MOUSE_MOVE; - this->x = ev->x; - this->y = ev->y; - this->x_abs = ev->x_root; - this->y_abs = ev->y_root; -} -#endif /* BUILD_X11 */ - void mouse_move_event::push_lua_data(lua_State *L) const { mouse_positioned_event::push_lua_data(L); push_mods(L, this->mods); } -#ifdef BUILD_X11 -mouse_scroll_event::mouse_scroll_event(XButtonEvent *ev) { - this->type = MOUSE_SCROLL; - this->x = ev->x; - this->y = ev->y; - this->x_abs = ev->x_root; - this->y_abs = ev->y_root; - this->mods = ev->state; - if (ev->button == 4) { - this->direction = scroll_direction_t::UP; - } else if (ev->button == 5) { - this->direction = scroll_direction_t::DOWN; - } -} -#endif /* BUILD_X11 */ - void mouse_scroll_event::push_lua_data(lua_State *L) const { mouse_positioned_event::push_lua_data(L); push_table_value(L, "direction", this->direction); push_mods(L, this->mods); } -#ifdef BUILD_X11 -mouse_button_event::mouse_button_event(XButtonEvent *ev) { - this->type = ev->type == ButtonPress ? MOUSE_PRESS : MOUSE_RELEASE; - this->x = ev->x; - this->y = ev->y; - this->x_abs = ev->x_root; - this->y_abs = ev->y_root; - this->mods = ev->state; - switch (ev->button) { - case Button1: - this->button = BUTTON_LEFT; - break; - case Button2: - this->button = BUTTON_RIGHT; - break; - case Button3: - this->button = BUTTON_MIDDLE; - break; - } -} -#endif /* BUILD_X11 */ - void mouse_button_event::push_lua_data(lua_State *L) const { mouse_positioned_event::push_lua_data(L); push_table_value(L, "button_code", static_cast(this->button)); push_table_value(L, "button", this->button); push_mods(L, this->mods); } - -#ifdef BUILD_X11 -mouse_crossing_event::mouse_crossing_event(XCrossingEvent *ev) { - this->type = ev->type == EnterNotify ? AREA_ENTER : AREA_LEAVE; - this->x = ev->x; - this->y = ev->y; - this->x_abs = ev->x_root; - this->y_abs = ev->y_root; -} -#endif /* BUILD_X11 */ diff --git a/src/mouse-events.h b/src/mouse-events.h index d9bde1b8..e842a9cc 100644 --- a/src/mouse-events.h +++ b/src/mouse-events.h @@ -25,12 +25,6 @@ #include extern "C" { -#ifdef BUILD_X11 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wvariadic-macros" -#include -#pragma GCC diagnostic pop -#endif /* BUILD_X11 */ #include } @@ -91,10 +85,7 @@ struct mouse_positioned_event : public mouse_event { struct mouse_move_event : public mouse_positioned_event { std::bitset<13> mods; // held buttons and modifiers (ctrl, shift, ...) - mouse_move_event(mouse_event_t type, size_t x, size_t y, size_t x_abs, size_t y_abs, std::bitset<13> mods = 0): mouse_positioned_event{type, x, y, x_abs, y_abs}, mods(mods) {}; - #ifdef BUILD_X11 - explicit mouse_move_event(XMotionEvent *ev); - #endif /* BUILD_X11 */ + mouse_move_event(size_t x, size_t y, size_t x_abs, size_t y_abs, std::bitset<13> mods = 0): mouse_positioned_event{mouse_event_t::MOUSE_MOVE, x, y, x_abs, y_abs}, mods(mods) {}; void push_lua_data(lua_State *L) const; }; @@ -110,10 +101,7 @@ struct mouse_scroll_event : public mouse_positioned_event { std::bitset<13> mods; // held buttons and modifiers (ctrl, shift, ...) scroll_direction_t direction; - mouse_scroll_event(mouse_event_t type, size_t x, size_t y, size_t x_abs, size_t y_abs, scroll_direction_t direction, std::bitset<13> mods = 0): mouse_positioned_event{type, x, y, x_abs, y_abs}, direction(direction), mods(mods) {}; - #ifdef BUILD_X11 - explicit mouse_scroll_event(XButtonEvent *ev); - #endif /* BUILD_X11 */ + mouse_scroll_event(size_t x, size_t y, size_t x_abs, size_t y_abs, scroll_direction_t direction, std::bitset<13> mods = 0): mouse_positioned_event{mouse_event_t::MOUSE_SCROLL, x, y, x_abs, y_abs}, direction(direction), mods(mods) {}; void push_lua_data(lua_State *L) const; }; @@ -123,24 +111,12 @@ struct mouse_button_event : public mouse_positioned_event { mouse_button_t button; mouse_button_event(mouse_event_t type, size_t x, size_t y, size_t x_abs, size_t y_abs, mouse_button_t button, std::bitset<13> mods = 0): mouse_positioned_event{type, x, y, x_abs, y_abs}, button(button), mods(mods) {}; - #ifdef BUILD_X11 - explicit mouse_button_event(XButtonEvent *ev); - #endif /* BUILD_X11 */ void push_lua_data(lua_State *L) const; }; -typedef struct mouse_button_event mouse_press_event; -typedef struct mouse_button_event mouse_release_event; - struct mouse_crossing_event : public mouse_positioned_event { mouse_crossing_event(mouse_event_t type, size_t x, size_t y, size_t x_abs, size_t y_abs): mouse_positioned_event{type, x, y, x_abs, y_abs} {}; - #ifdef BUILD_X11 - explicit mouse_crossing_event(XCrossingEvent *ev); - #endif /* BUILD_X11 */ }; -typedef struct mouse_crossing_event mouse_enter_event; -typedef struct mouse_crossing_event mouse_leave_event; - #endif /* MOUSE_EVENTS_H */