1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:48:11 +00:00

LibGUI+WindowServer: Introduce WindowModes

Previously, Windows only understood blocking modality: Windows were
either modal, i.e., in a blocking state, or not. Windows could also
be set as Accessories or ToolWindows, attributes which technically
applied modes to their parents but were implemented ad hoc. This patch
redefines these modal effects as WindowModes and sets up some helpers.
This will let us simplify a lot of modal logic in the upcoming patches
and make it easier to build new modal effects in the future.

Windows can now set 1 of 5 modes before reification:
-Modeless:	No modal effect; begins a new modal chain
-Passive:	Window joins its modal chain but has no effect
-RenderAbove:	Window renders above its parent
-CaptureInput:	Window captures the active input role from its parent
-Blocking:	Window blocks all interaction with its modal chain

States like fullscreen and tiling are dynamic and don't alter behavior
in modal chains, so they aren't included.
This commit is contained in:
thankyouverycool 2022-08-18 11:00:08 -04:00 committed by Andreas Kling
parent 609391b46e
commit 589572cfa4
15 changed files with 91 additions and 63 deletions

View file

@ -563,10 +563,10 @@ Window* ConnectionFromClient::window_from_id(i32 window_id)
}
void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect,
bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool closeable, bool resizable,
bool auto_position, bool has_alpha_channel, bool minimizable, bool closeable, bool resizable,
bool fullscreen, bool frameless, bool forced_shadow, bool accessory, float opacity,
float alpha_hit_threshold, Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment,
Gfx::IntSize const& minimum_size, Optional<Gfx::IntSize> const& resize_aspect_ratio, i32 type,
Gfx::IntSize const& minimum_size, Optional<Gfx::IntSize> const& resize_aspect_ratio, i32 type, i32 mode,
String const& title, i32 parent_window_id, Gfx::IntRect const& launch_origin_rect)
{
Window* parent_window = nullptr;
@ -576,6 +576,10 @@ void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect
did_misbehave("CreateWindow with bad parent_window_id");
return;
}
if (parent_window->is_blocking() || (parent_window->is_capturing_input() && mode == (i32)WindowMode::CaptureInput)) {
did_misbehave("CreateWindow with forbidden parent mode");
return;
}
}
if (type < 0 || type >= (i32)WindowType::_Count) {
@ -583,12 +587,17 @@ void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect
return;
}
if (mode < 0 || mode >= (i32)WindowMode::_Count) {
did_misbehave("CreateWindow with a bad mode");
return;
}
if (m_windows.contains(window_id)) {
did_misbehave("CreateWindow with already-used window ID");
return;
}
auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, closeable, frameless, resizable, fullscreen, accessory, parent_window);
auto window = Window::construct(*this, (WindowType)type, (WindowMode)mode, window_id, minimizable, closeable, frameless, resizable, fullscreen, accessory, parent_window);
window->set_forced_shadow(forced_shadow);