Merge pull request #5562 from Cacodemon345/wayland-fixes
Implement keyboard grabbing for Wayland
This commit is contained in:
@@ -453,6 +453,7 @@ if (UNIX AND NOT APPLE AND NOT HAIKU)
|
||||
set(WL_SOURCE_VAR)
|
||||
ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/relative-pointer-unstable-v1.xml BASENAME relative-pointer-unstable-v1)
|
||||
ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1)
|
||||
ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/keyboard-shortcuts-inhibit-unstable-v1.xml BASENAME keyboard-shortcuts-inhibit-unstable-v1)
|
||||
target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS})
|
||||
target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp)
|
||||
if (XKBCOMMON_FOUND)
|
||||
|
||||
@@ -672,6 +672,16 @@ main(int argc, char *argv[])
|
||||
} else {
|
||||
main_window->show();
|
||||
}
|
||||
#ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland")) {
|
||||
/* Force a sync. */
|
||||
(void)main_window->winId();
|
||||
QApplication::sync();
|
||||
extern void wl_keyboard_grab(QWindow *window);
|
||||
wl_keyboard_grab(main_window->windowHandle());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
app.installEventFilter(main_window);
|
||||
|
||||
|
||||
@@ -322,7 +322,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
if (ui->stackedWidget->mouse_capture_func)
|
||||
ui->stackedWidget->mouse_capture_func(this->windowHandle());
|
||||
} else {
|
||||
this->releaseKeyboard();
|
||||
if (!(windowState() & Qt::WindowActive))
|
||||
this->releaseKeyboard();
|
||||
if (ui->stackedWidget->mouse_uncapture_func) {
|
||||
ui->stackedWidget->mouse_uncapture_func();
|
||||
}
|
||||
@@ -1491,8 +1492,26 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event)
|
||||
curdopause = dopause;
|
||||
plat_pause(isShowMessage ? 2 : 1);
|
||||
emit setMouseCapture(false);
|
||||
releaseKeyboard();
|
||||
} else if (event->type() == QEvent::WindowUnblocked) {
|
||||
plat_pause(curdopause);
|
||||
#ifdef __unix__
|
||||
if (!QApplication::platformName().contains("wayland") && (this->windowState() & Qt::WindowActive)) {
|
||||
this->grabKeyboard();
|
||||
}
|
||||
#endif
|
||||
} else if (event->type() == QEvent::WindowActivate) {
|
||||
#ifdef __unix__
|
||||
if (!QApplication::platformName().contains("wayland")) {
|
||||
this->grabKeyboard();
|
||||
}
|
||||
#endif
|
||||
} else if (event->type() == QEvent::WindowDeactivate) {
|
||||
#ifdef __unix__
|
||||
if (!QApplication::platformName().contains("wayland")) {
|
||||
this->releaseKeyboard();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1610,13 +1629,13 @@ MainWindow::getRenderWidgetSize()
|
||||
void
|
||||
MainWindow::focusInEvent(QFocusEvent *event)
|
||||
{
|
||||
this->grabKeyboard();
|
||||
//this->grabKeyboard();
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
this->releaseKeyboard();
|
||||
//this->releaseKeyboard();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-relative-pointer-unstable-v1-client-protocol.h>
|
||||
#include <wayland-pointer-constraints-unstable-v1-client-protocol.h>
|
||||
#include <wayland-keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
|
||||
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QWindow>
|
||||
@@ -30,10 +31,12 @@ extern "C" {
|
||||
#include <86box/plat.h>
|
||||
}
|
||||
|
||||
static zwp_relative_pointer_manager_v1 *rel_manager = nullptr;
|
||||
static zwp_relative_pointer_v1 *rel_pointer = nullptr;
|
||||
static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr;
|
||||
static zwp_locked_pointer_v1 *conf_pointer = nullptr;
|
||||
static zwp_relative_pointer_manager_v1 *rel_manager = nullptr;
|
||||
static zwp_relative_pointer_v1 *rel_pointer = nullptr;
|
||||
static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr;
|
||||
static zwp_locked_pointer_v1 *conf_pointer = nullptr;
|
||||
static zwp_keyboard_shortcuts_inhibit_manager_v1 *kbd_manager = nullptr;
|
||||
static zwp_keyboard_shortcuts_inhibitor_v1 *kbd_inhibitor = nullptr;
|
||||
|
||||
static bool wl_init_ok = false;
|
||||
|
||||
@@ -47,6 +50,12 @@ static struct zwp_relative_pointer_v1_listener rel_listener = {
|
||||
rel_mouse_event
|
||||
};
|
||||
|
||||
static struct zwp_keyboard_shortcuts_inhibitor_v1_listener kbd_listener
|
||||
{
|
||||
[](void *data, struct zwp_keyboard_shortcuts_inhibitor_v1 *zwp_keyboard_shortcuts_inhibitor_v1) -> void {},
|
||||
[](void *data, struct zwp_keyboard_shortcuts_inhibitor_v1 *zwp_keyboard_shortcuts_inhibitor_v1) -> void {}
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
const char *interface, uint32_t version)
|
||||
@@ -57,16 +66,25 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
||||
if (!strcmp(interface, "zwp_pointer_constraints_v1")) {
|
||||
conf_pointer_interface = (zwp_pointer_constraints_v1 *) wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version);
|
||||
}
|
||||
if (!strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1")) {
|
||||
kbd_manager = (zwp_keyboard_shortcuts_inhibit_manager_v1 *) wl_registry_bind(registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, version);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
|
||||
{
|
||||
plat_mouse_capture(0);
|
||||
if (kbd_inhibitor) {
|
||||
zwp_keyboard_shortcuts_inhibitor_v1_destroy(kbd_inhibitor);
|
||||
kbd_inhibitor = nullptr;
|
||||
}
|
||||
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(kbd_manager);
|
||||
zwp_relative_pointer_manager_v1_destroy(rel_manager);
|
||||
zwp_pointer_constraints_v1_destroy(conf_pointer_interface);
|
||||
rel_manager = nullptr;
|
||||
conf_pointer_interface = nullptr;
|
||||
kbd_manager = nullptr;
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
@@ -90,9 +108,20 @@ wl_init()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wl_keyboard_grab(QWindow *window)
|
||||
{
|
||||
if (!kbd_inhibitor && kbd_manager) {
|
||||
kbd_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(kbd_manager, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_seat *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_seat"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wl_mouse_capture(QWindow *window)
|
||||
{
|
||||
if (!kbd_inhibitor) {
|
||||
kbd_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(kbd_manager, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_seat *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_seat"));
|
||||
}
|
||||
if (rel_manager) {
|
||||
rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"));
|
||||
zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user