From cbfcd3b0962a78676d77f31d89c9336cd6a8a2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 18 Feb 2015 01:37:45 +0100 Subject: [PATCH] implement showingDesktop by raising desktop window This is an alternative approach suggested by the NETWM spec. The advantage is, that windows are not minimized at all what apparently lead to some confusion about the nature of the mode (which was abused to tidy up) and a secret config key to allow for that unrelated behavior. Instead the ShowDesktopIsMinimizeAll key is removed and replaced by a dedicated script + shortcut. Bonus: less code to remember "minimized" windows =) --- client.cpp | 6 ++--- client.h | 2 +- layers.cpp | 2 +- manage.cpp | 2 +- workspace.cpp | 74 +++++---------------------------------------------- workspace.h | 3 --- 6 files changed, 12 insertions(+), 77 deletions(-) diff --git a/client.cpp b/client.cpp index 8bf10e8058..a6fbf3ea92 100644 --- a/client.cpp +++ b/client.cpp @@ -990,12 +990,12 @@ void Client::updateVisibility() return; } if (isManaged()) - resetShowingDesktop(true); + resetShowingDesktop(); internalShow(); } -void Client::resetShowingDesktop(bool keep_hidden) +void Client::resetShowingDesktop() { if (isDock() || !workspace()->showingDesktop()) return; @@ -1006,7 +1006,7 @@ void Client::resetShowingDesktop(bool keep_hidden) break; if (!belongs_to_desktop) - workspace()->resetShowingDesktop(keep_hidden); + workspace()->setShowingDesktop(false); } /** diff --git a/client.h b/client.h index b574aa26ab..40d503cfa9 100644 --- a/client.h +++ b/client.h @@ -717,7 +717,7 @@ private: bool processDecorationButtonPress(int button, int state, int x, int y, int x_root, int y_root, bool ignoreMenu = false); Client* findAutogroupCandidate() const; - void resetShowingDesktop(bool keep_hidden); + void resetShowingDesktop(); protected: virtual void debug(QDebug& stream) const; diff --git a/layers.cpp b/layers.cpp index ae08207504..b6d5b75f8f 100644 --- a/layers.cpp +++ b/layers.cpp @@ -827,7 +827,7 @@ Layer Client::layer() const Layer Client::belongsToLayer() const { if (isDesktop()) - return DesktopLayer; + return workspace()->showingDesktop() ? AboveLayer : DesktopLayer; if (isSplash()) // no damn annoying splashscreens return NormalLayer; // getting in the way of everything else if (isDock()) { diff --git a/manage.cpp b/manage.cpp index 241d322b9d..75af4e519b 100644 --- a/manage.cpp +++ b/manage.cpp @@ -603,7 +603,7 @@ bool Client::manage(xcb_window_t w, bool isMapped) } } - resetShowingDesktop(false); + resetShowingDesktop(); if (isOnCurrentDesktop() && !isMapped && !allow && (!session || session->stackingOrder < 0)) workspace()->restackClientUnderActive(this); diff --git a/workspace.cpp b/workspace.cpp index f9c1ab189e..45cf15e626 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -113,7 +113,6 @@ Workspace::Workspace(bool restore) , force_restacking(false) , x_stacking_dirty(true) , showing_desktop(false) - , block_showing_desktop(0) , was_user_interaction(false) , session_saving(false) , block_focus(0) @@ -550,7 +549,6 @@ void Workspace::removeClient(Client* c) desktops.removeAll(c); x_stacking_dirty = true; attention_chain.removeAll(c); - showing_desktop_clients.removeAll(c); Group* group = findGroup(c->window()); if (group != NULL) group->lostLeader(); @@ -849,7 +847,6 @@ void Workspace::slotCurrentDesktopChanged(uint oldDesktop, uint newDesktop) void Workspace::updateClientVisibilityOnDesktopChange(uint oldDesktop, uint newDesktop) { - ++block_showing_desktop; ObscuringWindows obs_wins; for (ToplevelList::ConstIterator it = stacking_order.constBegin(); it != stacking_order.constEnd(); @@ -879,9 +876,8 @@ void Workspace::updateClientVisibilityOnDesktopChange(uint oldDesktop, uint newD if (c->isOnDesktop(newDesktop) && c->isOnCurrentActivity()) c->updateVisibility(); } - --block_showing_desktop; if (showingDesktop()) // Do this only after desktop change to avoid flicker - resetShowingDesktop(false); + setShowingDesktop(false); } void Workspace::activateClientOnNewDesktop(uint desktop) @@ -956,7 +952,6 @@ void Workspace::updateCurrentActivity(const QString &new_activity) // TODO: Q_ASSERT( block_stacking_updates == 0 ); // Make sure stacking_order is up to date StackingUpdatesBlocker blocker(this); - ++block_showing_desktop; //FIXME should I be using that? // Optimized Desktop switching: unmapping done from back to front // mapping done from front to back => less exposure events //Notify::raise((Notify::Event) (Notify::DesktopChange+new_desktop)); @@ -997,10 +992,9 @@ void Workspace::updateCurrentActivity(const QString &new_activity) c->updateVisibility(); } - --block_showing_desktop; //FIXME not sure if I should do this either if (showingDesktop()) // Do this only after desktop change to avoid flicker - resetShowingDesktop(false); + setShowingDesktop(false); // Restore the focus on this desktop --block_focus; @@ -1206,68 +1200,12 @@ void Workspace::setShowingDesktop(bool showing) { rootInfo()->setShowingDesktop(showing); showing_desktop = showing; - ++block_showing_desktop; - if (showing_desktop) { - showing_desktop_clients.clear(); - ++block_focus; - ToplevelList cls = stackingOrder(); - // Find them first, then minimize, otherwise transients may get minimized with the window - // they're transient for - for (ToplevelList::ConstIterator it = cls.constBegin(); - it != cls.constEnd(); - ++it) { - Client *c = qobject_cast(*it); - if (!c) { - continue; - } - if (c->isOnCurrentActivity() && c->isOnCurrentDesktop() && c->isShown(true) && !c->isSpecialWindow()) - showing_desktop_clients.prepend(c); // Topmost first to reduce flicker - } - for (ClientList::ConstIterator it = showing_desktop_clients.constBegin(); - it != showing_desktop_clients.constEnd(); - ++it) - (*it)->minimize(); - --block_focus; - if (Client* desk = findDesktop(true, VirtualDesktopManager::self()->current())) + if (Client* desk = findDesktop(true, VirtualDesktopManager::self()->current())) { + desk->updateLayer(); + lowerClient(desk); + if (showing_desktop) requestFocus(desk); - } else { - for (ClientList::ConstIterator it = showing_desktop_clients.constBegin(); - it != showing_desktop_clients.constEnd(); - ++it) - (*it)->unminimize(); - if (showing_desktop_clients.count() > 0) - requestFocus(showing_desktop_clients.first()); - showing_desktop_clients.clear(); } - --block_showing_desktop; -} - -/** - * Following Kicker's behavior: - * Changing a virtual desktop resets the state and shows the windows again. - * Unminimizing a window resets the state but keeps the windows hidden (except - * the one that was unminimized). - * A new window resets the state and shows the windows again, with the new window - * being active. Due to popular demand (#67406) by people who apparently - * don't see a difference between "show desktop" and "minimize all", this is not - * true if "showDesktopIsMinimizeAll" is set in kwinrc. In such case showing - * a new window resets the state but doesn't show windows. - */ -void Workspace::resetShowingDesktop(bool keep_hidden) -{ - if (block_showing_desktop > 0) - return; - rootInfo()->setShowingDesktop(false); - showing_desktop = false; - ++block_showing_desktop; - if (!keep_hidden) { - for (ClientList::ConstIterator it = showing_desktop_clients.constBegin(); - it != showing_desktop_clients.constEnd(); - ++it) - (*it)->unminimize(); - } - showing_desktop_clients.clear(); - --block_showing_desktop; } void Workspace::disableGlobalShortcutsForClient(bool disable) diff --git a/workspace.h b/workspace.h index 0b7389f0a6..999a1c24f2 100644 --- a/workspace.h +++ b/workspace.h @@ -277,7 +277,6 @@ public: void setCurrentScreen(int new_screen); void setShowingDesktop(bool showing); - void resetShowingDesktop(bool keep_hidden); bool showingDesktop() const; void sendPingToWindow(xcb_window_t w, xcb_timestamp_t timestamp); // Called from Client::pingWindow() @@ -535,8 +534,6 @@ private: ClientList attention_chain; bool showing_desktop; - ClientList showing_desktop_clients; - int block_showing_desktop; GroupList groups;