mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:17:34 +00:00
WindowServer: Implement tile window overlay
This adds a tiling mode that will show a tile window overlay rather than immediately tiling a window, triggering window resizes.
This commit is contained in:
parent
035b0f9df6
commit
fe54a0ca27
15 changed files with 279 additions and 71 deletions
|
@ -121,6 +121,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
|
||||||
|
@GUI::Label {
|
||||||
|
text: "Tile Window Behavior:"
|
||||||
|
autosize: true
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Layout::Spacer {}
|
||||||
|
|
||||||
|
@GUI::ComboBox {
|
||||||
|
name: "tile_window_combobox"
|
||||||
|
fixed_width: 130
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@GUI::Widget {
|
@GUI::Widget {
|
||||||
fixed_height: 4
|
fixed_height: 4
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,13 @@ ErrorOr<void> EffectsSettingsWidget::setup_interface()
|
||||||
set_modified(true);
|
set_modified(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m_tile_window_combobox = find_descendant_of_type_named<ComboBox>("tile_window_combobox");
|
||||||
|
m_tile_window_combobox->set_only_allow_values_from_model(true);
|
||||||
|
m_tile_window_combobox->on_change = [this](auto&, auto&) {
|
||||||
|
m_system_effects.set_tile_window(static_cast<WindowServer::TileWindow>(m_tile_window_combobox->selected_index()));
|
||||||
|
set_modified(true);
|
||||||
|
};
|
||||||
|
|
||||||
if (auto result = load_settings(); result.is_error()) {
|
if (auto result = load_settings(); result.is_error()) {
|
||||||
warnln("Failed to load [Effects] from WindowServer.ini");
|
warnln("Failed to load [Effects] from WindowServer.ini");
|
||||||
return {};
|
return {};
|
||||||
|
@ -119,25 +126,36 @@ ErrorOr<void> EffectsSettingsWidget::load_settings()
|
||||||
ws_config->read_bool_entry("Effects", "TooltipShadow", true),
|
ws_config->read_bool_entry("Effects", "TooltipShadow", true),
|
||||||
};
|
};
|
||||||
auto geometry = WindowServer::ShowGeometryTools::string_to_enum(ws_config->read_entry("Effects", "ShowGeometry", "OnMoveAndResize"));
|
auto geometry = WindowServer::ShowGeometryTools::string_to_enum(ws_config->read_entry("Effects", "ShowGeometry", "OnMoveAndResize"));
|
||||||
m_system_effects = { effects, geometry };
|
auto tile_window = WindowServer::TileWindowTools::string_to_enum(ws_config->read_entry("Effects", "TileWindow", "ShowTileOverlay"));
|
||||||
|
m_system_effects = { effects, geometry, tile_window };
|
||||||
|
|
||||||
static constexpr Array list = {
|
static constexpr Array geometry_list = {
|
||||||
"On Move and Resize"sv,
|
"On Move and Resize"sv,
|
||||||
"On Move only"sv,
|
"On Move only"sv,
|
||||||
"On Resize only"sv,
|
"On Resize only"sv,
|
||||||
"Never"sv
|
"Never"sv
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < list.size(); ++i)
|
for (size_t i = 0; i < geometry_list.size(); ++i)
|
||||||
TRY(m_geometry_list.try_append(TRY(String::from_utf8(list[i]))));
|
TRY(m_geometry_list.try_append(TRY(String::from_utf8(geometry_list[i]))));
|
||||||
m_geometry_combobox->set_model(ItemListModel<String>::create(m_geometry_list));
|
m_geometry_combobox->set_model(ItemListModel<String>::create(m_geometry_list));
|
||||||
m_geometry_combobox->set_selected_index(to_underlying(m_system_effects.geometry()));
|
m_geometry_combobox->set_selected_index(to_underlying(m_system_effects.geometry()));
|
||||||
|
|
||||||
|
static constexpr Array tile_window_list = {
|
||||||
|
"Tile immediately"sv,
|
||||||
|
"Show tile overlay"sv,
|
||||||
|
"Never"sv
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < tile_window_list.size(); ++i)
|
||||||
|
TRY(m_tile_window_list.try_append(TRY(String::from_utf8(tile_window_list[i]))));
|
||||||
|
m_tile_window_combobox->set_model(ItemListModel<String>::create(m_tile_window_list));
|
||||||
|
m_tile_window_combobox->set_selected_index(static_cast<size_t>(m_system_effects.tile_window()));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsSettingsWidget::apply_settings()
|
void EffectsSettingsWidget::apply_settings()
|
||||||
{
|
{
|
||||||
ConnectionToWindowServer::the().async_set_system_effects(m_system_effects.effects(), to_underlying(m_system_effects.geometry()));
|
ConnectionToWindowServer::the().async_set_system_effects(m_system_effects.effects(), to_underlying(m_system_effects.geometry()), to_underlying(m_system_effects.tile_window()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ private:
|
||||||
|
|
||||||
SystemEffects m_system_effects;
|
SystemEffects m_system_effects;
|
||||||
Vector<String> m_geometry_list;
|
Vector<String> m_geometry_list;
|
||||||
|
Vector<String> m_tile_window_list;
|
||||||
RefPtr<ComboBox> m_geometry_combobox;
|
RefPtr<ComboBox> m_geometry_combobox;
|
||||||
|
RefPtr<ComboBox> m_tile_window_combobox;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -980,9 +980,9 @@ Messages::WindowServer::SetSystemFontsResponse ConnectionFromClient::set_system_
|
||||||
return !g_config->sync().is_error();
|
return !g_config->sync().is_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::set_system_effects(Vector<bool> const& effects, u8 geometry)
|
void ConnectionFromClient::set_system_effects(Vector<bool> const& effects, u8 geometry, u8 tile_window)
|
||||||
{
|
{
|
||||||
WindowManager::the().apply_system_effects(effects, static_cast<ShowGeometry>(geometry));
|
WindowManager::the().apply_system_effects(effects, static_cast<ShowGeometry>(geometry), static_cast<TileWindow>(tile_window));
|
||||||
ConnectionFromClient::for_each_client([&](auto& client) {
|
ConnectionFromClient::for_each_client([&](auto& client) {
|
||||||
client.async_update_system_effects(effects);
|
client.async_update_system_effects(effects);
|
||||||
});
|
});
|
||||||
|
|
|
@ -160,7 +160,7 @@ private:
|
||||||
virtual Messages::WindowServer::GetCursorHighlightColorResponse get_cursor_highlight_color() override;
|
virtual Messages::WindowServer::GetCursorHighlightColorResponse get_cursor_highlight_color() override;
|
||||||
virtual Messages::WindowServer::GetCursorThemeResponse get_cursor_theme() override;
|
virtual Messages::WindowServer::GetCursorThemeResponse get_cursor_theme() override;
|
||||||
virtual Messages::WindowServer::SetSystemFontsResponse set_system_fonts(DeprecatedString const&, DeprecatedString const&, DeprecatedString const&) override;
|
virtual Messages::WindowServer::SetSystemFontsResponse set_system_fonts(DeprecatedString const&, DeprecatedString const&, DeprecatedString const&) override;
|
||||||
virtual void set_system_effects(Vector<bool> const&, u8) override;
|
virtual void set_system_effects(Vector<bool> const&, u8, u8) override;
|
||||||
virtual void set_window_base_size_and_size_increment(i32, Gfx::IntSize, Gfx::IntSize) override;
|
virtual void set_window_base_size_and_size_increment(i32, Gfx::IntSize, Gfx::IntSize) override;
|
||||||
virtual void set_window_resize_aspect_ratio(i32, Optional<Gfx::IntSize> const&) override;
|
virtual void set_window_resize_aspect_ratio(i32, Optional<Gfx::IntSize> const&) override;
|
||||||
virtual void enable_display_link() override;
|
virtual void enable_display_link() override;
|
||||||
|
|
|
@ -351,4 +351,18 @@ WindowStackSwitchOverlay::WindowStackSwitchOverlay(Screen& screen, WindowStack&
|
||||||
set_rect(calculate_frame_rect(Gfx::IntRect({}, m_content_size).inflated(2 * default_screen_rect_margin, 2 * default_screen_rect_margin)).centered_within(screen.rect()));
|
set_rect(calculate_frame_rect(Gfx::IntRect({}, m_content_size).inflated(2 * default_screen_rect_margin, 2 * default_screen_rect_margin)).centered_within(screen.rect()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TileWindowOverlay::TileWindowOverlay(Window& window, Gfx::IntRect const& tiled_frame_rect, Gfx::Palette&& palette)
|
||||||
|
: m_window(window)
|
||||||
|
, m_tiled_frame_rect(tiled_frame_rect)
|
||||||
|
, m_palette(std::move(palette))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileWindowOverlay::render(Gfx::Painter& painter, Screen const&)
|
||||||
|
{
|
||||||
|
Gfx::IntRect paint_rect { {}, rect().size() };
|
||||||
|
painter.fill_rect(paint_rect, m_palette.rubber_band_fill());
|
||||||
|
painter.draw_rect(paint_rect, m_palette.rubber_band_border());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
#include <LibGfx/Painter.h>
|
#include <LibGfx/Painter.h>
|
||||||
|
#include <LibGfx/Palette.h>
|
||||||
#include <WindowServer/MultiScaleBitmaps.h>
|
#include <WindowServer/MultiScaleBitmaps.h>
|
||||||
#include <WindowServer/Screen.h>
|
#include <WindowServer/Screen.h>
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ public:
|
||||||
virtual ~Overlay();
|
virtual ~Overlay();
|
||||||
|
|
||||||
enum class ZOrder {
|
enum class ZOrder {
|
||||||
|
SnapWindow,
|
||||||
WindowGeometry,
|
WindowGeometry,
|
||||||
Dnd,
|
Dnd,
|
||||||
WindowStackSwitch,
|
WindowStackSwitch,
|
||||||
|
@ -192,4 +194,26 @@ private:
|
||||||
int const m_target_column;
|
int const m_target_column;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TileWindowOverlay : public Overlay {
|
||||||
|
public:
|
||||||
|
TileWindowOverlay(Window&, Gfx::IntRect const&, Gfx::Palette&&);
|
||||||
|
|
||||||
|
virtual ZOrder zorder() const override { return ZOrder::SnapWindow; }
|
||||||
|
virtual void render(Gfx::Painter&, Screen const&) override;
|
||||||
|
|
||||||
|
void set_overlay_rect(Gfx::IntRect const& rect)
|
||||||
|
{
|
||||||
|
set_rect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_tiled_frame_rect(Gfx::IntRect const& rect) { m_tiled_frame_rect = rect; }
|
||||||
|
Gfx::IntRect const& tiled_frame_rect() const { return m_tiled_frame_rect; }
|
||||||
|
bool is_window(Window& window) const { return &m_window == &window; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Window& m_window;
|
||||||
|
Gfx::IntRect m_tiled_frame_rect;
|
||||||
|
Gfx::Palette m_palette;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
|
|
||||||
namespace WindowServer {
|
namespace WindowServer {
|
||||||
|
|
||||||
|
enum class TileWindow : u8 {
|
||||||
|
TileImmediately,
|
||||||
|
ShowTileOverlay,
|
||||||
|
Never
|
||||||
|
};
|
||||||
|
|
||||||
enum class ShowGeometry : u8 {
|
enum class ShowGeometry : u8 {
|
||||||
OnMoveAndResize,
|
OnMoveAndResize,
|
||||||
OnMoveOnly,
|
OnMoveOnly,
|
||||||
|
@ -66,12 +72,42 @@ namespace ShowGeometryTools {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace TileWindowTools {
|
||||||
|
|
||||||
|
[[maybe_unused]] static StringView enum_to_string(TileWindow tile_window)
|
||||||
|
{
|
||||||
|
switch (tile_window) {
|
||||||
|
case TileWindow::Never:
|
||||||
|
return "Never"sv;
|
||||||
|
case TileWindow::TileImmediately:
|
||||||
|
return "TileImmediately"sv;
|
||||||
|
case TileWindow::ShowTileOverlay:
|
||||||
|
return "ShowTileOverlay"sv;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static TileWindow string_to_enum(StringView tile_window)
|
||||||
|
{
|
||||||
|
if (tile_window == "Never"sv)
|
||||||
|
return TileWindow::Never;
|
||||||
|
else if (tile_window == "TileImmediately"sv)
|
||||||
|
return TileWindow::TileImmediately;
|
||||||
|
else if (tile_window == "ShowTileOverlay"sv)
|
||||||
|
return TileWindow::ShowTileOverlay;
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class SystemEffects {
|
class SystemEffects {
|
||||||
public:
|
public:
|
||||||
SystemEffects() = default;
|
SystemEffects() = default;
|
||||||
SystemEffects(Vector<bool> effects, ShowGeometry show)
|
SystemEffects(Vector<bool> effects, ShowGeometry show, TileWindow tile_window)
|
||||||
: m_effects(effects)
|
: m_effects(effects)
|
||||||
, m_geometry(show)
|
, m_geometry(show)
|
||||||
|
, m_tile_window(tile_window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
SystemEffects(Vector<bool> effects)
|
SystemEffects(Vector<bool> effects)
|
||||||
|
@ -107,14 +143,18 @@ public:
|
||||||
void set_geometry(ShowGeometry g) { m_geometry = g; }
|
void set_geometry(ShowGeometry g) { m_geometry = g; }
|
||||||
ShowGeometry geometry() const { return m_geometry; }
|
ShowGeometry geometry() const { return m_geometry; }
|
||||||
|
|
||||||
|
void set_tile_window(TileWindow tile_window) { m_tile_window = tile_window; }
|
||||||
|
TileWindow tile_window() const { return m_tile_window; }
|
||||||
|
|
||||||
bool operator==(SystemEffects const& other) const
|
bool operator==(SystemEffects const& other) const
|
||||||
{
|
{
|
||||||
return m_effects == other.m_effects && m_geometry == other.m_geometry;
|
return m_effects == other.m_effects && m_geometry == other.m_geometry && m_tile_window == other.m_tile_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<bool> m_effects;
|
Vector<bool> m_effects;
|
||||||
ShowGeometry m_geometry { ShowGeometry::Never };
|
ShowGeometry m_geometry { ShowGeometry::Never };
|
||||||
|
TileWindow m_tile_window { TileWindow::ShowTileOverlay };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,8 +420,8 @@ void Window::set_maximized(bool maximized)
|
||||||
else
|
else
|
||||||
set_rect(m_floating_rect);
|
set_rect(m_floating_rect);
|
||||||
m_frame.did_set_maximized({}, maximized);
|
m_frame.did_set_maximized({}, maximized);
|
||||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
send_resize_event_to_client();
|
||||||
Core::EventLoop::current().post_event(*this, make<MoveEvent>(m_rect));
|
send_move_event_to_client();
|
||||||
set_default_positioned(false);
|
set_default_positioned(false);
|
||||||
|
|
||||||
WindowManager::the().notify_minimization_state_changed(*this);
|
WindowManager::the().notify_minimization_state_changed(*this);
|
||||||
|
@ -842,8 +842,8 @@ void Window::set_fullscreen(bool fullscreen)
|
||||||
new_window_rect = m_saved_nonfullscreen_rect;
|
new_window_rect = m_saved_nonfullscreen_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(new_window_rect));
|
send_resize_event_to_client();
|
||||||
Core::EventLoop::current().post_event(*this, make<MoveEvent>(new_window_rect));
|
send_move_event_to_client();
|
||||||
set_rect(new_window_rect);
|
set_rect(new_window_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +858,7 @@ WindowTileType Window::tile_type_based_on_rect(Gfx::IntRect const& rect) const
|
||||||
bool tiling_to_left = current_tile_type == WindowTileType::Left || current_tile_type == WindowTileType::TopLeft || current_tile_type == WindowTileType::BottomLeft;
|
bool tiling_to_left = current_tile_type == WindowTileType::Left || current_tile_type == WindowTileType::TopLeft || current_tile_type == WindowTileType::BottomLeft;
|
||||||
bool tiling_to_right = current_tile_type == WindowTileType::Right || current_tile_type == WindowTileType::TopRight || current_tile_type == WindowTileType::BottomRight;
|
bool tiling_to_right = current_tile_type == WindowTileType::Right || current_tile_type == WindowTileType::TopRight || current_tile_type == WindowTileType::BottomRight;
|
||||||
|
|
||||||
auto ideal_tiled_rect = WindowManager::the().tiled_window_rect(*this, current_tile_type);
|
auto ideal_tiled_rect = WindowManager::the().tiled_window_rect(*this, window_screen, current_tile_type);
|
||||||
bool same_top = ideal_tiled_rect.top() == rect.top();
|
bool same_top = ideal_tiled_rect.top() == rect.top();
|
||||||
bool same_left = ideal_tiled_rect.left() == rect.left();
|
bool same_left = ideal_tiled_rect.left() == rect.left();
|
||||||
bool same_right = ideal_tiled_rect.right() == rect.right();
|
bool same_right = ideal_tiled_rect.right() == rect.right();
|
||||||
|
@ -870,9 +870,9 @@ WindowTileType Window::tile_type_based_on_rect(Gfx::IntRect const& rect) const
|
||||||
if (tiling_to_top && same_top && same_left && same_right)
|
if (tiling_to_top && same_top && same_left && same_right)
|
||||||
return WindowTileType::Top;
|
return WindowTileType::Top;
|
||||||
else if ((tiling_to_top || tiling_to_left) && same_top && same_left)
|
else if ((tiling_to_top || tiling_to_left) && same_top && same_left)
|
||||||
return rect.bottom() == WindowManager::the().tiled_window_rect(*this, WindowTileType::Bottom).bottom() ? WindowTileType::Left : WindowTileType::TopLeft;
|
return rect.bottom() == WindowManager::the().tiled_window_rect(*this, window_screen, WindowTileType::Bottom).bottom() ? WindowTileType::Left : WindowTileType::TopLeft;
|
||||||
else if ((tiling_to_top || tiling_to_right) && same_top && same_right)
|
else if ((tiling_to_top || tiling_to_right) && same_top && same_right)
|
||||||
return rect.bottom() == WindowManager::the().tiled_window_rect(*this, WindowTileType::Bottom).bottom() ? WindowTileType::Right : WindowTileType::TopRight;
|
return rect.bottom() == WindowManager::the().tiled_window_rect(*this, window_screen, WindowTileType::Bottom).bottom() ? WindowTileType::Right : WindowTileType::TopRight;
|
||||||
else if (tiling_to_left && same_left && same_top && same_bottom)
|
else if (tiling_to_left && same_left && same_top && same_bottom)
|
||||||
return WindowTileType::Left;
|
return WindowTileType::Left;
|
||||||
else if (tiling_to_right && same_right && same_top && same_bottom)
|
else if (tiling_to_right && same_right && same_top && same_bottom)
|
||||||
|
@ -880,9 +880,9 @@ WindowTileType Window::tile_type_based_on_rect(Gfx::IntRect const& rect) const
|
||||||
else if (tiling_to_bottom && same_bottom && same_left && same_right)
|
else if (tiling_to_bottom && same_bottom && same_left && same_right)
|
||||||
return WindowTileType::Bottom;
|
return WindowTileType::Bottom;
|
||||||
else if ((tiling_to_bottom || tiling_to_left) && same_bottom && same_left)
|
else if ((tiling_to_bottom || tiling_to_left) && same_bottom && same_left)
|
||||||
return rect.top() == WindowManager::the().tiled_window_rect(*this, WindowTileType::Left).top() ? WindowTileType::Left : WindowTileType::BottomLeft;
|
return rect.top() == WindowManager::the().tiled_window_rect(*this, window_screen, WindowTileType::Left).top() ? WindowTileType::Left : WindowTileType::BottomLeft;
|
||||||
else if ((tiling_to_bottom || tiling_to_right) && same_bottom && same_right)
|
else if ((tiling_to_bottom || tiling_to_right) && same_bottom && same_right)
|
||||||
return rect.top() == WindowManager::the().tiled_window_rect(*this, WindowTileType::Right).top() ? WindowTileType::Right : WindowTileType::BottomRight;
|
return rect.top() == WindowManager::the().tiled_window_rect(*this, window_screen, WindowTileType::Right).top() ? WindowTileType::Right : WindowTileType::BottomRight;
|
||||||
}
|
}
|
||||||
return tile_type;
|
return tile_type;
|
||||||
}
|
}
|
||||||
|
@ -911,15 +911,11 @@ bool Window::set_untiled()
|
||||||
VERIFY(!resize_aspect_ratio().has_value());
|
VERIFY(!resize_aspect_ratio().has_value());
|
||||||
|
|
||||||
m_tile_type = WindowTileType::None;
|
m_tile_type = WindowTileType::None;
|
||||||
set_rect(m_floating_rect);
|
tile_type_changed();
|
||||||
|
|
||||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
|
||||||
Core::EventLoop::current().post_event(*this, make<MoveEvent>(m_rect));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_tiled(WindowTileType tile_type)
|
void Window::set_tiled(WindowTileType tile_type, Optional<Screen const&> tile_on_screen)
|
||||||
{
|
{
|
||||||
VERIFY(tile_type != WindowTileType::None);
|
VERIFY(tile_type != WindowTileType::None);
|
||||||
|
|
||||||
|
@ -933,9 +929,26 @@ void Window::set_tiled(WindowTileType tile_type)
|
||||||
set_maximized(false);
|
set_maximized(false);
|
||||||
|
|
||||||
m_tile_type = tile_type;
|
m_tile_type = tile_type;
|
||||||
|
tile_type_changed(tile_on_screen);
|
||||||
|
}
|
||||||
|
|
||||||
set_rect(WindowManager::the().tiled_window_rect(*this, tile_type));
|
void Window::tile_type_changed(Optional<Screen const&> tile_on_screen)
|
||||||
|
{
|
||||||
|
if (m_tile_type != WindowTileType::None)
|
||||||
|
set_rect(WindowManager::the().tiled_window_rect(*this, tile_on_screen, m_tile_type));
|
||||||
|
else
|
||||||
|
set_rect(m_floating_rect);
|
||||||
|
send_resize_event_to_client();
|
||||||
|
send_move_event_to_client();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::send_resize_event_to_client()
|
||||||
|
{
|
||||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::send_move_event_to_client()
|
||||||
|
{
|
||||||
Core::EventLoop::current().post_event(*this, make<MoveEvent>(m_rect));
|
Core::EventLoop::current().post_event(*this, make<MoveEvent>(m_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -951,7 +964,7 @@ void Window::recalculate_rect()
|
||||||
|
|
||||||
bool send_event = true;
|
bool send_event = true;
|
||||||
if (is_tiled()) {
|
if (is_tiled()) {
|
||||||
set_rect(WindowManager::the().tiled_window_rect(*this, m_tile_type));
|
set_rect(WindowManager::the().tiled_window_rect(*this, {}, m_tile_type));
|
||||||
} else if (type() == WindowType::Desktop) {
|
} else if (type() == WindowType::Desktop) {
|
||||||
set_rect(WindowManager::the().arena_rect_for_type(Screen::main(), WindowType::Desktop));
|
set_rect(WindowManager::the().arena_rect_for_type(Screen::main(), WindowType::Desktop));
|
||||||
} else {
|
} else {
|
||||||
|
@ -959,7 +972,7 @@ void Window::recalculate_rect()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_event) {
|
if (send_event) {
|
||||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect));
|
send_resize_event_to_client();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
|
|
||||||
WindowTileType tile_type() const { return m_tile_type; }
|
WindowTileType tile_type() const { return m_tile_type; }
|
||||||
bool is_tiled() const { return m_tile_type != WindowTileType::None; }
|
bool is_tiled() const { return m_tile_type != WindowTileType::None; }
|
||||||
void set_tiled(WindowTileType);
|
void set_tiled(WindowTileType, Optional<Screen const&> = {});
|
||||||
WindowTileType tile_type_based_on_rect(Gfx::IntRect const&) const;
|
WindowTileType tile_type_based_on_rect(Gfx::IntRect const&) const;
|
||||||
void check_untile_due_to_resize(Gfx::IntRect const&);
|
void check_untile_due_to_resize(Gfx::IntRect const&);
|
||||||
bool set_untiled();
|
bool set_untiled();
|
||||||
|
@ -376,6 +376,9 @@ public:
|
||||||
void remove_all_stealing() { m_stealable_by_client_ids.clear(); }
|
void remove_all_stealing() { m_stealable_by_client_ids.clear(); }
|
||||||
bool is_stealable_by_client(i32 client_id) const { return m_stealable_by_client_ids.contains_slow(client_id); }
|
bool is_stealable_by_client(i32 client_id) const { return m_stealable_by_client_ids.contains_slow(client_id); }
|
||||||
|
|
||||||
|
void send_resize_event_to_client();
|
||||||
|
void send_move_event_to_client();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window(ConnectionFromClient&, WindowType, WindowMode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, Window* parent_window = nullptr);
|
Window(ConnectionFromClient&, WindowType, WindowMode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, Window* parent_window = nullptr);
|
||||||
Window(Core::Object&, WindowType);
|
Window(Core::Object&, WindowType);
|
||||||
|
@ -386,6 +389,7 @@ private:
|
||||||
void add_child_window(Window&);
|
void add_child_window(Window&);
|
||||||
void ensure_window_menu();
|
void ensure_window_menu();
|
||||||
void update_window_menu_items();
|
void update_window_menu_items();
|
||||||
|
void tile_type_changed(Optional<Screen const&> = {});
|
||||||
ErrorOr<Optional<DeprecatedString>> compute_title_username(ConnectionFromClient* client);
|
ErrorOr<Optional<DeprecatedString>> compute_title_username(ConnectionFromClient* client);
|
||||||
|
|
||||||
ConnectionFromClient* m_client { nullptr };
|
ConnectionFromClient* m_client { nullptr };
|
||||||
|
|
|
@ -60,7 +60,7 @@ static DeprecatedString s_last_menu_shadow_path;
|
||||||
static DeprecatedString s_last_taskbar_shadow_path;
|
static DeprecatedString s_last_taskbar_shadow_path;
|
||||||
static DeprecatedString s_last_tooltip_shadow_path;
|
static DeprecatedString s_last_tooltip_shadow_path;
|
||||||
|
|
||||||
static Gfx::IntRect frame_rect_for_window(Window& window, Gfx::IntRect const& rect)
|
Gfx::IntRect WindowFrame::frame_rect_for_window(Window& window, Gfx::IntRect const& rect)
|
||||||
{
|
{
|
||||||
if (window.is_frameless())
|
if (window.is_frameless())
|
||||||
return rect;
|
return rect;
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
};
|
};
|
||||||
friend class RenderedCache;
|
friend class RenderedCache;
|
||||||
|
|
||||||
|
static Gfx::IntRect frame_rect_for_window(Window&, Gfx::IntRect const&);
|
||||||
|
|
||||||
static void reload_config();
|
static void reload_config();
|
||||||
|
|
||||||
explicit WindowFrame(Window&);
|
explicit WindowFrame(Window&);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <LibGfx/StylePainter.h>
|
#include <LibGfx/StylePainter.h>
|
||||||
#include <LibGfx/SystemTheme.h>
|
#include <LibGfx/SystemTheme.h>
|
||||||
#include <Services/Taskbar/TaskbarWindow.h>
|
#include <Services/Taskbar/TaskbarWindow.h>
|
||||||
|
#include <WindowServer/Animation.h>
|
||||||
#include <WindowServer/AppletManager.h>
|
#include <WindowServer/AppletManager.h>
|
||||||
#include <WindowServer/Button.h>
|
#include <WindowServer/Button.h>
|
||||||
#include <WindowServer/ConnectionFromClient.h>
|
#include <WindowServer/ConnectionFromClient.h>
|
||||||
|
@ -335,8 +336,8 @@ void WindowManager::add_window(Window& window)
|
||||||
|
|
||||||
if (window.is_fullscreen()) {
|
if (window.is_fullscreen()) {
|
||||||
auto& screen = Screen::main(); // TODO: support fullscreen windows on other screens!
|
auto& screen = Screen::main(); // TODO: support fullscreen windows on other screens!
|
||||||
Core::EventLoop::current().post_event(window, make<ResizeEvent>(screen.rect()));
|
|
||||||
window.set_rect(screen.rect());
|
window.set_rect(screen.rect());
|
||||||
|
window.send_resize_event_to_client();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.type() != WindowType::Desktop || is_first_window)
|
if (window.type() != WindowType::Desktop || is_first_window)
|
||||||
|
@ -415,6 +416,9 @@ void WindowManager::remove_window(Window& window)
|
||||||
conn.async_window_removed(conn.window_id(), window.client_id(), window.window_id());
|
conn.async_window_removed(conn.window_id(), window.client_id(), window.window_id());
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (m_tile_window_overlay && m_tile_window_overlay->is_window(window))
|
||||||
|
stop_tile_window_animation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::greet_window_manager(WMConnectionFromClient& conn)
|
void WindowManager::greet_window_manager(WMConnectionFromClient& conn)
|
||||||
|
@ -738,6 +742,44 @@ void WindowManager::start_window_resize(Window& window, MouseEvent const& event,
|
||||||
start_window_resize(window, event.position(), event.button(), resize_direction);
|
start_window_resize(window, event.position(), event.button(), resize_direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::start_tile_window_animation(Gfx::IntRect const& starting_rect)
|
||||||
|
{
|
||||||
|
m_tile_window_overlay_animation = Animation::create();
|
||||||
|
m_tile_window_overlay_animation->set_duration(150);
|
||||||
|
m_tile_window_overlay_animation->on_update = [this, starting_rect](float progress, Gfx::Painter&, Screen&, Gfx::DisjointIntRectSet&) {
|
||||||
|
if (m_tile_window_overlay) {
|
||||||
|
auto target_rect = starting_rect.interpolated_to(m_tile_window_overlay->tiled_frame_rect(), progress);
|
||||||
|
m_tile_window_overlay->set_overlay_rect(target_rect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
m_tile_window_overlay_animation->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::stop_tile_window_animation()
|
||||||
|
{
|
||||||
|
m_tile_window_overlay = nullptr;
|
||||||
|
m_tile_window_overlay_animation = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::show_tile_window_overlay(Window& window, Screen const& cursor_screen, WindowTileType tile_type)
|
||||||
|
{
|
||||||
|
m_move_window_suggested_tile = tile_type;
|
||||||
|
if (tile_type != WindowTileType::None && (!m_tile_window_overlay || !m_tile_window_overlay->is_window(window))) {
|
||||||
|
auto tiled_frame_rect = WindowFrame::frame_rect_for_window(window, tiled_window_rect(window, cursor_screen, tile_type));
|
||||||
|
m_tile_window_overlay = Compositor::the().create_overlay<TileWindowOverlay>(window, tiled_frame_rect, palette());
|
||||||
|
m_tile_window_overlay->set_enabled(true);
|
||||||
|
start_tile_window_animation(window.frame().rect());
|
||||||
|
} else if (tile_type == WindowTileType::None) {
|
||||||
|
stop_tile_window_animation();
|
||||||
|
} else {
|
||||||
|
auto tiled_frame_rect = WindowFrame::frame_rect_for_window(window, tiled_window_rect(window, cursor_screen, tile_type));
|
||||||
|
if (m_tile_window_overlay->tiled_frame_rect() != tiled_frame_rect) {
|
||||||
|
m_tile_window_overlay->set_tiled_frame_rect(tiled_frame_rect);
|
||||||
|
start_tile_window_animation(m_tile_window_overlay->rect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowManager::process_ongoing_window_move(MouseEvent& event)
|
bool WindowManager::process_ongoing_window_move(MouseEvent& event)
|
||||||
{
|
{
|
||||||
if (!m_move_window)
|
if (!m_move_window)
|
||||||
|
@ -746,10 +788,21 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event)
|
||||||
|
|
||||||
dbgln_if(MOVE_DEBUG, "[WM] Finish moving Window({})", m_move_window);
|
dbgln_if(MOVE_DEBUG, "[WM] Finish moving Window({})", m_move_window);
|
||||||
|
|
||||||
if (!m_move_window->is_tiled())
|
bool did_tile = false;
|
||||||
|
if (m_move_window_suggested_tile != WindowTileType::None && m_system_effects.tile_window() == TileWindow::ShowTileOverlay) {
|
||||||
|
auto& cursor_screen = Screen::closest_to_location(event.position());
|
||||||
|
m_move_window->set_tiled(m_move_window_suggested_tile, cursor_screen);
|
||||||
|
m_move_window_suggested_tile = WindowTileType::None;
|
||||||
|
stop_tile_window_animation();
|
||||||
|
did_tile = true;
|
||||||
|
} else {
|
||||||
|
did_tile = m_move_window->is_tiled();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!did_tile)
|
||||||
m_move_window->set_floating_rect(m_move_window->rect());
|
m_move_window->set_floating_rect(m_move_window->rect());
|
||||||
|
|
||||||
Core::EventLoop::current().post_event(*m_move_window, make<MoveEvent>(m_move_window->rect()));
|
m_move_window->send_move_event_to_client();
|
||||||
m_move_window->invalidate(true, true);
|
m_move_window->invalidate(true, true);
|
||||||
if (m_move_window->is_resizable()) {
|
if (m_move_window->is_resizable()) {
|
||||||
process_event_for_doubleclick(*m_move_window, event);
|
process_event_for_doubleclick(*m_move_window, event);
|
||||||
|
@ -788,30 +841,44 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bool is_resizable = m_move_window->is_resizable();
|
bool is_resizable = m_move_window->is_resizable();
|
||||||
|
auto tile_window = m_system_effects.tile_window();
|
||||||
|
bool allow_tile = is_resizable && tile_window != TileWindow::Never;
|
||||||
auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin);
|
auto pixels_moved_from_start = event.position().pixels_moved(m_move_origin);
|
||||||
|
|
||||||
auto event_location_relative_to_screen = event.position().translated(-cursor_screen.rect().location());
|
auto apply_window_tile = [&](WindowTileType tile_type) {
|
||||||
if (is_resizable && event_location_relative_to_screen.x() <= tiling_deadzone) {
|
if (tile_window == TileWindow::ShowTileOverlay) {
|
||||||
if (event_location_relative_to_screen.y() <= tiling_deadzone + desktop_relative_to_screen.top())
|
show_tile_window_overlay(*m_move_window, cursor_screen, tile_type);
|
||||||
m_move_window->set_tiled(WindowTileType::TopLeft);
|
} else if (tile_window == TileWindow::TileImmediately) {
|
||||||
else if (event_location_relative_to_screen.y() >= desktop_relative_to_screen.height() - tiling_deadzone)
|
if (tile_type != WindowTileType::None) {
|
||||||
m_move_window->set_tiled(WindowTileType::BottomLeft);
|
m_move_window->set_tiled(tile_type, cursor_screen);
|
||||||
else
|
return;
|
||||||
m_move_window->set_tiled(WindowTileType::Left);
|
}
|
||||||
} else if (is_resizable && event_location_relative_to_screen.x() >= cursor_screen.width() - tiling_deadzone) {
|
}
|
||||||
if (event_location_relative_to_screen.y() <= tiling_deadzone + desktop.top())
|
auto pos = m_move_window_origin.translated(event.position() - m_move_origin);
|
||||||
m_move_window->set_tiled(WindowTileType::TopRight);
|
|
||||||
else if (event_location_relative_to_screen.y() >= desktop_relative_to_screen.height() - tiling_deadzone)
|
|
||||||
m_move_window->set_tiled(WindowTileType::BottomRight);
|
|
||||||
else
|
|
||||||
m_move_window->set_tiled(WindowTileType::Right);
|
|
||||||
} else if (is_resizable && event_location_relative_to_screen.y() <= secondary_deadzone + desktop_relative_to_screen.top()) {
|
|
||||||
m_move_window->set_tiled(WindowTileType::Top);
|
|
||||||
} else if (is_resizable && event_location_relative_to_screen.y() >= desktop_relative_to_screen.bottom() - secondary_deadzone) {
|
|
||||||
m_move_window->set_tiled(WindowTileType::Bottom);
|
|
||||||
} else if (!m_move_window->is_tiled()) {
|
|
||||||
Gfx::IntPoint pos = m_move_window_origin.translated(event.position() - m_move_origin);
|
|
||||||
m_move_window->set_position_without_repaint(pos);
|
m_move_window->set_position_without_repaint(pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto event_location_relative_to_screen = event.position().translated(-cursor_screen.rect().location());
|
||||||
|
if (allow_tile && event_location_relative_to_screen.x() <= tiling_deadzone) {
|
||||||
|
if (event_location_relative_to_screen.y() <= tiling_deadzone + desktop_relative_to_screen.top())
|
||||||
|
apply_window_tile(WindowTileType::TopLeft);
|
||||||
|
else if (event_location_relative_to_screen.y() >= desktop_relative_to_screen.height() - tiling_deadzone)
|
||||||
|
apply_window_tile(WindowTileType::BottomLeft);
|
||||||
|
else
|
||||||
|
apply_window_tile(WindowTileType::Left);
|
||||||
|
} else if (allow_tile && event_location_relative_to_screen.x() >= cursor_screen.width() - tiling_deadzone) {
|
||||||
|
if (event_location_relative_to_screen.y() <= tiling_deadzone + desktop.top())
|
||||||
|
apply_window_tile(WindowTileType::TopRight);
|
||||||
|
else if (event_location_relative_to_screen.y() >= desktop_relative_to_screen.height() - tiling_deadzone)
|
||||||
|
apply_window_tile(WindowTileType::BottomRight);
|
||||||
|
else
|
||||||
|
apply_window_tile(WindowTileType::Right);
|
||||||
|
} else if (allow_tile && event_location_relative_to_screen.y() <= secondary_deadzone + desktop_relative_to_screen.top()) {
|
||||||
|
apply_window_tile(WindowTileType::Top);
|
||||||
|
} else if (allow_tile && event_location_relative_to_screen.y() >= desktop_relative_to_screen.bottom() - secondary_deadzone) {
|
||||||
|
apply_window_tile(WindowTileType::Bottom);
|
||||||
|
} else if (!m_move_window->is_tiled()) {
|
||||||
|
apply_window_tile(WindowTileType::None);
|
||||||
} else if (pixels_moved_from_start > 5) {
|
} else if (pixels_moved_from_start > 5) {
|
||||||
Gfx::IntPoint adjusted_position = event.position().translated(-m_move_window_cursor_position);
|
Gfx::IntPoint adjusted_position = event.position().translated(-m_move_window_cursor_position);
|
||||||
m_move_window->set_untiled();
|
m_move_window->set_untiled();
|
||||||
|
@ -824,7 +891,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event)
|
||||||
m_geometry_overlay->window_rect_changed();
|
m_geometry_overlay->window_rect_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Core::EventLoop::current().post_event(*m_move_window, make<MoveEvent>(m_move_window->rect()));
|
m_move_window->send_move_event_to_client();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,7 +942,7 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event)
|
||||||
if (!m_resize_window->is_tiled())
|
if (!m_resize_window->is_tiled())
|
||||||
m_resize_window->set_floating_rect(m_resize_window->rect());
|
m_resize_window->set_floating_rect(m_resize_window->rect());
|
||||||
|
|
||||||
Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect()));
|
m_resize_window->send_resize_event_to_client();
|
||||||
m_resize_window->invalidate(true, true);
|
m_resize_window->invalidate(true, true);
|
||||||
m_resize_window = nullptr;
|
m_resize_window = nullptr;
|
||||||
m_geometry_overlay = nullptr;
|
m_geometry_overlay = nullptr;
|
||||||
|
@ -1013,7 +1080,7 @@ bool WindowManager::process_ongoing_window_resize(MouseEvent const& event)
|
||||||
if (system_effects().geometry() == ShowGeometry::OnMoveAndResize || system_effects().geometry() == ShowGeometry::OnResizeOnly) {
|
if (system_effects().geometry() == ShowGeometry::OnMoveAndResize || system_effects().geometry() == ShowGeometry::OnResizeOnly) {
|
||||||
m_geometry_overlay->window_rect_changed();
|
m_geometry_overlay->window_rect_changed();
|
||||||
}
|
}
|
||||||
Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(new_rect));
|
m_resize_window->send_resize_event_to_client();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,7 +1491,7 @@ void WindowManager::clear_resize_candidate()
|
||||||
m_resize_candidate = nullptr;
|
m_resize_candidate = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntRect WindowManager::desktop_rect(Screen& screen) const
|
Gfx::IntRect WindowManager::desktop_rect(Screen const& screen) const
|
||||||
{
|
{
|
||||||
if (active_fullscreen_window())
|
if (active_fullscreen_window())
|
||||||
return Screen::main().rect(); // TODO: we should support fullscreen windows on any screen
|
return Screen::main().rect(); // TODO: we should support fullscreen windows on any screen
|
||||||
|
@ -1965,11 +2032,11 @@ ResizeDirection WindowManager::resize_direction_of_window(Window const& window)
|
||||||
return m_resize_direction;
|
return m_resize_direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::IntRect WindowManager::tiled_window_rect(Window const& window, WindowTileType tile_type, bool relative_to_window_screen) const
|
Gfx::IntRect WindowManager::tiled_window_rect(Window const& window, Optional<Screen const&> cursor_screen, WindowTileType tile_type) const
|
||||||
{
|
{
|
||||||
VERIFY(tile_type != WindowTileType::None);
|
VERIFY(tile_type != WindowTileType::None);
|
||||||
|
|
||||||
auto& screen = Screen::closest_to_rect(window.frame().rect());
|
auto const& screen = cursor_screen.has_value() ? cursor_screen.value() : Screen::closest_to_rect(window.frame().rect());
|
||||||
auto rect = desktop_rect(screen);
|
auto rect = desktop_rect(screen);
|
||||||
|
|
||||||
if (tile_type == WindowTileType::Maximized) {
|
if (tile_type == WindowTileType::Maximized) {
|
||||||
|
@ -2022,9 +2089,6 @@ Gfx::IntRect WindowManager::tiled_window_rect(Window const& window, WindowTileTy
|
||||||
rect.set_y(rect.y() + window_rect.y() - window_frame_rect.y());
|
rect.set_y(rect.y() + window_rect.y() - window_frame_rect.y());
|
||||||
rect.set_height(rect.height() - window_frame_rect.height() + window_rect.height());
|
rect.set_height(rect.height() - window_frame_rect.height() + window_rect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relative_to_window_screen)
|
|
||||||
rect.translate_by(-screen.rect().location());
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2312,12 +2376,12 @@ void WindowManager::set_cursor_highlight_color(Gfx::Color color)
|
||||||
sync_config_to_disk();
|
sync_config_to_disk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::apply_system_effects(Vector<bool> effects, ShowGeometry geometry)
|
void WindowManager::apply_system_effects(Vector<bool> effects, ShowGeometry geometry, TileWindow tile_window)
|
||||||
{
|
{
|
||||||
if (m_system_effects == SystemEffects { effects, geometry })
|
if (m_system_effects == SystemEffects { effects, geometry, tile_window })
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_system_effects = { effects, geometry };
|
m_system_effects = { effects, geometry, tile_window };
|
||||||
g_config->write_bool_entry("Effects", "AnimateMenus", m_system_effects.animate_menus());
|
g_config->write_bool_entry("Effects", "AnimateMenus", m_system_effects.animate_menus());
|
||||||
g_config->write_bool_entry("Effects", "FlashMenus", m_system_effects.flash_menus());
|
g_config->write_bool_entry("Effects", "FlashMenus", m_system_effects.flash_menus());
|
||||||
g_config->write_bool_entry("Effects", "AnimateWindows", m_system_effects.animate_windows());
|
g_config->write_bool_entry("Effects", "AnimateWindows", m_system_effects.animate_windows());
|
||||||
|
@ -2329,6 +2393,7 @@ void WindowManager::apply_system_effects(Vector<bool> effects, ShowGeometry geom
|
||||||
g_config->write_bool_entry("Effects", "WindowShadow", m_system_effects.window_shadow());
|
g_config->write_bool_entry("Effects", "WindowShadow", m_system_effects.window_shadow());
|
||||||
g_config->write_bool_entry("Effects", "TooltipShadow", m_system_effects.tooltip_shadow());
|
g_config->write_bool_entry("Effects", "TooltipShadow", m_system_effects.tooltip_shadow());
|
||||||
g_config->write_entry("Effects", "ShowGeometry", ShowGeometryTools::enum_to_string(geometry));
|
g_config->write_entry("Effects", "ShowGeometry", ShowGeometryTools::enum_to_string(geometry));
|
||||||
|
g_config->write_entry("Effects", "TileWindow", TileWindowTools::enum_to_string(tile_window));
|
||||||
sync_config_to_disk();
|
sync_config_to_disk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2347,7 +2412,8 @@ void WindowManager::load_system_effects()
|
||||||
g_config->read_bool_entry("Effects", "TooltipShadow", true)
|
g_config->read_bool_entry("Effects", "TooltipShadow", true)
|
||||||
};
|
};
|
||||||
ShowGeometry geometry = ShowGeometryTools::string_to_enum(g_config->read_entry("Effects", "ShowGeometry", "OnMoveAndResize"));
|
ShowGeometry geometry = ShowGeometryTools::string_to_enum(g_config->read_entry("Effects", "ShowGeometry", "OnMoveAndResize"));
|
||||||
m_system_effects = { effects, geometry };
|
TileWindow tile_window = TileWindowTools::string_to_enum(g_config->read_entry("Effects", "TileWindow", "ShowTileOverlay"));
|
||||||
|
m_system_effects = { effects, geometry, tile_window };
|
||||||
|
|
||||||
ConnectionFromClient::for_each_client([&](auto& client) {
|
ConnectionFromClient::for_each_client([&](auto& client) {
|
||||||
client.async_update_system_effects(effects);
|
client.async_update_system_effects(effects);
|
||||||
|
|
|
@ -43,6 +43,7 @@ class WindowSwitcher;
|
||||||
class Button;
|
class Button;
|
||||||
class DndOverlay;
|
class DndOverlay;
|
||||||
class WindowGeometryOverlay;
|
class WindowGeometryOverlay;
|
||||||
|
class TileWindowOverlay;
|
||||||
|
|
||||||
class WindowManager : public Core::Object {
|
class WindowManager : public Core::Object {
|
||||||
C_OBJECT(WindowManager)
|
C_OBJECT(WindowManager)
|
||||||
|
@ -79,7 +80,7 @@ public:
|
||||||
void notify_progress_changed(Window&);
|
void notify_progress_changed(Window&);
|
||||||
void notify_modified_changed(Window&);
|
void notify_modified_changed(Window&);
|
||||||
|
|
||||||
Gfx::IntRect tiled_window_rect(Window const&, WindowTileType tile_type = WindowTileType::Maximized, bool relative_to_window_screen = false) const;
|
Gfx::IntRect tiled_window_rect(Window const&, Optional<Screen const&> = {}, WindowTileType tile_type = WindowTileType::Maximized) const;
|
||||||
|
|
||||||
ConnectionFromClient const* dnd_client() const { return m_dnd_client.ptr(); }
|
ConnectionFromClient const* dnd_client() const { return m_dnd_client.ptr(); }
|
||||||
Core::MimeData const& dnd_mime_data() const { return *m_dnd_mime_data; }
|
Core::MimeData const& dnd_mime_data() const { return *m_dnd_mime_data; }
|
||||||
|
@ -115,7 +116,7 @@ public:
|
||||||
|
|
||||||
void move_to_front_and_make_active(Window&);
|
void move_to_front_and_make_active(Window&);
|
||||||
|
|
||||||
Gfx::IntRect desktop_rect(Screen&) const;
|
Gfx::IntRect desktop_rect(Screen const&) const;
|
||||||
Gfx::IntRect arena_rect_for_type(Screen&, WindowType) const;
|
Gfx::IntRect arena_rect_for_type(Screen&, WindowType) const;
|
||||||
|
|
||||||
Cursor const& active_cursor() const;
|
Cursor const& active_cursor() const;
|
||||||
|
@ -328,7 +329,7 @@ public:
|
||||||
bool is_cursor_highlight_enabled() const { return m_cursor_highlight_radius > 0 && m_cursor_highlight_enabled; }
|
bool is_cursor_highlight_enabled() const { return m_cursor_highlight_radius > 0 && m_cursor_highlight_enabled; }
|
||||||
|
|
||||||
void load_system_effects();
|
void load_system_effects();
|
||||||
void apply_system_effects(Vector<bool>, ShowGeometry);
|
void apply_system_effects(Vector<bool>, ShowGeometry, TileWindow);
|
||||||
SystemEffects& system_effects() { return m_system_effects; }
|
SystemEffects& system_effects() { return m_system_effects; }
|
||||||
|
|
||||||
RefPtr<KeymapSwitcher> keymap_switcher() { return m_keymap_switcher; }
|
RefPtr<KeymapSwitcher> keymap_switcher() { return m_keymap_switcher; }
|
||||||
|
@ -339,6 +340,9 @@ public:
|
||||||
|
|
||||||
u8 last_processed_buttons() { return m_last_processed_buttons; }
|
u8 last_processed_buttons() { return m_last_processed_buttons; }
|
||||||
|
|
||||||
|
void start_tile_window_animation(Gfx::IntRect const&);
|
||||||
|
void stop_tile_window_animation();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit WindowManager(Gfx::PaletteImpl&);
|
explicit WindowManager(Gfx::PaletteImpl&);
|
||||||
|
|
||||||
|
@ -433,6 +437,8 @@ private:
|
||||||
|
|
||||||
Gfx::IntPoint to_floating_cursor_position(Gfx::IntPoint) const;
|
Gfx::IntPoint to_floating_cursor_position(Gfx::IntPoint) const;
|
||||||
|
|
||||||
|
void show_tile_window_overlay(Window&, Screen const&, WindowTileType);
|
||||||
|
|
||||||
DoubleClickInfo m_double_click_info;
|
DoubleClickInfo m_double_click_info;
|
||||||
int m_double_click_speed { 0 };
|
int m_double_click_speed { 0 };
|
||||||
int m_max_distance_for_double_click { 4 };
|
int m_max_distance_for_double_click { 4 };
|
||||||
|
@ -448,7 +454,10 @@ private:
|
||||||
WeakPtr<Window> m_automatic_cursor_tracking_window;
|
WeakPtr<Window> m_automatic_cursor_tracking_window;
|
||||||
|
|
||||||
OwnPtr<WindowGeometryOverlay> m_geometry_overlay;
|
OwnPtr<WindowGeometryOverlay> m_geometry_overlay;
|
||||||
|
OwnPtr<TileWindowOverlay> m_tile_window_overlay;
|
||||||
|
RefPtr<Animation> m_tile_window_overlay_animation;
|
||||||
WeakPtr<Window> m_move_window;
|
WeakPtr<Window> m_move_window;
|
||||||
|
WindowTileType m_move_window_suggested_tile { WindowTileType::None };
|
||||||
Gfx::IntPoint m_move_origin;
|
Gfx::IntPoint m_move_origin;
|
||||||
Gfx::IntPoint m_move_window_origin;
|
Gfx::IntPoint m_move_window_origin;
|
||||||
Gfx::IntPoint m_move_window_cursor_position;
|
Gfx::IntPoint m_move_window_cursor_position;
|
||||||
|
|
|
@ -152,7 +152,7 @@ endpoint WindowServer
|
||||||
get_cursor_highlight_color() => (Gfx::Color color)
|
get_cursor_highlight_color() => (Gfx::Color color)
|
||||||
|
|
||||||
set_system_fonts(DeprecatedString default_font_query, DeprecatedString fixed_width_font_query, DeprecatedString window_title_font_query) => (bool success)
|
set_system_fonts(DeprecatedString default_font_query, DeprecatedString fixed_width_font_query, DeprecatedString window_title_font_query) => (bool success)
|
||||||
set_system_effects(Vector<bool> effects, u8 geometry) =|
|
set_system_effects(Vector<bool> effects, u8 geometry, u8 tile_window) =|
|
||||||
|
|
||||||
set_window_base_size_and_size_increment(i32 window_id, Gfx::IntSize base_size, Gfx::IntSize size_increment) =|
|
set_window_base_size_and_size_increment(i32 window_id, Gfx::IntSize base_size, Gfx::IntSize size_increment) =|
|
||||||
set_window_resize_aspect_ratio(i32 window_id, Optional<Gfx::IntSize> resize_aspect_ratio) =|
|
set_window_resize_aspect_ratio(i32 window_id, Optional<Gfx::IntSize> resize_aspect_ratio) =|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue