Fix X11 build

Fix most issues with X11 event propagation.
Remove X11 code from mouse-events.cc/.h completely.

CMake:
Update toluapp cmake_minimum_required to stop it complaining during build.
Fix ConkyPlatformCheck.cmake not providing access to cairo, imlib2 and rsvg to Wayland.
Move BUILD_MOUSE_EVENTS includes under BUILD_GUI so they're not duplicated.

Signed-off-by: Tin <tin.svagelj@live.com>
This commit is contained in:
Tin 2023-11-08 03:29:59 +01:00 committed by Brenden Matthews
parent 8195533bb3
commit b1b7ae8b2c
No known key found for this signature in database
GPG Key ID: 137B7AC2BDFD8DF0
7 changed files with 104 additions and 126 deletions

View File

@ -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 )

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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 <X11/X.h>
#include <config.h>
#include <cstdint>
#include "logging.h"
#ifdef BUILD_X11
#pragma GCC diagnostic push
@ -37,7 +40,7 @@
#include "x11.h"
#ifdef BUILD_XDAMAGE
#include <X11/extensions/Xdamage.h>
#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

View File

@ -25,10 +25,6 @@
#include <lua.h>
#include <time.h>
#ifdef BUILD_X11
#include "X11/Xlib.h"
#endif /* BUILD_X11 */
/* Lua helper functions */
template <typename T>
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<uint32_t>(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 */

View File

@ -25,12 +25,6 @@
#include <cstdint>
extern "C" {
#ifdef BUILD_X11
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
#include <X11/Xlib.h>
#pragma GCC diagnostic pop
#endif /* BUILD_X11 */
#include <lua.h>
}
@ -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 */