mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 04:12: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(); | ||||
|         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: { | ||||
|         auto& changed_event = static_cast<GWMWindowIconChangedEvent&>(event); | ||||
| #ifdef EVENT_DEBUG | ||||
|  |  | |||
|  | @ -30,9 +30,13 @@ public: | |||
|         FocusOut, | ||||
|         WindowCloseRequest, | ||||
|         ContextMenu, | ||||
| 
 | ||||
|         __Begin_WM_Events, | ||||
|         WM_WindowRemoved, | ||||
|         WM_WindowStateChanged, | ||||
|         WM_WindowRectChanged, | ||||
|         WM_WindowIconChanged, | ||||
|         __End_WM_Events, | ||||
|     }; | ||||
| 
 | ||||
|     GEvent() { } | ||||
|  | @ -95,6 +99,20 @@ private: | |||
|     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 { | ||||
| public: | ||||
|     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 | ||||
|     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)); | ||||
|     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) | ||||
|         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) | ||||
|  |  | |||
|  | @ -277,7 +277,7 @@ void GWindow::event(CEvent& event) | |||
|         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)); | ||||
| 
 | ||||
|     CObject::event(event); | ||||
|  |  | |||
|  | @ -57,6 +57,13 @@ enum class WSAPI_StandardCursor : unsigned char { | |||
|     ResizeVertical, | ||||
| }; | ||||
| 
 | ||||
| enum WSAPI_WMEventMask : unsigned { | ||||
|     WindowRectChanges = 1 << 0, | ||||
|     WindowStateChanges = 1 << 1, | ||||
|     WindowIconChanges = 1 << 2, | ||||
|     WindowRemovals = 1 << 3, | ||||
| }; | ||||
| 
 | ||||
| struct WSAPI_ServerMessage { | ||||
|     enum Type : unsigned { | ||||
|         Invalid, | ||||
|  | @ -97,6 +104,7 @@ struct WSAPI_ServerMessage { | |||
|         ScreenRectChanged, | ||||
|         WM_WindowRemoved, | ||||
|         WM_WindowStateChanged, | ||||
|         WM_WindowRectChanged, | ||||
|         WM_WindowIconChanged, | ||||
|     }; | ||||
|     Type type { Invalid }; | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ public: | |||
| 
 | ||||
|         WM_WindowRemoved, | ||||
|         WM_WindowStateChanged, | ||||
|         WM_WindowRectChanged, | ||||
|         WM_WindowIconChanged, | ||||
| 
 | ||||
|         __Begin_API_Client_Requests, | ||||
|  | @ -750,3 +751,17 @@ public: | |||
| private: | ||||
|     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) | ||||
| { | ||||
|     // 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; | ||||
|     } | ||||
|     WSWindowManager::the().add_window(*this); | ||||
| } | ||||
| 
 | ||||
|  | @ -210,6 +212,15 @@ void WSWindow::event(CEvent& event) | |||
|         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: | ||||
|         break; | ||||
|     } | ||||
|  |  | |||
|  | @ -19,6 +19,9 @@ public: | |||
|     WSWindow(CObject&, WSWindowType); | ||||
|     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; } | ||||
|     void set_background_color(Color color) { m_background_color = color; } | ||||
| 
 | ||||
|  | @ -156,4 +159,5 @@ private: | |||
|     RetainPtr<WSCursor> m_override_cursor; | ||||
|     WSWindowFrame m_frame; | ||||
|     Color m_background_color { Color::LightGray }; | ||||
|     unsigned m_wm_event_mask { 0 }; | ||||
| }; | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include <WindowServer/WSCursor.h> | ||||
| #include <WindowServer/WSButton.h> | ||||
| #include <LibCore/CTimer.h> | ||||
| #include <WindowServer/WSAPITypes.h> | ||||
| 
 | ||||
| //#define DEBUG_COUNTERS
 | ||||
| //#define RESIZE_DEBUG
 | ||||
|  | @ -311,6 +312,8 @@ void WSWindowManager::remove_window(WSWindow& window) | |||
|         m_switcher.refresh(); | ||||
| 
 | ||||
|     for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { | ||||
|         if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowRemovals)) | ||||
|             return IterationDecision::Continue; | ||||
|         if (window.client()) | ||||
|             WSEventLoop::the().post_event(listener, make<WSWMWindowRemovedEvent>(window.client()->client_id(), window.window_id())); | ||||
|         return IterationDecision::Continue; | ||||
|  | @ -319,12 +322,24 @@ void WSWindowManager::remove_window(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()) | ||||
|         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) | ||||
| { | ||||
|     if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) | ||||
|         return; | ||||
|     if (window.client()) | ||||
|         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) | ||||
| { | ||||
|     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 | ||||
|     if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) | ||||
|         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) | ||||
|  |  | |||
|  | @ -112,6 +112,7 @@ public: | |||
| 
 | ||||
|     void tell_wm_listeners_window_state_changed(WSWindow&); | ||||
|     void tell_wm_listeners_window_icon_changed(WSWindow&); | ||||
|     void tell_wm_listeners_window_rect_changed(WSWindow&); | ||||
| 
 | ||||
| private: | ||||
|     void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window); | ||||
|  | @ -139,6 +140,7 @@ private: | |||
|     void tick_clock(); | ||||
|     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_rect(WSWindow& listener, WSWindow&); | ||||
|     void pick_new_active_window(); | ||||
| 
 | ||||
|     WSScreen& m_screen; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling