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. # Please note that the package source code is licensed under its own license.
project ( toluapp C ) 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 # Disable dist stuff, we're not installing this as a lib
# include ( cmake/dist.cmake ) # 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}) set(conky_includes ${conky_includes} ${LUA_INCLUDE_DIR})
include_directories(3rdparty/toluapp/include) include_directories(3rdparty/toluapp/include)
if(BUILD_X11) if(BUILD_GUI)
# Check for libraries used by Lua bindings # Check for libraries used by Lua bindings
if(BUILD_LUA_CAIRO) if(BUILD_LUA_CAIRO)
pkg_check_modules(CAIRO REQUIRED cairo>=1.14 cairo-xlib) 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_libs ${IMLIB2_LIBS} ${IMLIB2_LDFLAGS} ${LUA_LIBRARIES})
set(luaimlib2_includes set(luaimlib2_includes
${IMLIB2_INCLUDE_DIRS} ${IMLIB2_INCLUDE_DIRS}
${LUA_INCLUDE_DIR} ${LUA_INCLUDE_DIR})
${X11_INCLUDE_DIR})
endif(BUILD_LUA_IMLIB2) endif(BUILD_LUA_IMLIB2)
if(BUILD_LUA_RSVG) if(BUILD_LUA_RSVG)
@ -478,7 +477,7 @@ if(BUILD_X11)
set(luarsvg_libs ${RSVG_LIBRARIES} ${LUA_LIBRARIES}) set(luarsvg_libs ${RSVG_LIBRARIES} ${LUA_LIBRARIES})
set(luarsvg_includes ${RSVG_INCLUDE_DIRS} ${LUA_INCLUDE_DIR}) set(luarsvg_includes ${RSVG_INCLUDE_DIRS} ${LUA_INCLUDE_DIR})
endif(BUILD_LUA_RSVG) endif(BUILD_LUA_RSVG)
endif(BUILD_X11) endif(BUILD_GUI)
if(BUILD_AUDACIOUS) if(BUILD_AUDACIOUS)
set(WANT_GLIB true) set(WANT_GLIB true)

View File

@ -239,16 +239,16 @@ endif(BUILD_PORT_MONITORS)
if(BUILD_X11) if(BUILD_X11)
set(x11 x11.cc x11.h) set(x11 x11.cc x11.h)
set(optional_sources ${optional_sources} ${x11}) 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) endif(BUILD_X11)
if(BUILD_GUI) if(BUILD_GUI)
set(gui fonts.cc fonts.h gui.cc gui.h) set(gui fonts.cc fonts.h gui.cc gui.h)
set(optional_sources ${optional_sources} ${gui}) 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) endif(BUILD_GUI)
if(BUILD_WAYLAND) if(BUILD_WAYLAND)

View File

@ -491,7 +491,6 @@ static void on_pointer_motion(void *data,
size_t abs_y = w->rectangle.y + y; size_t abs_y = w->rectangle.y + y;
mouse_move_event event { mouse_move_event event {
mouse_event_t::MOUSE_MOVE,
x, x,
y, y,
abs_x, abs_x,
@ -552,7 +551,6 @@ void on_pointer_axis(void *data,
size_t abs_y = w->rectangle.y + y; size_t abs_y = w->rectangle.y + y;
mouse_scroll_event event { mouse_scroll_event event {
mouse_event_t::MOUSE_SCROLL,
x, x,
y, y,
abs_x, abs_x,

View File

@ -7,7 +7,7 @@
* Copyright (C) 2018-2021 François Revol et al. * Copyright (C) 2018-2021 François Revol et al.
* Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
* Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al. * Copyright (c) 2005-2021 Brenden Matthews, Philip Kovacs, et. al.
* (see AUTHORS) * (see AUTHORS)
* All rights reserved. * All rights reserved.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -24,7 +24,10 @@
* *
*/ */
#include <X11/X.h>
#include <config.h> #include <config.h>
#include <cstdint>
#include "logging.h"
#ifdef BUILD_X11 #ifdef BUILD_X11
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -37,7 +40,7 @@
#include "x11.h" #include "x11.h"
#ifdef BUILD_XDAMAGE #ifdef BUILD_XDAMAGE
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
#endif #endif /* BUILD_XDAMAGE */
#include "fonts.h" #include "fonts.h"
#ifdef BUILD_IMLIB2 #ifdef BUILD_IMLIB2
#include "imlib2.h" #include "imlib2.h"
@ -227,6 +230,29 @@ bool display_output_x11::shutdown() {
return true; 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) { bool display_output_x11::main_loop_wait(double t) {
/* wait for X event or timeout */ /* wait for X event or timeout */
if (!display || !window.gc) return true; if (!display || !window.gc) return true;
@ -458,10 +484,34 @@ bool display_output_x11::main_loop_wait(double t) {
case ButtonPress: case ButtonPress:
#ifdef BUILD_MOUSE_EVENTS #ifdef BUILD_MOUSE_EVENTS
if (ev.xbutton.button == 4 || ev.xbutton.button == 5) { if (ev.xbutton.button == 4) {
consumed = llua_mouse_hook(mouse_scroll_event(&ev.xbutton)); 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 { } 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 */ #endif /* BUILD_MOUSE_EVENTS */
if (own_window.get(*state)) { if (own_window.get(*state)) {
@ -472,16 +522,7 @@ bool display_output_x11::main_loop_wait(double t) {
/* allow conky to hold input focus. */ /* allow conky to hold input focus. */
break; break;
} }
XUngrabPointer(display, ev.xbutton.time); propagate_unconsumed_event(ev, consumed);
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);
}
} }
break; break;
@ -489,7 +530,23 @@ bool display_output_x11::main_loop_wait(double t) {
#ifdef BUILD_MOUSE_EVENTS #ifdef BUILD_MOUSE_EVENTS
/* don't report scrollwheel release events */ /* don't report scrollwheel release events */
if (ev.xbutton.button != Button4 && ev.xbutton.button != Button5) { 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 */ #endif /* BUILD_MOUSE_EVENTS */
if (own_window.get(*state)) { if (own_window.get(*state)) {
@ -499,11 +556,7 @@ bool display_output_x11::main_loop_wait(double t) {
/* allow conky to hold input focus. */ /* allow conky to hold input focus. */
break; break;
} }
/* forward the release to the desktop window */ propagate_unconsumed_event(ev, consumed);
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);
} }
break; break;
#ifdef BUILD_MOUSE_EVENTS #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. can't forward the event without filtering XQueryTree output.
*/ */
case MotionNotify: case MotionNotify:
llua_mouse_hook(mouse_move_event(&ev.xmotion)); consumed = llua_mouse_hook(mouse_move_event(
break; ev.xmotion.x, ev.xmotion.y, ev.xmotion.x_root, ev.xmotion.y_root, ev.xmotion.state
case EnterNotify: ));
llua_mouse_hook(mouse_enter_event(&ev.xcrossing)); propagate_unconsumed_event(ev, consumed);
break; break;
case LeaveNotify: 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; break;
#endif /* BUILD_MOUSE_EVENTS */ #endif /* BUILD_MOUSE_EVENTS */
#endif #endif

View File

@ -25,10 +25,6 @@
#include <lua.h> #include <lua.h>
#include <time.h> #include <time.h>
#ifdef BUILD_X11
#include "X11/Xlib.h"
#endif /* BUILD_X11 */
/* Lua helper functions */ /* Lua helper functions */
template <typename T> template <typename T>
void push_table_value(lua_State *L, std::string key, T value); 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); 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 { void mouse_move_event::push_lua_data(lua_State *L) const {
mouse_positioned_event::push_lua_data(L); mouse_positioned_event::push_lua_data(L);
push_mods(L, this->mods); 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 { void mouse_scroll_event::push_lua_data(lua_State *L) const {
mouse_positioned_event::push_lua_data(L); mouse_positioned_event::push_lua_data(L);
push_table_value(L, "direction", this->direction); push_table_value(L, "direction", this->direction);
push_mods(L, this->mods); 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 { void mouse_button_event::push_lua_data(lua_State *L) const {
mouse_positioned_event::push_lua_data(L); mouse_positioned_event::push_lua_data(L);
push_table_value(L, "button_code", static_cast<uint32_t>(this->button)); push_table_value(L, "button_code", static_cast<uint32_t>(this->button));
push_table_value(L, "button", this->button); push_table_value(L, "button", this->button);
push_mods(L, this->mods); 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> #include <cstdint>
extern "C" { 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> #include <lua.h>
} }
@ -91,10 +85,7 @@ struct mouse_positioned_event : public mouse_event {
struct mouse_move_event : public mouse_positioned_event { struct mouse_move_event : public mouse_positioned_event {
std::bitset<13> mods; // held buttons and modifiers (ctrl, shift, ...) 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) {}; 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) {};
#ifdef BUILD_X11
explicit mouse_move_event(XMotionEvent *ev);
#endif /* BUILD_X11 */
void push_lua_data(lua_State *L) const; 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, ...) std::bitset<13> mods; // held buttons and modifiers (ctrl, shift, ...)
scroll_direction_t direction; 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) {}; 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) {};
#ifdef BUILD_X11
explicit mouse_scroll_event(XButtonEvent *ev);
#endif /* BUILD_X11 */
void push_lua_data(lua_State *L) const; 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_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) {}; 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; 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 { 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} {}; 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 */ #endif /* MOUSE_EVENTS_H */