From b90ae2f8fc7ba5c2ad29c728a868f7af63df37ce Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Thu, 1 Jun 2023 13:31:04 +0300 Subject: [PATCH] Move window hiding logic to Window The window hiding logic is mostly the same both in X11 and Wayland windows, so let's move it in Window to share the same code. --- .../integration/move_resize_window_test.cpp | 2 +- autotests/integration/window_rules_test.cpp | 2 - autotests/integration/xdgshellwindow_test.cpp | 4 +- autotests/integration/xwayland_input_test.cpp | 1 - src/activation.cpp | 2 +- src/effects.cpp | 2 +- src/events.cpp | 2 +- src/input.cpp | 4 +- src/inputpanelv1window.cpp | 4 +- src/internalwindow.cpp | 18 --------- src/internalwindow.h | 4 -- src/layershellv1window.cpp | 8 ++-- src/scene/windowitem.cpp | 2 +- src/scripting/workspace_wrapper.cpp | 2 +- src/waylandwindow.cpp | 37 ------------------ src/waylandwindow.h | 6 --- src/window.cpp | 29 ++++++++++++++ src/window.h | 11 +++--- src/workspace.cpp | 6 +-- src/x11window.cpp | 39 +++++-------------- src/x11window.h | 19 +-------- 21 files changed, 65 insertions(+), 139 deletions(-) diff --git a/autotests/integration/move_resize_window_test.cpp b/autotests/integration/move_resize_window_test.cpp index c48dee80aa..4551cebfab 100644 --- a/autotests/integration/move_resize_window_test.cpp +++ b/autotests/integration/move_resize_window_test.cpp @@ -754,7 +754,7 @@ void MoveResizeWindowTest::testAdjustClientGeometryOfHiddenWaylandPanel() QTEST(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false).toPoint(), "expectedAdjustedPoint"); // now let's hide the panel - panel->hideClient(); + panel->setHidden(true); // now try to snap again QCOMPARE(Workspace::self()->adjustWindowPosition(testWindow, targetPoint, false), targetPoint); diff --git a/autotests/integration/window_rules_test.cpp b/autotests/integration/window_rules_test.cpp index 5ec62b856a..f4b3a01829 100644 --- a/autotests/integration/window_rules_test.cpp +++ b/autotests/integration/window_rules_test.cpp @@ -118,7 +118,6 @@ void WindowRuleTest::testApplyInitialMaximizeVert() QVERIFY(window); QVERIFY(window->isDecorated()); QVERIFY(!window->hasStrut()); - QVERIFY(!window->isHiddenInternal()); QVERIFY(!window->readyForPainting()); QMetaObject::invokeMethod(window, "setReadyForPainting"); QVERIFY(window->readyForPainting()); @@ -181,7 +180,6 @@ void WindowRuleTest::testWindowClassChange() QVERIFY(window); QVERIFY(window->isDecorated()); QVERIFY(!window->hasStrut()); - QVERIFY(!window->isHiddenInternal()); QVERIFY(!window->readyForPainting()); QMetaObject::invokeMethod(window, "setReadyForPainting"); QVERIFY(window->readyForPainting()); diff --git a/autotests/integration/xdgshellwindow_test.cpp b/autotests/integration/xdgshellwindow_test.cpp index 82dba96d09..a0aff5a78a 100644 --- a/autotests/integration/xdgshellwindow_test.cpp +++ b/autotests/integration/xdgshellwindow_test.cpp @@ -618,14 +618,14 @@ void TestXdgShellWindow::testHidden() QVERIFY(window->wantsTabFocus()); QVERIFY(window->isShown()); - window->hideClient(); + window->setHidden(true); QVERIFY(!window->isShown()); QVERIFY(!window->isActive()); QVERIFY(window->wantsInput()); QVERIFY(window->wantsTabFocus()); // unhide again - window->showClient(); + window->setHidden(false); QVERIFY(window->isShown()); QVERIFY(window->wantsInput()); QVERIFY(window->wantsTabFocus()); diff --git a/autotests/integration/xwayland_input_test.cpp b/autotests/integration/xwayland_input_test.cpp index e6e52298e7..5352c4e985 100644 --- a/autotests/integration/xwayland_input_test.cpp +++ b/autotests/integration/xwayland_input_test.cpp @@ -153,7 +153,6 @@ void XWaylandInputTest::testPointerEnterLeaveSsd() QVERIFY(window); QVERIFY(window->isDecorated()); QVERIFY(!window->hasStrut()); - QVERIFY(!window->isHiddenInternal()); QVERIFY(!window->readyForPainting()); QMetaObject::invokeMethod(window, "setReadyForPainting"); diff --git a/src/activation.cpp b/src/activation.cpp index 36788018bd..df80da8463 100644 --- a/src/activation.cpp +++ b/src/activation.cpp @@ -323,7 +323,7 @@ void Workspace::activateWindow(Window *window, bool force) } // ensure the window is really visible - could eg. be a hidden utility window, see bug #348083 - window->showClient(); + window->setHidden(false); // TODO force should perhaps allow this only if the window already contains the mouse if (options->focusPolicyIsReasonable() || force) { diff --git a/src/effects.cpp b/src/effects.cpp index 0d78ac0297..fc5c059622 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -1953,7 +1953,7 @@ WINDOW_HELPER(bool, isLockScreen, isLockScreen) WINDOW_HELPER(pid_t, pid, pid) WINDOW_HELPER(QUuid, internalId, internalId) WINDOW_HELPER(bool, isMinimized, isMinimized) -WINDOW_HELPER(bool, isHidden, isHiddenInternal) +WINDOW_HELPER(bool, isHidden, isHidden) WINDOW_HELPER(bool, isHiddenByShowDesktop, isHiddenByShowDesktop) WINDOW_HELPER(bool, isModal, isModal) WINDOW_HELPER(bool, isFullScreen, isFullScreen) diff --git a/src/events.cpp b/src/events.cpp index 054e9be769..a3b43bc8db 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -987,7 +987,7 @@ bool X11Window::buttonPressEvent(xcb_window_t w, int button, int state, int x, i if (isSplash() && button == XCB_BUTTON_INDEX_1 && !bModKeyHeld) { // hide splashwindow if the user clicks on it - hideClient(); + setHidden(true); if (w == wrapperId()) { xcb_allow_events(kwinApp()->x11Connection(), XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME); // xTime()); } diff --git a/src/input.cpp b/src/input.cpp index 6d2816f716..5afcea64b6 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -2563,7 +2563,7 @@ private: if (!window->isClient()) { continue; } - if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHiddenInternal() || window->isHiddenByShowDesktop()) { + if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHidden() || window->isHiddenByShowDesktop()) { continue; } if (!window->readyForPainting()) { @@ -3203,7 +3203,7 @@ Window *InputRedirection::findToplevel(const QPointF &pos) // a deleted window doesn't get mouse events continue; } - if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHiddenInternal() || window->isHiddenByShowDesktop()) { + if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHidden() || window->isHiddenByShowDesktop()) { continue; } if (!window->readyForPainting()) { diff --git a/src/inputpanelv1window.cpp b/src/inputpanelv1window.cpp index e2424b976a..9503c4ab91 100644 --- a/src/inputpanelv1window.cpp +++ b/src/inputpanelv1window.cpp @@ -74,7 +74,7 @@ void InputPanelV1Window::hide() { m_virtualKeyboardShouldBeShown = false; if (readyForPainting() && m_mode != Mode::Overlay) { - hideClient(); + setHidden(true); } } @@ -192,7 +192,7 @@ void InputPanelV1Window::maybeShow() if (shouldShow && !isDeleted() && surface()->isMapped()) { markAsMapped(); reposition(); - showClient(); + setHidden(false); } } diff --git a/src/internalwindow.cpp b/src/internalwindow.cpp index d001b6b685..ddb137acc5 100644 --- a/src/internalwindow.cpp +++ b/src/internalwindow.cpp @@ -242,24 +242,6 @@ bool InternalWindow::isOutline() const return false; } -bool InternalWindow::isShown() const -{ - return readyForPainting() && !isHiddenByShowDesktop(); -} - -bool InternalWindow::isHiddenInternal() const -{ - return false; -} - -void InternalWindow::hideClient() -{ -} - -void InternalWindow::showClient() -{ -} - QRectF InternalWindow::resizeWithChecks(const QRectF &geometry, const QSizeF &size) { if (!m_handle) { diff --git a/src/internalwindow.h b/src/internalwindow.h index e5d92be4d8..7a0308c9bd 100644 --- a/src/internalwindow.h +++ b/src/internalwindow.h @@ -47,10 +47,6 @@ public: bool isInternal() const override; bool isLockScreen() const override; bool isOutline() const override; - bool isShown() const override; - bool isHiddenInternal() const override; - void hideClient() override; - void showClient() override; QRectF resizeWithChecks(const QRectF &geometry, const QSizeF &size) override; Window *findModal(bool allow_itself = false) override; bool takeFocus() override; diff --git a/src/layershellv1window.cpp b/src/layershellv1window.cpp index 631e26f2d3..f01e2ac385 100644 --- a/src/layershellv1window.cpp +++ b/src/layershellv1window.cpp @@ -297,7 +297,7 @@ void LayerShellV1Window::setVirtualKeyboardGeometry(const QRectF &geo) void LayerShellV1Window::showOnScreenEdge() { - // ShowOnScreenEdge can be called by an Edge, and hideClient could destroy the Edge + // ShowOnScreenEdge can be called by an Edge, and setHidden could destroy the Edge // Use the singleshot to avoid use-after-free QTimer::singleShot(0, this, &LayerShellV1Window::deactivateScreenEdge); } @@ -323,15 +323,15 @@ void LayerShellV1Window::installAutoHideScreenEdgeV1(KWaylandServer::AutoHideScr void LayerShellV1Window::reserveScreenEdge() { if (workspace()->screenEdges()->reserve(this, m_screenEdge->border())) { - hideClient(); + setHidden(true); } else { - showClient(); + setHidden(false); } } void LayerShellV1Window::unreserveScreenEdge() { - showClient(); + setHidden(false); workspace()->screenEdges()->reserve(this, ElectricNone); } diff --git a/src/scene/windowitem.cpp b/src/scene/windowitem.cpp index 06ad55f4ed..4dd3b939e7 100644 --- a/src/scene/windowitem.cpp +++ b/src/scene/windowitem.cpp @@ -170,7 +170,7 @@ bool WindowItem::computeVisibility() const return false; } } - if (m_window->isHiddenInternal() || m_window->isHiddenByShowDesktop()) { + if (m_window->isHidden() || m_window->isHiddenByShowDesktop()) { if (m_forceVisibleByHiddenCount == 0) { return false; } diff --git a/src/scripting/workspace_wrapper.cpp b/src/scripting/workspace_wrapper.cpp index 05241a8a03..e5049dddb2 100644 --- a/src/scripting/workspace_wrapper.cpp +++ b/src/scripting/workspace_wrapper.cpp @@ -317,7 +317,7 @@ QList WorkspaceWrapper::windowAt(const QPointF &pos, int count) if (window->isDeleted()) { continue; } - if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHiddenInternal() || window->isHiddenByShowDesktop()) { + if (!window->isOnCurrentActivity() || !window->isOnCurrentDesktop() || window->isMinimized() || window->isHidden() || window->isHiddenByShowDesktop()) { continue; } if (window->hitTest(pos)) { diff --git a/src/waylandwindow.cpp b/src/waylandwindow.cpp index 0a5278bbe7..7fdc4e6cce 100644 --- a/src/waylandwindow.cpp +++ b/src/waylandwindow.cpp @@ -238,43 +238,6 @@ void WaylandWindow::cleanGrouping() } } -bool WaylandWindow::isShown() const -{ - return !isDeleted() && !isHidden() && !isHiddenByShowDesktop() && !isMinimized(); -} - -bool WaylandWindow::isHiddenInternal() const -{ - return isHidden(); -} - -bool WaylandWindow::isHidden() const -{ - return m_isHidden; -} - -void WaylandWindow::showClient() -{ - if (!isHidden()) { - return; - } - m_isHidden = false; - Q_EMIT windowShown(this); -} - -void WaylandWindow::hideClient() -{ - if (isHidden()) { - return; - } - if (isInteractiveMoveResize()) { - leaveInteractiveMoveResize(); - } - m_isHidden = true; - workspace()->windowHidden(this); - Q_EMIT windowHidden(this); -} - QRectF WaylandWindow::frameRectToBufferRect(const QRectF &rect) const { return QRectF(rect.topLeft(), surface()->size()); diff --git a/src/waylandwindow.h b/src/waylandwindow.h index 2c7b5c8186..2ed8951379 100644 --- a/src/waylandwindow.h +++ b/src/waylandwindow.h @@ -28,13 +28,8 @@ public: QRectF resizeWithChecks(const QRectF &geometry, const QSizeF &size) override; void killWindow() override; QString windowRole() const override; - bool isShown() const override; - bool isHiddenInternal() const override; - void hideClient() override; - void showClient() override; virtual QRectF frameRectToBufferRect(const QRectF &rect) const; - bool isHidden() const; void setCaption(const QString &caption); @@ -56,7 +51,6 @@ private: QString m_captionNormal; QString m_captionSuffix; - bool m_isHidden = false; bool m_isScreenLocker = false; }; diff --git a/src/window.cpp b/src/window.cpp index d3ef167fac..ea4ed85448 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3566,6 +3566,10 @@ void Window::doSetQuickTileMode() { } +void Window::doSetHidden() +{ +} + void Window::doSetHiddenByShowDesktop() { } @@ -4213,6 +4217,31 @@ WindowOffscreenRenderRef::~WindowOffscreenRenderRef() } } +bool Window::isShown() const +{ + return !isDeleted() && !isHidden() && !isHiddenByShowDesktop() && !isMinimized(); +} + +bool Window::isHidden() const +{ + return m_hidden; +} + +void Window::setHidden(bool hidden) +{ + if (m_hidden == hidden) { + return; + } + m_hidden = hidden; + doSetHidden(); + if (hidden) { + workspace()->windowHidden(this); + Q_EMIT windowHidden(this); + } else { + Q_EMIT windowShown(this); + } +} + bool Window::isHiddenByShowDesktop() const { return m_hiddenByShowDesktop; diff --git a/src/window.h b/src/window.h index ef000c5dd0..1f05175422 100644 --- a/src/window.h +++ b/src/window.h @@ -530,7 +530,7 @@ class KWIN_EXPORT Window : public QObject /** * Whether this window is hidden. It's usually the case with auto-hide panels. */ - Q_PROPERTY(bool hidden READ isHiddenInternal NOTIFY hiddenChanged) + Q_PROPERTY(bool hidden READ isHidden NOTIFY hiddenChanged) /** * The Tile this window is associated to, if any @@ -932,10 +932,9 @@ public: virtual QString captionSuffix() const = 0; virtual bool isPlaceable() const; virtual bool isCloseable() const = 0; - virtual bool isShown() const = 0; - virtual bool isHiddenInternal() const = 0; - virtual void hideClient() = 0; - virtual void showClient() = 0; + bool isShown() const; + bool isHidden() const; + void setHidden(bool hidden); bool isHiddenByShowDesktop() const; void setHiddenByShowDesktop(bool hidden); // TODO: remove boolean trap @@ -1501,6 +1500,7 @@ protected: virtual void doSetSkipSwitcher(); virtual void doSetDemandsAttention(); virtual void doSetQuickTileMode(); + virtual void doSetHidden(); virtual void doSetHiddenByShowDesktop(); void setupWindowManagementInterface(); @@ -1723,6 +1723,7 @@ protected: QRectF m_clientGeometry; QRectF m_bufferGeometry; bool ready_for_painting; + bool m_hidden = false; bool m_hiddenByShowDesktop = false; int m_refCount = 1; diff --git a/src/workspace.cpp b/src/workspace.cpp index 87c0ba9232..9573299e0f 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -860,7 +860,7 @@ void Workspace::updateToolWindows(bool also_hide) if (!options->isHideUtilityWindowsForInactive()) { for (auto it = m_windows.constBegin(); it != m_windows.constEnd(); ++it) { if (X11Window *x11Window = qobject_cast(*it)) { - x11Window->showClient(); + x11Window->setHidden(false); } } return; @@ -931,11 +931,11 @@ void Workspace::updateToolWindows(bool also_hide) } // First show new ones, then hide for (int i = to_show.size() - 1; i >= 0; --i) { // From topmost // TODO: Since this is in stacking order, the order of taskbar entries changes :( - to_show.at(i)->showClient(); + to_show.at(i)->setHidden(false); } if (also_hide) { for (auto it = to_hide.constBegin(); it != to_hide.constEnd(); ++it) { // From bottommost - (*it)->hideClient(); + (*it)->setHidden(true); } updateToolWindowsTimer.stop(); } else { // setActiveWindow() is after called with NULL window, quickly followed diff --git a/src/x11window.cpp b/src/x11window.cpp index 2d463675b9..225b4aba66 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -315,7 +315,6 @@ X11Window::X11Window() info = nullptr; m_fullscreenMode = FullScreenNone; - hidden = false; noborder = false; app_noborder = false; ignore_focus_stealing = false; @@ -424,7 +423,6 @@ void X11Window::releaseWindow(bool on_shutdown) grabXServer(); exportMappingState(XCB_ICCCM_WM_STATE_WITHDRAWN); setModal(false); // Otherwise its mainwindow wouldn't get focus - hidden = true; // So that it's not considered visible anymore (can't use hideClient(), it would set flags) if (!on_shutdown) { workspace()->windowHidden(this); } @@ -495,7 +493,6 @@ void X11Window::destroyWindow() finishWindowRules(); blockGeometryUpdates(); setModal(false); - hidden = true; // So that it's not considered visible anymore workspace()->windowHidden(this); cleanGrouping(); workspace()->removeX11Window(this); @@ -1610,27 +1607,6 @@ void X11Window::updateInputShape() } } -void X11Window::hideClient() -{ - if (hidden) { - return; - } - hidden = true; - updateVisibility(); - workspace()->windowHidden(this); - Q_EMIT windowHidden(this); -} - -void X11Window::showClient() -{ - if (!hidden) { - return; - } - hidden = false; - updateVisibility(); - Q_EMIT windowShown(this); -} - bool X11Window::setupCompositing() { if (!Window::setupCompositing()) { @@ -1805,7 +1781,7 @@ void X11Window::updateVisibility() if (isUnmanaged() || isDeleted()) { return; } - if (hidden) { + if (isHidden()) { info->setState(NET::Hidden, NET::Hidden); setSkipTaskbar(true); // Also hide from taskbar if (Compositor::compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) { @@ -2187,6 +2163,11 @@ void X11Window::doSetDemandsAttention() info->setState(isDemandingAttention() ? NET::DemandsAttention : NET::States(), NET::DemandsAttention); } +void X11Window::doSetHidden() +{ + updateVisibility(); +} + void X11Window::doSetHiddenByShowDesktop() { updateVisibility(); @@ -2911,9 +2892,9 @@ void X11Window::readShowOnScreenEdge(Xcb::Property &property) auto reserveScreenEdge = [this, border]() { if (workspace()->screenEdges()->reserve(this, border)) { - hideClient(); + setHidden(true); } else { - showClient(); + setHidden(false); } }; @@ -2927,7 +2908,7 @@ void X11Window::readShowOnScreenEdge(Xcb::Property &property) // restore disconnect(m_edgeGeometryTrackingConnection); - showClient(); + setHidden(false); workspace()->screenEdges()->reserve(this, ElectricNone); } @@ -2941,7 +2922,7 @@ void X11Window::updateShowOnScreenEdge() void X11Window::showOnScreenEdge() { - showClient(); + setHidden(false); xcb_delete_property(kwinApp()->x11Connection(), window(), atoms->kde_screen_edge_show); } diff --git a/src/x11window.h b/src/x11window.h index 710005a2c3..dd08608585 100644 --- a/src/x11window.h +++ b/src/x11window.h @@ -143,10 +143,6 @@ public: void doSetOnActivities(const QStringList &newActivitiesList) override; void updateActivities(bool includeTransients) override; - /// Is not minimized and not hidden. I.e. normally visible on some virtual desktop. - bool isShown() const override; - bool isHiddenInternal() const override; // For compositing - bool isShadeable() const override; bool isMaximizable() const override; MaximizeMode maximizeMode() const override; @@ -200,9 +196,6 @@ public: /// Updates visibility depending on being shaded, virtual desktop, etc. void updateVisibility(); - /// Hides a client - Basically like minimize, but without effects, it's simply hidden - void hideClient() override; - void showClient() override; bool hiddenPreview() const; ///< Window is mapped in order to get a window pixmap bool setupCompositing() override; @@ -343,6 +336,7 @@ protected: void doSetSkipTaskbar() override; void doSetSkipSwitcher() override; void doSetDemandsAttention() override; + void doSetHidden() override; void doSetHiddenByShowDesktop() override; bool belongsToDesktop() const override; bool doStartInteractiveMoveResize() override; @@ -479,7 +473,6 @@ private: xcb_window_t m_originalTransientForId; X11Window *shade_below; Xcb::MotifHints m_motif; - uint hidden : 1; ///< Forcibly hidden by calling hide() uint noborder : 1; uint app_noborder : 1; ///< App requested no border via window type, shape extension, etc. uint ignore_focus_stealing : 1; ///< Don't apply focus stealing prevention to this client @@ -585,16 +578,6 @@ inline Group *X11Window::group() return in_group; } -inline bool X11Window::isShown() const -{ - return !isMinimized() && !hidden && !isHiddenByShowDesktop(); -} - -inline bool X11Window::isHiddenInternal() const -{ - return hidden; -} - inline MaximizeMode X11Window::maximizeMode() const { return max_mode;