From 9ebf2503126bcb5d8518a3539f8e8af086d68a40 Mon Sep 17 00:00:00 2001 From: tsujan Date: Thu, 28 Nov 2024 22:37:34 +0330 Subject: [PATCH] Put dropdown window on active screen under Wayland (#1196) All complex problems in implementing this feature were caused by resizing the window programmatically on Wayland, as was done on X11. This patch sets 4 anchors instead, and then sets the left, right and bottom margins properly on showing the window. Fixes https://github.com/lxqt/qterminal/issues/1142 --- src/mainwindow.cpp | 39 ++++++++++++++++++++++++++++++++------- src/mainwindow.h | 5 +++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 10290604..3fe1c317 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -69,7 +69,8 @@ MainWindow::MainWindow(TerminalConfig &cfg, presetsMenu(nullptr), m_config(cfg), m_dropLockButton(nullptr), - m_dropMode(dropMode) + m_dropMode(dropMode), + m_layerWindow(nullptr) { #ifdef HAVE_QDBUS registerAdapter(this); @@ -176,12 +177,17 @@ void MainWindow::enableDropMode() winId(); if (QWindow *win = windowHandle()) { - if (LayerShellQt::Window* layershell = LayerShellQt::Window::get(win)) + m_layerWindow = LayerShellQt::Window::get(win); + if (m_layerWindow) { - layershell->setLayer(LayerShellQt::Window::Layer::LayerOverlay); - layershell->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityOnDemand); - LayerShellQt::Window::Anchors anchors = {LayerShellQt::Window::AnchorTop}; - layershell->setAnchors(anchors); + m_layerWindow->setLayer(LayerShellQt::Window::Layer::LayerOverlay); + m_layerWindow->setKeyboardInteractivity(LayerShellQt::Window::KeyboardInteractivityOnDemand); + LayerShellQt::Window::Anchors anchors = {LayerShellQt::Window::AnchorTop + | LayerShellQt::Window::AnchorBottom + | LayerShellQt::Window::AnchorLeft + | LayerShellQt::Window::AnchorRight}; + m_layerWindow->setAnchors(anchors); + m_layerWindow->setScreenConfiguration(LayerShellQt::Window::ScreenConfiguration::ScreenFromCompositor); } } } @@ -757,9 +763,15 @@ void MainWindow::realign() { if (m_dropMode) { + if (m_layerWindow) + { + return; // done in showEvent + } QScreen *appScreen = QGuiApplication::screenAt(QCursor::pos()); if(appScreen == nullptr) + { appScreen = QGuiApplication::primaryScreen(); + } const QRect desktop = appScreen->availableGeometry(); QRect g = QRect(desktop.x(), desktop.y(), @@ -768,7 +780,8 @@ void MainWindow::realign() g.moveCenter(desktop.center()); // do not use 0 here - we need to calculate with potential panel on top g.moveTop(desktop.top()); - if (g != geometry()) { + if (g != geometry()) + { setGeometry(g); } } @@ -871,6 +884,18 @@ bool MainWindow::event(QEvent *event) return QMainWindow::event(event); } +void MainWindow::showEvent(QShowEvent* event) +{ + if (m_dropMode && m_layerWindow) + { + const QRect desktop = windowHandle()->screen()->availableGeometry(); + int hMargin = desktop.width() * (100 - Properties::Instance()->dropWidth) / 200; + int vMargin = desktop.height() * (100 - Properties::Instance()->dropHeight) / 100; + m_layerWindow->setMargins(QMargins(hMargin, 0, hMargin, vMargin)); + } + QMainWindow::showEvent(event); +} + void MainWindow::newTerminalWindow() { TerminalConfig cfg; diff --git a/src/mainwindow.h b/src/mainwindow.h index 4a353831..e67baed0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -28,6 +28,9 @@ #include "terminalconfig.h" #include "dbusaddressable.h" +namespace LayerShellQt { + class Window; +} class QToolButton; @@ -55,6 +58,7 @@ class MainWindow : public QMainWindow, private Ui::mainWindow, public DBusAddres protected: bool event(QEvent* event) override; + void showEvent(QShowEvent* event) override; private: QActionGroup *tabPosition, *scrollBarPosition, *keyboardCursorShape; @@ -86,6 +90,7 @@ class MainWindow : public QMainWindow, private Ui::mainWindow, public DBusAddres void enableDropMode(); QToolButton *m_dropLockButton; bool m_dropMode; + LayerShellQt::Window *m_layerWindow; QxtGlobalShortcut m_dropShortcut; void realign(); void setDropShortcut(const QKeySequence& dropShortCut);