mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 18:32:45 +00:00 
			
		
		
		
	WindowServer: Flash modal window when clicking on window blocked by it
This makes window modality a bit more discoverable by indicating to the user that the modal window must be closed before mouse interaction is possible in the clicked window.
This commit is contained in:
		
							parent
							
								
									2e8db6560f
								
							
						
					
					
						commit
						af7800d947
					
				
					 3 changed files with 31 additions and 0 deletions
				
			
		|  | @ -160,6 +160,10 @@ Gfx::IntRect WindowFrame::title_bar_text_rect() const | |||
| Gfx::WindowTheme::WindowState WindowFrame::window_state_for_theme() const | ||||
| { | ||||
|     auto& wm = WindowManager::the(); | ||||
| 
 | ||||
|     if (m_flash_timer && m_flash_timer->is_active()) | ||||
|         return m_flash_counter & 1 ? Gfx::WindowTheme::WindowState::Active : Gfx::WindowTheme::WindowState::Inactive; | ||||
| 
 | ||||
|     if (&m_window == wm.m_highlight_window) | ||||
|         return Gfx::WindowTheme::WindowState::Highlighted; | ||||
|     if (&m_window == wm.m_move_window) | ||||
|  | @ -360,4 +364,19 @@ void WindowFrame::on_mouse_event(const MouseEvent& event) | |||
|     if (m_window.is_resizable() && event.type() == Event::MouseDown && event.button() == MouseButton::Left) | ||||
|         wm.start_window_resize(m_window, event.translated(rect().location())); | ||||
| } | ||||
| 
 | ||||
| void WindowFrame::start_flash_animation() | ||||
| { | ||||
|     if (!m_flash_timer) { | ||||
|         m_flash_timer = Core::Timer::construct(100, [this] { | ||||
|             ASSERT(m_flash_counter); | ||||
|             invalidate_title_bar(); | ||||
|             if (!--m_flash_counter) | ||||
|                 m_flash_timer->stop(); | ||||
|         }); | ||||
|     } | ||||
|     m_flash_counter = 8; | ||||
|     m_flash_timer->start(); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -28,6 +28,8 @@ | |||
| 
 | ||||
| #include <AK/Forward.h> | ||||
| #include <AK/NonnullOwnPtrVector.h> | ||||
| #include <AK/RefPtr.h> | ||||
| #include <LibCore/Forward.h> | ||||
| #include <LibGfx/Forward.h> | ||||
| #include <LibGfx/WindowTheme.h> | ||||
| 
 | ||||
|  | @ -58,6 +60,8 @@ public: | |||
|     void layout_buttons(); | ||||
|     void set_button_icons(); | ||||
| 
 | ||||
|     void start_flash_animation(); | ||||
| 
 | ||||
| private: | ||||
|     void paint_notification_frame(Gfx::Painter&); | ||||
|     void paint_normal_frame(Gfx::Painter&); | ||||
|  | @ -69,6 +73,9 @@ private: | |||
|     Button* m_close_button { nullptr }; | ||||
|     Button* m_maximize_button { nullptr }; | ||||
|     Button* m_minimize_button { nullptr }; | ||||
| 
 | ||||
|     RefPtr<Core::Timer> m_flash_timer; | ||||
|     size_t m_flash_counter { 0 }; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -996,6 +996,11 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind | |||
|             // Well okay, let's see if we're hitting the frame or the window inside the frame.
 | ||||
|             if (window.rect().contains(event.position())) { | ||||
|                 if (event.type() == Event::MouseDown) { | ||||
|                     // We're clicking on something that's blocked by a modal window.
 | ||||
|                     // Flash the modal window to let the user know about it.
 | ||||
|                     if (auto* blocking_modal_window = window.is_blocked_by_modal_window()) | ||||
|                         blocking_modal_window->frame().start_flash_animation(); | ||||
| 
 | ||||
|                     if (window.type() == WindowType::Normal) | ||||
|                         move_to_front_and_make_active(window); | ||||
|                     else if (window.type() == WindowType::Desktop) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling