diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index 91d81357e6..b1be5561cd 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -1001,7 +1001,19 @@ void Compositor::recompute_occlusions() auto& wm = WindowManager::the(); bool is_switcher_visible = wm.m_switcher.is_visible(); wm.for_each_window_stack([&](WindowStack& window_stack) { - window_stack.set_all_occluded(!is_switcher_visible); + if (is_switcher_visible) { + switch (wm.m_switcher.mode()) { + case WindowSwitcher::Mode::ShowCurrentDesktop: + window_stack.set_all_occluded(!(&window_stack == m_current_window_stack || &window_stack == m_transitioning_to_window_stack)); + break; + case WindowSwitcher::Mode::ShowAllWindows: + window_stack.set_all_occluded(false); + break; + } + } else { + window_stack.set_all_occluded(!(&window_stack == m_current_window_stack || &window_stack == m_transitioning_to_window_stack)); + } + return IterationDecision::Continue; }); if (!is_switcher_visible) { diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 0dd823016c..edc0edde21 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -1567,8 +1567,12 @@ void WindowManager::process_key_event(KeyEvent& event) return; } - if (event.type() == Event::KeyDown && ((event.modifiers() == Mod_Super && event.key() == Key_Tab) || (event.modifiers() == (Mod_Super | Mod_Shift) && event.key() == Key_Tab))) - m_switcher.show(); + if (event.type() == Event::KeyDown) { + if ((event.modifiers() == Mod_Super && event.key() == Key_Tab) || (event.modifiers() == (Mod_Super | Mod_Shift) && event.key() == Key_Tab)) + m_switcher.show(WindowSwitcher::Mode::ShowAllWindows); + else if ((event.modifiers() == Mod_Alt && event.key() == Key_Tab) || (event.modifiers() == (Mod_Alt | Mod_Shift) && event.key() == Key_Tab)) + m_switcher.show(WindowSwitcher::Mode::ShowCurrentDesktop); + } if (m_switcher.is_visible()) { m_switcher.on_key_event(event); return; diff --git a/Userland/Services/WindowServer/WindowSwitcher.cpp b/Userland/Services/WindowServer/WindowSwitcher.cpp index 2ba8aafcbd..f7054c1c17 100644 --- a/Userland/Services/WindowServer/WindowSwitcher.cpp +++ b/Userland/Services/WindowServer/WindowSwitcher.cpp @@ -86,7 +86,7 @@ void WindowSwitcher::event(Core::Event& event) void WindowSwitcher::on_key_event(const KeyEvent& event) { if (event.type() == Event::KeyUp) { - if (event.key() == Key_Super) { + if (event.key() == (m_mode == Mode::ShowAllWindows ? Key_Super : Key_Alt)) { if (auto* window = selected_window()) { window->set_minimized(false); WindowManager::the().move_to_front_and_make_active(*window); @@ -135,7 +135,12 @@ void WindowSwitcher::select_window_at_index(int index) m_selected_index = index; auto* highlight_window = m_windows.at(index).ptr(); VERIFY(highlight_window); - WindowManager::the().set_highlight_window(highlight_window); + auto& wm = WindowManager::the(); + if (m_mode == Mode::ShowAllWindows) { + if (auto* window_stack = highlight_window->outer_stack(); window_stack != &wm.current_window_stack()) + wm.switch_to_window_stack(*window_stack, nullptr, false); + } + wm.set_highlight_window(highlight_window); redraw(); } @@ -202,7 +207,8 @@ void WindowSwitcher::refresh() m_selected_index = 0; int window_count = 0; int longest_title_width = 0; - wm.for_each_window_stack([&](auto& window_stack) { + + auto add_window_stack_windows = [&](WindowStack& window_stack) { window_stack.for_each_window_of_type_from_front_to_back( WindowType::Normal, [&](Window& window) { if (window.is_frameless()) @@ -215,8 +221,16 @@ void WindowSwitcher::refresh() return IterationDecision::Continue; }, true); - return IterationDecision::Continue; - }); + }; + if (m_mode == Mode::ShowAllWindows) { + wm.for_each_window_stack([&](auto& window_stack) { + add_window_stack_windows(window_stack); + return IterationDecision::Continue; + }); + } else { + add_window_stack_windows(wm.current_window_stack()); + } + if (m_windows.is_empty()) { hide(); return; diff --git a/Userland/Services/WindowServer/WindowSwitcher.h b/Userland/Services/WindowServer/WindowSwitcher.h index 6657678084..c0997eecfd 100644 --- a/Userland/Services/WindowServer/WindowSwitcher.h +++ b/Userland/Services/WindowServer/WindowSwitcher.h @@ -20,6 +20,10 @@ class Window; class WindowSwitcher final : public Core::Object { C_OBJECT(WindowSwitcher) public: + enum class Mode { + ShowAllWindows, + ShowCurrentDesktop + }; static WindowSwitcher& the(); WindowSwitcher(); @@ -28,7 +32,11 @@ public: bool is_visible() const { return m_visible; } void set_visible(bool); - void show() { set_visible(true); } + void show(Mode mode) + { + m_mode = mode; + set_visible(true); + } void hide() { set_visible(false); } void on_key_event(const KeyEvent&); @@ -38,6 +46,8 @@ public: void select_window(Window&); + Mode mode() const { return m_mode; } + private: int thumbnail_width() const { return 40; } int thumbnail_height() const { return 40; } @@ -54,6 +64,7 @@ private: virtual void event(Core::Event&) override; RefPtr m_switcher_window; + Mode m_mode { Mode::ShowCurrentDesktop }; Gfx::IntRect m_rect; bool m_visible { false }; Vector> m_windows;