Pārlūkot izejas kodu

Taskbar: Plumb window active state from the WindowServer to the taskbar.

Andreas Kling 6 gadi atpakaļ
vecāks
revīzija
7b1384c4ef

+ 23 - 7
Applications/Taskbar/TaskbarWindow.cpp

@@ -19,6 +19,10 @@ TaskbarWindow::TaskbarWindow()
 
     auto* widget = new TaskbarWidget(m_window_list);
     set_main_widget(widget);
+
+    m_window_list.aid_create_button = [this] {
+        return create_button();
+    };
 }
 
 TaskbarWindow::~TaskbarWindow()
@@ -31,25 +35,34 @@ void TaskbarWindow::on_screen_rect_change(const Rect& rect)
     set_rect(new_rect);
 }
 
+GButton* TaskbarWindow::create_button()
+{
+    auto* button = new GButton(main_widget());
+    button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
+    button->set_preferred_size({ 100, 22 });
+    button->set_checkable(true);
+    return button;
+}
+
 void TaskbarWindow::wm_event(GWMEvent& event)
 {
     WindowIdentifier identifier { event.client_id(), event.window_id() };
     switch (event.type()) {
     case GEvent::WM_WindowAdded: {
         auto& added_event = static_cast<GWMWindowAddedEvent&>(event);
-        printf("WM_WindowAdded: client_id=%d, window_id=%d, title=%s, rect=%s\n",
+        printf("WM_WindowAdded: client_id=%d, window_id=%d, title=%s, rect=%s, is_active=%u\n",
             added_event.client_id(),
             added_event.window_id(),
             added_event.title().characters(),
-            added_event.rect().to_string().characters()
+            added_event.rect().to_string().characters(),
+            added_event.is_active()
         );
         auto& window = m_window_list.ensure_window(identifier);
         window.set_title(added_event.title());
         window.set_rect(added_event.rect());
-        window.set_button(new GButton(main_widget()));
-        window.button()->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
-        window.button()->set_preferred_size({ 100, 22 });
+        window.set_active(added_event.is_active());
         window.button()->set_caption(window.title());
+        window.button()->set_checked(window.is_active());
         update();
         break;
     }
@@ -65,16 +78,19 @@ void TaskbarWindow::wm_event(GWMEvent& event)
     }
     case GEvent::WM_WindowStateChanged: {
         auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event);
-        printf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s\n",
+        printf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s, is_active=%u\n",
             changed_event.client_id(),
             changed_event.window_id(),
             changed_event.title().characters(),
-            changed_event.rect().to_string().characters()
+            changed_event.rect().to_string().characters(),
+            changed_event.is_active()
         );
         auto& window = m_window_list.ensure_window(identifier);
         window.set_title(changed_event.title());
         window.set_rect(changed_event.rect());
+        window.set_active(changed_event.is_active());
         window.button()->set_caption(changed_event.title());
+        window.button()->set_checked(changed_event.is_active());
         break;
     }
     default:

+ 1 - 0
Applications/Taskbar/TaskbarWindow.h

@@ -13,6 +13,7 @@ public:
 
 private:
     void on_screen_rect_change(const Rect&);
+    GButton* create_button();
 
     virtual void wm_event(GWMEvent&) override;
 

+ 1 - 0
Applications/Taskbar/WindowList.cpp

@@ -6,6 +6,7 @@ Window& WindowList::ensure_window(const WindowIdentifier& identifier)
     if (it != m_windows.end())
         return *it->value;
     auto window = make<Window>(identifier);
+    window->set_button(aid_create_button());
     auto& window_ref = *window;
     m_windows.set(identifier, move(window));
     return window_ref;

+ 6 - 0
Applications/Taskbar/WindowList.h

@@ -57,11 +57,15 @@ public:
     GButton* button() { return m_button; }
     void set_button(GButton* button) { m_button = button; }
 
+    void set_active(bool active) { m_active = active; }
+    bool is_active() const { return m_active; }
+
 private:
     WindowIdentifier m_identifier;
     String m_title;
     Rect m_rect;
     GButton* m_button { nullptr };
+    bool m_active { false };
 };
 
 class WindowList {
@@ -75,6 +79,8 @@ public:
     Window& ensure_window(const WindowIdentifier&);
     void remove_window(const WindowIdentifier&);
 
+    Function<GButton*()> aid_create_button;
+
 private:
     HashMap<WindowIdentifier, OwnPtr<Window>> m_windows;
 };

+ 8 - 2
LibGUI/GEvent.h

@@ -74,19 +74,22 @@ private:
 
 class GWMWindowAddedEvent : public GWMEvent {
 public:
-    GWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect)
+    GWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active)
         : GWMEvent(GEvent::Type::WM_WindowAdded, client_id, window_id)
         , m_title(title)
         , m_rect(rect)
+        , m_active(is_active)
     {
     }
 
     String title() const { return m_title; }
     Rect rect() const { return m_rect; }
+    bool is_active() const { return m_active; }
 
 private:
     String m_title;
     Rect m_rect;
+    bool m_active;
 };
 
 class GWMWindowRemovedEvent : public GWMEvent {
@@ -99,19 +102,22 @@ public:
 
 class GWMWindowStateChangedEvent : public GWMEvent {
 public:
-    GWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect)
+    GWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active)
         : GWMEvent(GEvent::Type::WM_WindowStateChanged, client_id, window_id)
         , m_title(title)
         , m_rect(rect)
+        , m_active(is_active)
     {
     }
 
     String title() const { return m_title; }
     Rect rect() const { return m_rect; }
+    bool is_active() const { return m_active; }
 
 private:
     String m_title;
     Rect m_rect;
+    bool m_active;
 };
 
 class QuitEvent final : public GEvent {

+ 2 - 2
LibGUI/GEventLoop.cpp

@@ -271,9 +271,9 @@ void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event)
 void GEventLoop::handle_wm_event(const WSAPI_ServerMessage& event, GWindow& window)
 {
     if (event.type == WSAPI_ServerMessage::WM_WindowAdded)
-        return post_event(window, make<GWMWindowAddedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect));
+        return post_event(window, make<GWMWindowAddedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect, event.wm.is_active));
     if (event.type == WSAPI_ServerMessage::WM_WindowStateChanged)
-        return post_event(window, make<GWMWindowStateChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect));
+        return post_event(window, make<GWMWindowStateChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect, event.wm.is_active));
     if (event.type == WSAPI_ServerMessage::WM_WindowRemoved)
         return post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id));
     ASSERT_NOT_REACHED();

+ 1 - 0
Servers/WindowServer/WSAPITypes.h

@@ -110,6 +110,7 @@ struct WSAPI_ServerMessage {
             int client_id;
             int window_id;
             WSAPI_Rect rect;
+            bool is_active;
         } wm;
         struct {
             WSAPI_Rect rect;

+ 8 - 2
Servers/WindowServer/WSMessage.h

@@ -605,19 +605,22 @@ private:
 
 class WSWMWindowAddedEvent : public WSWMEvent {
 public:
-    WSWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect)
+    WSWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active)
         : WSWMEvent(WSMessage::WM_WindowAdded, client_id, window_id)
         , m_title(title)
         , m_rect(rect)
+        , m_active(is_active)
     {
     }
 
     String title() const { return m_title; }
     Rect rect() const { return m_rect; }
+    bool is_active() const { return m_active; }
 
 private:
     String m_title;
     Rect m_rect;
+    bool m_active;
 };
 
 class WSWMWindowRemovedEvent : public WSWMEvent {
@@ -630,17 +633,20 @@ public:
 
 class WSWMWindowStateChangedEvent : public WSWMEvent {
 public:
-    WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect)
+    WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active)
         : WSWMEvent(WSMessage::WM_WindowStateChanged, client_id, window_id)
         , m_title(title)
         , m_rect(rect)
+        , m_active(is_active)
     {
     }
 
     String title() const { return m_title; }
     Rect rect() const { return m_rect; }
+    bool is_active() const { return m_active; }
 
 private:
     String m_title;
     Rect m_rect;
+    bool m_active;
 };

+ 2 - 0
Servers/WindowServer/WSWindow.cpp

@@ -146,6 +146,7 @@ void WSWindow::on_message(const WSMessage& message)
         server_message.type = WSAPI_ServerMessage::Type::WM_WindowAdded;
         server_message.wm.client_id = added_event.client_id();
         server_message.wm.window_id = added_event.window_id();
+        server_message.wm.is_active = added_event.is_active();
         ASSERT(added_event.title().length() < sizeof(server_message.text));
         memcpy(server_message.text, added_event.title().characters(), added_event.title().length());
         server_message.text_length = added_event.title().length();
@@ -164,6 +165,7 @@ void WSWindow::on_message(const WSMessage& message)
         server_message.type = WSAPI_ServerMessage::Type::WM_WindowStateChanged;
         server_message.wm.client_id = changed_event.client_id();
         server_message.wm.window_id = changed_event.window_id();
+        server_message.wm.is_active = changed_event.is_active();
         ASSERT(changed_event.title().length() < sizeof(server_message.text));
         memcpy(server_message.text, changed_event.title().characters(), changed_event.title().length());
         server_message.text_length = changed_event.title().length();

+ 17 - 16
Servers/WindowServer/WSWindowManager.cpp

@@ -18,10 +18,6 @@
 #include <SharedGraphics/PNGLoader.h>
 #include "WSCursor.h"
 
-#ifdef KERNEL
-#include <Kernel/ProcFS.h>
-#endif
-
 //#define DEBUG_COUNTERS
 //#define DEBUG_WID_IN_TITLE_BAR
 //#define RESIZE_DEBUG
@@ -510,7 +506,7 @@ void WSWindowManager::add_window(WSWindow& window)
 
     for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
         if (window.client())
-            WSMessageLoop::the().post_message(listener, make<WSWMWindowAddedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
+            WSMessageLoop::the().post_message(listener, make<WSWMWindowAddedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active()));
         return IterationDecision::Continue;
     });
 }
@@ -548,6 +544,15 @@ void WSWindowManager::remove_window(WSWindow& window)
     });
 }
 
+void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window)
+{
+    for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
+        if (window.client())
+            WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active()));
+        return IterationDecision::Continue;
+    });
+}
+
 void WSWindowManager::notify_title_changed(WSWindow& window)
 {
     dbgprintf("[WM] WSWindow{%p} title set to '%s'\n", &window, window.title().characters());
@@ -555,11 +560,7 @@ void WSWindowManager::notify_title_changed(WSWindow& window)
     if (m_switcher.is_visible())
         m_switcher.refresh();
 
-    for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
-        if (window.client())
-            WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
-        return IterationDecision::Continue;
-    });
+    tell_wm_listeners_window_state_changed(window);
 }
 
 void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect, const Rect& new_rect)
@@ -572,11 +573,7 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect
     if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
         m_switcher.refresh();
 
-    for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
-        if (window.client())
-            WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
-        return IterationDecision::Continue;
-    });
+    tell_wm_listeners_window_state_changed(window);
 }
 
 void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
@@ -1139,7 +1136,8 @@ void WSWindowManager::set_active_window(WSWindow* window)
     if (window == m_active_window.ptr())
         return;
 
-    if (auto* previously_active_window = m_active_window.ptr()) {
+    auto* previously_active_window = m_active_window.ptr();
+    if (previously_active_window) {
         WSMessageLoop::the().post_message(*previously_active_window, make<WSMessage>(WSMessage::WindowDeactivated));
         invalidate(*previously_active_window);
     }
@@ -1151,6 +1149,9 @@ void WSWindowManager::set_active_window(WSWindow* window)
         auto* client = window->client();
         ASSERT(client);
         set_current_menubar(client->app_menubar());
+        if (previously_active_window)
+            tell_wm_listeners_window_state_changed(*previously_active_window);
+        tell_wm_listeners_window_state_changed(*m_active_window);
     }
 }
 

+ 1 - 0
Servers/WindowServer/WSWindowManager.h

@@ -120,6 +120,7 @@ private:
     void paint_window_frame(const WSWindow&);
     void flip_buffers();
     void tick_clock();
+    void tell_wm_listeners_window_state_changed(WSWindow&);
 
     WSScreen& m_screen;
     Rect m_screen_rect;