mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:32:43 +00:00 
			
		
		
		
	WindowServer: Introduce a WM event mask so Taskbar can ignore window rects.
Taskbar was waking up to do nothing every time a window rect changed.
This commit is contained in:
		
							parent
							
								
									ab94a6be00
								
							
						
					
					
						commit
						49e7ffc06a
					
				
					 10 changed files with 97 additions and 3 deletions
				
			
		|  | @ -76,6 +76,17 @@ void TaskbarWindow::wm_event(GWMEvent& event) | ||||||
|         update(); |         update(); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |     case GEvent::WM_WindowRectChanged: { | ||||||
|  | #ifdef EVENT_DEBUG | ||||||
|  |         auto& changed_event = static_cast<GWMWindowRectChangedEvent&>(event); | ||||||
|  |         dbgprintf("WM_WindowRectChanged: client_id=%d, window_id=%d, rect=%s\n", | ||||||
|  |             changed_event.client_id(), | ||||||
|  |             changed_event.window_id(), | ||||||
|  |             changed_event.rect().to_string().characters() | ||||||
|  |         ); | ||||||
|  | #endif | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|     case GEvent::WM_WindowIconChanged: { |     case GEvent::WM_WindowIconChanged: { | ||||||
|         auto& changed_event = static_cast<GWMWindowIconChangedEvent&>(event); |         auto& changed_event = static_cast<GWMWindowIconChangedEvent&>(event); | ||||||
| #ifdef EVENT_DEBUG | #ifdef EVENT_DEBUG | ||||||
|  |  | ||||||
|  | @ -30,9 +30,13 @@ public: | ||||||
|         FocusOut, |         FocusOut, | ||||||
|         WindowCloseRequest, |         WindowCloseRequest, | ||||||
|         ContextMenu, |         ContextMenu, | ||||||
|  | 
 | ||||||
|  |         __Begin_WM_Events, | ||||||
|         WM_WindowRemoved, |         WM_WindowRemoved, | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|  |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
|  |         __End_WM_Events, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     GEvent() { } |     GEvent() { } | ||||||
|  | @ -95,6 +99,20 @@ private: | ||||||
|     bool m_minimized; |     bool m_minimized; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | class GWMWindowRectChangedEvent : public GWMEvent { | ||||||
|  | public: | ||||||
|  |     GWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) | ||||||
|  |         : GWMEvent(GEvent::Type::WM_WindowRectChanged, client_id, window_id) | ||||||
|  |         , m_rect(rect) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Rect rect() const { return m_rect; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     Rect m_rect; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class GWMWindowIconChangedEvent : public GWMEvent { | class GWMWindowIconChangedEvent : public GWMEvent { | ||||||
| public: | public: | ||||||
|     GWMWindowIconChangedEvent(int client_id, int window_id, const String& icon_path) |     GWMWindowIconChangedEvent(int client_id, int window_id, const String& icon_path) | ||||||
|  |  | ||||||
|  | @ -175,6 +175,8 @@ void GEventLoop::handle_wm_event(const WSAPI_ServerMessage& event, GWindow& wind | ||||||
| #endif | #endif | ||||||
|     if (event.type == WSAPI_ServerMessage::WM_WindowStateChanged) |     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, event.wm.is_active, (GWindowType)event.wm.window_type, event.wm.is_minimized)); |         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, (GWindowType)event.wm.window_type, event.wm.is_minimized)); | ||||||
|  |     if (event.type == WSAPI_ServerMessage::WM_WindowRectChanged) | ||||||
|  |         return post_event(window, make<GWMWindowRectChangedEvent>(event.wm.client_id, event.wm.window_id, event.wm.rect)); | ||||||
|     if (event.type == WSAPI_ServerMessage::WM_WindowIconChanged) |     if (event.type == WSAPI_ServerMessage::WM_WindowIconChanged) | ||||||
|         return post_event(window, make<GWMWindowIconChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length))); |         return post_event(window, make<GWMWindowIconChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length))); | ||||||
|     if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) |     if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) | ||||||
|  |  | ||||||
|  | @ -277,7 +277,7 @@ void GWindow::event(CEvent& event) | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (event.type() == GEvent::WM_WindowRemoved || event.type() == GEvent::WM_WindowStateChanged || event.type() == GEvent::WM_WindowIconChanged) |     if (event.type() > GEvent::__Begin_WM_Events && event.type() < GEvent::__End_WM_Events) | ||||||
|         return wm_event(static_cast<GWMEvent&>(event)); |         return wm_event(static_cast<GWMEvent&>(event)); | ||||||
| 
 | 
 | ||||||
|     CObject::event(event); |     CObject::event(event); | ||||||
|  |  | ||||||
|  | @ -57,6 +57,13 @@ enum class WSAPI_StandardCursor : unsigned char { | ||||||
|     ResizeVertical, |     ResizeVertical, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | enum WSAPI_WMEventMask : unsigned { | ||||||
|  |     WindowRectChanges = 1 << 0, | ||||||
|  |     WindowStateChanges = 1 << 1, | ||||||
|  |     WindowIconChanges = 1 << 2, | ||||||
|  |     WindowRemovals = 1 << 3, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct WSAPI_ServerMessage { | struct WSAPI_ServerMessage { | ||||||
|     enum Type : unsigned { |     enum Type : unsigned { | ||||||
|         Invalid, |         Invalid, | ||||||
|  | @ -97,6 +104,7 @@ struct WSAPI_ServerMessage { | ||||||
|         ScreenRectChanged, |         ScreenRectChanged, | ||||||
|         WM_WindowRemoved, |         WM_WindowRemoved, | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|  |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
|     }; |     }; | ||||||
|     Type type { Invalid }; |     Type type { Invalid }; | ||||||
|  |  | ||||||
|  | @ -29,6 +29,7 @@ public: | ||||||
| 
 | 
 | ||||||
|         WM_WindowRemoved, |         WM_WindowRemoved, | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|  |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
| 
 | 
 | ||||||
|         __Begin_API_Client_Requests, |         __Begin_API_Client_Requests, | ||||||
|  | @ -750,3 +751,17 @@ public: | ||||||
| private: | private: | ||||||
|     String m_icon_path; |     String m_icon_path; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | class WSWMWindowRectChangedEvent : public WSWMEvent { | ||||||
|  | public: | ||||||
|  |     WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) | ||||||
|  |         : WSWMEvent(WSEvent::WM_WindowRectChanged, client_id, window_id) | ||||||
|  |         , m_rect(rect) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Rect rect() const { return m_rect; } | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     Rect m_rect; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | @ -38,8 +38,10 @@ WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int win | ||||||
|     , m_frame(*this) |     , m_frame(*this) | ||||||
| { | { | ||||||
|     // FIXME: This should not be hard-coded here.
 |     // FIXME: This should not be hard-coded here.
 | ||||||
|     if (m_type == WSWindowType::Taskbar) |     if (m_type == WSWindowType::Taskbar) { | ||||||
|  |         m_wm_event_mask = WSAPI_WMEventMask::WindowStateChanges | WSAPI_WMEventMask::WindowRemovals | WSAPI_WMEventMask::WindowIconChanges; | ||||||
|         m_listens_to_wm_events = true; |         m_listens_to_wm_events = true; | ||||||
|  |     } | ||||||
|     WSWindowManager::the().add_window(*this); |     WSWindowManager::the().add_window(*this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -210,6 +212,15 @@ void WSWindow::event(CEvent& event) | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     case WSEvent::WM_WindowRectChanged: { | ||||||
|  |         auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event); | ||||||
|  |         server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; | ||||||
|  |         server_message.wm.client_id = changed_event.client_id(); | ||||||
|  |         server_message.wm.window_id = changed_event.window_id(); | ||||||
|  |         server_message.wm.rect = changed_event.rect(); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     default: |     default: | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -19,6 +19,9 @@ public: | ||||||
|     WSWindow(CObject&, WSWindowType); |     WSWindow(CObject&, WSWindowType); | ||||||
|     virtual ~WSWindow() override; |     virtual ~WSWindow() override; | ||||||
| 
 | 
 | ||||||
|  |     unsigned wm_event_mask() const { return m_wm_event_mask; } | ||||||
|  |     void set_wm_event_mask(unsigned mask) { m_wm_event_mask = mask; } | ||||||
|  | 
 | ||||||
|     Color background_color() const { return m_background_color; } |     Color background_color() const { return m_background_color; } | ||||||
|     void set_background_color(Color color) { m_background_color = color; } |     void set_background_color(Color color) { m_background_color = color; } | ||||||
| 
 | 
 | ||||||
|  | @ -156,4 +159,5 @@ private: | ||||||
|     RetainPtr<WSCursor> m_override_cursor; |     RetainPtr<WSCursor> m_override_cursor; | ||||||
|     WSWindowFrame m_frame; |     WSWindowFrame m_frame; | ||||||
|     Color m_background_color { Color::LightGray }; |     Color m_background_color { Color::LightGray }; | ||||||
|  |     unsigned m_wm_event_mask { 0 }; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| #include <WindowServer/WSCursor.h> | #include <WindowServer/WSCursor.h> | ||||||
| #include <WindowServer/WSButton.h> | #include <WindowServer/WSButton.h> | ||||||
| #include <LibCore/CTimer.h> | #include <LibCore/CTimer.h> | ||||||
|  | #include <WindowServer/WSAPITypes.h> | ||||||
| 
 | 
 | ||||||
| //#define DEBUG_COUNTERS
 | //#define DEBUG_COUNTERS
 | ||||||
| //#define RESIZE_DEBUG
 | //#define RESIZE_DEBUG
 | ||||||
|  | @ -311,6 +312,8 @@ void WSWindowManager::remove_window(WSWindow& window) | ||||||
|         m_switcher.refresh(); |         m_switcher.refresh(); | ||||||
| 
 | 
 | ||||||
|     for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { |     for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { | ||||||
|  |         if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowRemovals)) | ||||||
|  |             return IterationDecision::Continue; | ||||||
|         if (window.client()) |         if (window.client()) | ||||||
|             WSEventLoop::the().post_event(listener, make<WSWMWindowRemovedEvent>(window.client()->client_id(), window.window_id())); |             WSEventLoop::the().post_event(listener, make<WSWMWindowRemovedEvent>(window.client()->client_id(), window.window_id())); | ||||||
|         return IterationDecision::Continue; |         return IterationDecision::Continue; | ||||||
|  | @ -319,12 +322,24 @@ void WSWindowManager::remove_window(WSWindow& window) | ||||||
| 
 | 
 | ||||||
| void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow& window) | void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow& window) | ||||||
| { | { | ||||||
|  |     if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowStateChanges)) | ||||||
|  |         return; | ||||||
|     if (window.client()) |     if (window.client()) | ||||||
|         WSEventLoop::the().post_event(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active(), window.type(), window.is_minimized())); |         WSEventLoop::the().post_event(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active(), window.type(), window.is_minimized())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void WSWindowManager::tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow& window) | ||||||
|  | { | ||||||
|  |     if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowRectChanges)) | ||||||
|  |         return; | ||||||
|  |     if (window.client()) | ||||||
|  |         WSEventLoop::the().post_event(listener, make<WSWMWindowRectChangedEvent>(window.client()->client_id(), window.window_id(), window.rect())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow& window) | void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow& window) | ||||||
| { | { | ||||||
|  |     if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) | ||||||
|  |         return; | ||||||
|     if (window.client()) |     if (window.client()) | ||||||
|         WSEventLoop::the().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); |         WSEventLoop::the().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); | ||||||
| } | } | ||||||
|  | @ -345,6 +360,14 @@ void WSWindowManager::tell_wm_listeners_window_icon_changed(WSWindow& window) | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void WSWindowManager::tell_wm_listeners_window_rect_changed(WSWindow& window) | ||||||
|  | { | ||||||
|  |     for_each_window_listening_to_wm_events([&] (WSWindow& listener) { | ||||||
|  |         tell_wm_listener_about_window_rect(listener, window); | ||||||
|  |         return IterationDecision::Continue; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void WSWindowManager::notify_title_changed(WSWindow& window) | void WSWindowManager::notify_title_changed(WSWindow& window) | ||||||
| { | { | ||||||
|     dbgprintf("[WM] WSWindow{%p} title set to '%s'\n", &window, window.title().characters()); |     dbgprintf("[WM] WSWindow{%p} title set to '%s'\n", &window, window.title().characters()); | ||||||
|  | @ -364,7 +387,7 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect | ||||||
| #endif | #endif | ||||||
|     if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) |     if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) | ||||||
|         m_switcher.refresh(); |         m_switcher.refresh(); | ||||||
|     tell_wm_listeners_window_state_changed(window); |     tell_wm_listeners_window_rect_changed(window); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WSWindowManager::notify_minimization_state_changed(WSWindow& window) | void WSWindowManager::notify_minimization_state_changed(WSWindow& window) | ||||||
|  |  | ||||||
|  | @ -112,6 +112,7 @@ public: | ||||||
| 
 | 
 | ||||||
|     void tell_wm_listeners_window_state_changed(WSWindow&); |     void tell_wm_listeners_window_state_changed(WSWindow&); | ||||||
|     void tell_wm_listeners_window_icon_changed(WSWindow&); |     void tell_wm_listeners_window_icon_changed(WSWindow&); | ||||||
|  |     void tell_wm_listeners_window_rect_changed(WSWindow&); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window); |     void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window); | ||||||
|  | @ -139,6 +140,7 @@ private: | ||||||
|     void tick_clock(); |     void tick_clock(); | ||||||
|     void tell_wm_listener_about_window(WSWindow& listener, WSWindow&); |     void tell_wm_listener_about_window(WSWindow& listener, WSWindow&); | ||||||
|     void tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow&); |     void tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow&); | ||||||
|  |     void tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow&); | ||||||
|     void pick_new_active_window(); |     void pick_new_active_window(); | ||||||
| 
 | 
 | ||||||
|     WSScreen& m_screen; |     WSScreen& m_screen; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling