mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +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
Notes:
sideshowbarker
2024-07-19 00:17:34 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/af7800d947f
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
|
Gfx::WindowTheme::WindowState WindowFrame::window_state_for_theme() const
|
||||||
{
|
{
|
||||||
auto& wm = WindowManager::the();
|
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)
|
if (&m_window == wm.m_highlight_window)
|
||||||
return Gfx::WindowTheme::WindowState::Highlighted;
|
return Gfx::WindowTheme::WindowState::Highlighted;
|
||||||
if (&m_window == wm.m_move_window)
|
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)
|
if (m_window.is_resizable() && event.type() == Event::MouseDown && event.button() == MouseButton::Left)
|
||||||
wm.start_window_resize(m_window, event.translated(rect().location()));
|
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/Forward.h>
|
||||||
#include <AK/NonnullOwnPtrVector.h>
|
#include <AK/NonnullOwnPtrVector.h>
|
||||||
|
#include <AK/RefPtr.h>
|
||||||
|
#include <LibCore/Forward.h>
|
||||||
#include <LibGfx/Forward.h>
|
#include <LibGfx/Forward.h>
|
||||||
#include <LibGfx/WindowTheme.h>
|
#include <LibGfx/WindowTheme.h>
|
||||||
|
|
||||||
|
@ -58,6 +60,8 @@ public:
|
||||||
void layout_buttons();
|
void layout_buttons();
|
||||||
void set_button_icons();
|
void set_button_icons();
|
||||||
|
|
||||||
|
void start_flash_animation();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paint_notification_frame(Gfx::Painter&);
|
void paint_notification_frame(Gfx::Painter&);
|
||||||
void paint_normal_frame(Gfx::Painter&);
|
void paint_normal_frame(Gfx::Painter&);
|
||||||
|
@ -69,6 +73,9 @@ private:
|
||||||
Button* m_close_button { nullptr };
|
Button* m_close_button { nullptr };
|
||||||
Button* m_maximize_button { nullptr };
|
Button* m_maximize_button { nullptr };
|
||||||
Button* m_minimize_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.
|
// Well okay, let's see if we're hitting the frame or the window inside the frame.
|
||||||
if (window.rect().contains(event.position())) {
|
if (window.rect().contains(event.position())) {
|
||||||
if (event.type() == Event::MouseDown) {
|
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)
|
if (window.type() == WindowType::Normal)
|
||||||
move_to_front_and_make_active(window);
|
move_to_front_and_make_active(window);
|
||||||
else if (window.type() == WindowType::Desktop)
|
else if (window.type() == WindowType::Desktop)
|
||||||
|
|
Loading…
Reference in a new issue