diff --git a/Libraries/LibGUI/ComboBox.cpp b/Libraries/LibGUI/ComboBox.cpp index ae6a236edb..9b1abf63b3 100644 --- a/Libraries/LibGUI/ComboBox.cpp +++ b/Libraries/LibGUI/ComboBox.cpp @@ -99,8 +99,17 @@ ComboBox::ComboBox() open(); }; - m_list_window = add(); + m_list_window = add(window()); m_list_window->set_frameless(true); + m_list_window->set_accessory(true); + + m_list_window->on_active_input_change = [this](bool is_active_input) { + if (!is_active_input) { + m_open_button->set_enabled(true); + close(); + } + }; + m_list_window->on_activity_change = [this](const bool is_active) { if (!is_active) { m_open_button->set_enabled(false); diff --git a/Libraries/LibGUI/Event.h b/Libraries/LibGUI/Event.h index 298e8872a6..1fe9205892 100644 --- a/Libraries/LibGUI/Event.h +++ b/Libraries/LibGUI/Event.h @@ -57,6 +57,8 @@ public: WindowLeft, WindowBecameInactive, WindowBecameActive, + WindowInputEntered, + WindowInputLeft, FocusIn, FocusOut, WindowCloseRequest, diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp index f64d1df5b2..5d1a123887 100644 --- a/Libraries/LibGUI/Widget.cpp +++ b/Libraries/LibGUI/Widget.cpp @@ -502,9 +502,12 @@ bool Widget::is_focused() const auto* win = window(); if (!win) return false; - if (!win->is_active()) - return false; - return win->focused_widget() == this; + // Accessory windows are not active despite being the active + // input window. So we can have focus if either we're the active + // input window or we're the active window + if (win->is_active_input() || win->is_active()) + return win->focused_widget() == this; + return false; } void Widget::set_focus(bool focus) diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index b5c024e0c3..b9a1c9e5cc 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -101,6 +101,7 @@ void Window::show() m_resizable, m_fullscreen, m_frameless, + m_accessory, m_opacity_when_windowless, m_base_size, m_size_increment, @@ -338,6 +339,17 @@ void Window::event(Core::Event& event) return; } + if (event.type() == Event::WindowInputEntered || event.type() == Event::WindowInputLeft) { + m_is_active_input = event.type() == Event::WindowInputEntered; + if (on_active_input_change) + on_active_input_change(m_is_active_input); + if (m_main_widget) + m_main_widget->dispatch_event(event, this); + if (m_focused_widget) + m_focused_widget->update(); + return; + } + if (event.type() == Event::WindowCloseRequest) { if (on_close_request) { if (on_close_request() == Window::CloseRequestDecision::StayOpen) diff --git a/Libraries/LibGUI/Window.h b/Libraries/LibGUI/Window.h index 1e75fec470..2b505b6b02 100644 --- a/Libraries/LibGUI/Window.h +++ b/Libraries/LibGUI/Window.h @@ -98,6 +98,7 @@ public: }; Function on_close_request; + Function on_active_input_change; Function on_activity_change; int x() const { return rect().x(); } @@ -122,6 +123,10 @@ public: bool is_visible() const; bool is_active() const { return m_is_active; } + bool is_active_input() const { return m_is_active_input; } + + bool is_accessory() const { return m_accessory; } + void set_accessory(bool accessory) { m_accessory = accessory; } void show(); void hide(); @@ -232,6 +237,7 @@ private: WindowType m_window_type { WindowType::Normal }; StandardCursor m_override_cursor { StandardCursor::None }; bool m_is_active { false }; + bool m_is_active_input { false }; bool m_has_alpha_channel { false }; bool m_double_buffering_enabled { true }; bool m_modal { false }; @@ -242,6 +248,7 @@ private: bool m_layout_pending { false }; bool m_visible_for_timer_purposes { true }; bool m_visible { false }; + bool m_accessory { false }; }; } diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp index 5301186680..1f29afe18a 100644 --- a/Libraries/LibGUI/WindowServerConnection.cpp +++ b/Libraries/LibGUI/WindowServerConnection.cpp @@ -106,6 +106,18 @@ void WindowServerConnection::handle(const Messages::WindowClient::WindowDeactiva Core::EventLoop::current().post_event(*window, make(Event::WindowBecameInactive)); } +void WindowServerConnection::handle(const Messages::WindowClient::WindowInputEntered& message) +{ + if (auto* window = Window::from_window_id(message.window_id())) + Core::EventLoop::current().post_event(*window, make(Event::WindowInputEntered)); +} + +void WindowServerConnection::handle(const Messages::WindowClient::WindowInputLeft& message) +{ + if (auto* window = Window::from_window_id(message.window_id())) + Core::EventLoop::current().post_event(*window, make(Event::WindowInputLeft)); +} + void WindowServerConnection::handle(const Messages::WindowClient::WindowCloseRequest& message) { if (auto* window = Window::from_window_id(message.window_id())) diff --git a/Libraries/LibGUI/WindowServerConnection.h b/Libraries/LibGUI/WindowServerConnection.h index 9f8dda6e4e..49850e3839 100644 --- a/Libraries/LibGUI/WindowServerConnection.h +++ b/Libraries/LibGUI/WindowServerConnection.h @@ -59,6 +59,8 @@ private: virtual void handle(const Messages::WindowClient::KeyUp&) override; virtual void handle(const Messages::WindowClient::WindowActivated&) override; virtual void handle(const Messages::WindowClient::WindowDeactivated&) override; + virtual void handle(const Messages::WindowClient::WindowInputEntered&) override; + virtual void handle(const Messages::WindowClient::WindowInputLeft&) override; virtual void handle(const Messages::WindowClient::WindowCloseRequest&) override; virtual void handle(const Messages::WindowClient::WindowResized&) override; virtual void handle(const Messages::WindowClient::MenuItemActivated&) override; diff --git a/Services/WindowServer/ClientConnection.cpp b/Services/WindowServer/ClientConnection.cpp index d62d92a930..9089ece782 100644 --- a/Services/WindowServer/ClientConnection.cpp +++ b/Services/WindowServer/ClientConnection.cpp @@ -434,22 +434,18 @@ Window* ClientConnection::window_from_id(i32 window_id) OwnPtr ClientConnection::handle(const Messages::WindowServer::CreateWindow& message) { - int window_id = m_next_window_id++; - auto window = Window::construct(*this, (WindowType)message.type(), window_id, message.modal(), message.minimizable(), message.frameless(), message.resizable(), message.fullscreen()); - + Window* parent_window = nullptr; if (message.parent_window_id()) { - auto* parent_window = window_from_id(message.parent_window_id()); + parent_window = window_from_id(message.parent_window_id()); if (!parent_window) { did_misbehave("CreateWindow with bad parent_window_id"); return nullptr; } - if (parent_window->window_id() == window_id) { - did_misbehave("CreateWindow trying to make a window with itself as parent"); - return nullptr; - } - window->set_parent_window(*parent_window); } + int window_id = m_next_window_id++; + auto window = Window::construct(*this, (WindowType)message.type(), window_id, message.modal(), message.minimizable(), message.frameless(), message.resizable(), message.fullscreen(), message.accessory(), parent_window); + window->set_has_alpha_channel(message.has_alpha_channel()); window->set_title(message.title()); if (!message.fullscreen()) { diff --git a/Services/WindowServer/Event.h b/Services/WindowServer/Event.h index fb29fb4d4e..550c8275e9 100644 --- a/Services/WindowServer/Event.h +++ b/Services/WindowServer/Event.h @@ -50,6 +50,8 @@ public: KeyUp, WindowActivated, WindowDeactivated, + WindowInputEntered, + WindowInputLeft, WindowCloseRequest, WindowResized, }; diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index 8f16da8d93..08fc0f80f2 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -91,7 +91,7 @@ Window::Window(Core::Object& parent, WindowType type) WindowManager::the().add_window(*this); } -Window::Window(ClientConnection& client, WindowType window_type, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen) +Window::Window(ClientConnection& client, WindowType window_type, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window) : Core::Object(&client) , m_client(&client) , m_type(window_type) @@ -100,6 +100,7 @@ Window::Window(ClientConnection& client, WindowType window_type, int window_id, , m_frameless(frameless) , m_resizable(resizable) , m_fullscreen(fullscreen) + , m_accessory(accessory) , m_window_id(window_id) , m_client_id(client.client_id()) , m_icon(default_window_icon()) @@ -111,6 +112,8 @@ Window::Window(ClientConnection& client, WindowType window_type, int window_id, m_listens_to_wm_events = true; } + if (parent_window) + set_parent_window(*parent_window); WindowManager::the().add_window(*this); } @@ -321,6 +324,12 @@ void Window::event(Core::Event& event) case Event::WindowDeactivated: m_client->post_message(Messages::WindowClient::WindowDeactivated(m_window_id)); break; + case Event::WindowInputEntered: + m_client->post_message(Messages::WindowClient::WindowInputEntered(m_window_id)); + break; + case Event::WindowInputLeft: + m_client->post_message(Messages::WindowClient::WindowInputLeft(m_window_id)); + break; case Event::WindowCloseRequest: m_client->post_message(Messages::WindowClient::WindowCloseRequest(m_window_id)); break; @@ -566,11 +575,26 @@ void Window::add_child_window(Window& child_window) m_child_windows.append(child_window.make_weak_ptr()); } +void Window::add_accessory_window(Window& accessory_window) +{ + m_accessory_windows.append(accessory_window.make_weak_ptr()); +} + void Window::set_parent_window(Window& parent_window) { ASSERT(!m_parent_window); m_parent_window = parent_window.make_weak_ptr(); - parent_window.add_child_window(*this); + if (m_accessory) + parent_window.add_accessory_window(*this); + else + parent_window.add_child_window(*this); +} + +bool Window::is_accessory_of(Window& window) const +{ + if (!is_accessory()) + return false; + return parent_window() == &window; } void Window::set_progress(int progress) diff --git a/Services/WindowServer/Window.h b/Services/WindowServer/Window.h index fec098aaf6..b5384b5227 100644 --- a/Services/WindowServer/Window.h +++ b/Services/WindowServer/Window.h @@ -76,7 +76,7 @@ class Window final : public Core::Object , public InlineLinkedListNode { C_OBJECT(Window) public: - Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen); + Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window = nullptr); Window(Core::Object&, WindowType); virtual ~Window() override; @@ -240,6 +240,13 @@ public: Vector>& child_windows() { return m_child_windows; } const Vector>& child_windows() const { return m_child_windows; } + Vector>& accessory_windows() { return m_accessory_windows; } + const Vector>& accessory_windows() const { return m_accessory_windows; } + + void set_accessory(bool accessory) { m_accessory = accessory; } + bool is_accessory() const { return m_accessory; } + bool is_accessory_of(Window&) const; + void set_frameless(bool frameless) { m_frameless = frameless; } bool is_frameless() const { return m_frameless; } @@ -251,12 +258,14 @@ private: void update_menu_item_text(PopupMenuItem item); void update_menu_item_enabled(PopupMenuItem item); void add_child_window(Window&); + void add_accessory_window(Window&); void ensure_window_menu(); ClientConnection* m_client { nullptr }; WeakPtr m_parent_window; Vector> m_child_windows; + Vector> m_accessory_windows; String m_title; Gfx::IntRect m_rect; @@ -275,6 +284,7 @@ private: bool m_minimized { false }; bool m_maximized { false }; bool m_fullscreen { false }; + bool m_accessory { false }; WindowTileType m_tiled { WindowTileType::None }; Gfx::IntRect m_untiled_rect; bool m_occluded { false }; diff --git a/Services/WindowServer/WindowClient.ipc b/Services/WindowServer/WindowClient.ipc index ed0308c79c..53d8dc2747 100644 --- a/Services/WindowServer/WindowClient.ipc +++ b/Services/WindowServer/WindowClient.ipc @@ -8,6 +8,8 @@ endpoint WindowClient = 4 MouseWheel(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| WindowEntered(i32 window_id) =| WindowLeft(i32 window_id) =| + WindowInputEntered(i32 window_id) =| + WindowInputLeft(i32 window_id) =| KeyDown(i32 window_id, u32 code_point, u32 key, u32 modifiers, u32 scancode) =| KeyUp(i32 window_id, u32 code_point, u32 key, u32 modifiers, u32 scancode) =| WindowActivated(i32 window_id) =| diff --git a/Services/WindowServer/WindowFrame.cpp b/Services/WindowServer/WindowFrame.cpp index 7e1d9fa589..cce040fd87 100644 --- a/Services/WindowServer/WindowFrame.cpp +++ b/Services/WindowServer/WindowFrame.cpp @@ -189,7 +189,7 @@ WindowFrame::FrameColors WindowFrame::compute_frame_colors() const return { palette.highlight_window_title(), palette.highlight_window_border1(), palette.highlight_window_border2() }; if (&m_window == wm.m_move_window) return { palette.moving_window_title(), palette.moving_window_border1(), palette.moving_window_border2() }; - if (&m_window == wm.m_active_window) + if (wm.is_active_window_or_accessory(m_window)) return { palette.active_window_title(), palette.active_window_border1(), palette.active_window_border2() }; return { palette.inactive_window_title(), palette.inactive_window_border1(), palette.inactive_window_border2() }; } diff --git a/Services/WindowServer/WindowManager.cpp b/Services/WindowServer/WindowManager.cpp index 9addfd4a23..06f218930b 100644 --- a/Services/WindowServer/WindowManager.cpp +++ b/Services/WindowServer/WindowManager.cpp @@ -208,6 +208,27 @@ void WindowManager::move_to_front_and_make_active(Window& window) if (window.is_blocked_by_modal_window()) return; + bool make_active = true; + if (window.is_accessory()) { + if (auto* parent = window.parent_window()) { + do_move_to_front(*parent, true, false); + make_active = false; + + for (auto& accessory_window : parent->accessory_windows()) { + if (accessory_window && accessory_window.ptr() != &window) + do_move_to_front(*accessory_window, false, false); + } + } else { + // If accessory window was unparented, convert to a regular window + window.set_accessory(false); + } + } + + do_move_to_front(window, make_active, true); +} + +void WindowManager::do_move_to_front(Window& window, bool make_active, bool make_input) +{ if (m_windows_in_order.tail() != &window) window.invalidate(); m_windows_in_order.remove(&window); @@ -215,17 +236,20 @@ void WindowManager::move_to_front_and_make_active(Window& window) Compositor::the().recompute_occlusions(); - set_active_window(&window); + if (make_active) + set_active_window(&window, make_input); if (m_switcher.is_visible()) { m_switcher.refresh(); - m_switcher.select_window(window); - set_highlight_window(&window); + if (!window.is_accessory()) { + m_switcher.select_window(window); + set_highlight_window(&window); + } } for (auto& child_window : window.child_windows()) { if (child_window) - move_to_front_and_make_active(*child_window); + do_move_to_front(*child_window, make_active, make_input); } } @@ -234,7 +258,7 @@ void WindowManager::remove_window(Window& window) window.invalidate(); m_windows_in_order.remove(&window); if (window.is_active()) - pick_new_active_window(); + pick_new_active_window(window); if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher) m_switcher.refresh(); @@ -352,7 +376,7 @@ void WindowManager::notify_minimization_state_changed(Window& window) window.client()->post_message(Messages::WindowClient::WindowStateChanged(window.window_id(), window.is_minimized(), window.is_occluded())); if (window.is_active() && window.is_minimized()) - pick_new_active_window(); + pick_new_active_window(window); } void WindowManager::notify_occlusion_state_changed(Window& window) @@ -366,12 +390,14 @@ void WindowManager::notify_progress_changed(Window& window) tell_wm_listeners_window_state_changed(window); } -void WindowManager::pick_new_active_window() +void WindowManager::pick_new_active_window(Window& previous_active) { bool new_window_picked = false; for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, [&](Window& candidate) { - set_active_window(&candidate); - new_window_picked = true; + if (!candidate.is_accessory_of(previous_active)) { + set_active_window(&candidate); + new_window_picked = true; + } return IterationDecision::Break; }); if (!new_window_picked) @@ -846,20 +872,20 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind Window* event_window_with_frame = nullptr; - if (m_active_input_window) { + if (m_active_input_tracking_window) { // At this point, we have delivered the start of an input sequence to a // client application. We must keep delivering to that client // application until the input sequence is done. // // This prevents e.g. moving on one window out of the bounds starting // a move in that other unrelated window, and other silly shenanigans. - if (!windows_who_received_mouse_event_due_to_cursor_tracking.contains(m_active_input_window)) { - auto translated_event = event.translated(-m_active_input_window->position()); - deliver_mouse_event(*m_active_input_window, translated_event); - windows_who_received_mouse_event_due_to_cursor_tracking.set(m_active_input_window.ptr()); + if (!windows_who_received_mouse_event_due_to_cursor_tracking.contains(m_active_input_tracking_window)) { + auto translated_event = event.translated(-m_active_input_tracking_window->position()); + deliver_mouse_event(*m_active_input_tracking_window, translated_event); + windows_who_received_mouse_event_due_to_cursor_tracking.set(m_active_input_tracking_window.ptr()); } if (event.type() == Event::MouseUp && event.buttons() == 0) { - m_active_input_window = nullptr; + m_active_input_tracking_window = nullptr; } for_each_visible_window_from_front_to_back([&](auto& window) { @@ -915,7 +941,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind auto translated_event = event.translated(-window.position()); deliver_mouse_event(window, translated_event); if (event.type() == Event::MouseDown) { - m_active_input_window = window.make_weak_ptr(); + m_active_input_tracking_window = window.make_weak_ptr(); } } return; @@ -1004,45 +1030,45 @@ void WindowManager::event(Core::Event& event) return; } - if (m_active_window) { + if (m_active_input_window) { if (key_event.type() == Event::KeyDown && key_event.modifiers() == Mod_Logo) { if (key_event.key() == Key_Down) { - if (m_active_window->is_resizable() && m_active_window->is_maximized()) { - m_active_window->set_maximized(false); + if (m_active_input_window->is_resizable() && m_active_input_window->is_maximized()) { + m_active_input_window->set_maximized(false); return; } - if (m_active_window->is_minimizable()) - m_active_window->set_minimized(true); + if (m_active_input_window->is_minimizable()) + m_active_input_window->set_minimized(true); return; } - if (m_active_window->is_resizable()) { + if (m_active_input_window->is_resizable()) { if (key_event.key() == Key_Up) { - m_active_window->set_maximized(!m_active_window->is_maximized()); + m_active_input_window->set_maximized(!m_active_input_window->is_maximized()); return; } if (key_event.key() == Key_Left) { - if (m_active_window->tiled() != WindowTileType::None) { - m_active_window->set_tiled(WindowTileType::None); + if (m_active_input_window->tiled() != WindowTileType::None) { + m_active_input_window->set_tiled(WindowTileType::None); return; } - if (m_active_window->is_maximized()) - m_active_window->set_maximized(false); - m_active_window->set_tiled(WindowTileType::Left); + if (m_active_input_window->is_maximized()) + m_active_input_window->set_maximized(false); + m_active_input_window->set_tiled(WindowTileType::Left); return; } if (key_event.key() == Key_Right) { - if (m_active_window->tiled() != WindowTileType::None) { - m_active_window->set_tiled(WindowTileType::None); + if (m_active_input_window->tiled() != WindowTileType::None) { + m_active_input_window->set_tiled(WindowTileType::None); return; } - if (m_active_window->is_maximized()) - m_active_window->set_maximized(false); - m_active_window->set_tiled(WindowTileType::Right); + if (m_active_input_window->is_maximized()) + m_active_input_window->set_maximized(false); + m_active_input_window->set_tiled(WindowTileType::Right); return; } } } - m_active_window->dispatch_event(event); + m_active_input_window->dispatch_event(event); return; } } @@ -1061,12 +1087,30 @@ void WindowManager::set_highlight_window(Window* window) m_highlight_window->invalidate(); } +bool WindowManager::is_active_window_or_accessory(Window& window) const +{ + if (m_active_window == &window) + return true; + + if (!window.is_accessory()) + return false; + + auto* parent = window.parent_window(); + if (!parent) { + // If accessory window was unparented, convert to a regular window + window.set_accessory(false); + return false; + } + + return m_active_window == parent; +} + static bool window_type_can_become_active(WindowType type) { return type == WindowType::Normal || type == WindowType::Desktop; } -void WindowManager::set_active_window(Window* window) +void WindowManager::set_active_window(Window* window, bool make_input) { if (window && window->is_blocked_by_modal_window()) return; @@ -1074,6 +1118,32 @@ void WindowManager::set_active_window(Window* window) if (window && !window_type_can_become_active(window->type())) return; + if (make_input) { + auto* new_active_input_window = window; + if (window && window->is_accessory()) { + if (auto* parent = window->parent_window()) { + // The parent of an accessory window is always the active + // window, but input is routed to the accessory window + window = parent; + } else { + // If accessory window was unparented, convert to a regular window + window->set_accessory(false); + } + } + + if (new_active_input_window != m_active_input_window) { + if (m_active_input_window) + Core::EventLoop::current().post_event(*m_active_input_window, make(Event::WindowInputLeft)); + + if (new_active_input_window) { + m_active_input_window = new_active_input_window->make_weak_ptr(); + Core::EventLoop::current().post_event(*new_active_input_window, make(Event::WindowInputEntered)); + } else { + m_active_input_window = nullptr; + } + } + } + if (window == m_active_window) return; @@ -1087,7 +1157,7 @@ void WindowManager::set_active_window(Window* window) Core::EventLoop::current().post_event(*previously_active_window, make(Event::WindowDeactivated)); previously_active_window->invalidate(); m_active_window = nullptr; - m_active_input_window = nullptr; + m_active_input_tracking_window = nullptr; tell_wm_listeners_window_state_changed(*previously_active_window); } @@ -1236,7 +1306,7 @@ void WindowManager::start_dnd_drag(ClientConnection& client, const String& text, m_dnd_data_type = data_type; m_dnd_data = data; Compositor::the().invalidate_cursor(); - m_active_input_window = nullptr; + m_active_input_tracking_window = nullptr; } void WindowManager::end_dnd_drag() @@ -1288,10 +1358,10 @@ bool WindowManager::update_theme(String theme_path, String theme_name) void WindowManager::did_popup_a_menu(Badge) { // Clear any ongoing input gesture - if (!m_active_input_window) + if (!m_active_input_tracking_window) return; - m_active_input_window->set_automatic_cursor_tracking_enabled(false); - m_active_input_window = nullptr; + m_active_input_tracking_window->set_automatic_cursor_tracking_enabled(false); + m_active_input_tracking_window = nullptr; } } diff --git a/Services/WindowServer/WindowManager.h b/Services/WindowServer/WindowManager.h index 640a719349..89250941c5 100644 --- a/Services/WindowServer/WindowManager.h +++ b/Services/WindowServer/WindowManager.h @@ -145,7 +145,7 @@ public: bool set_resolution(int width, int height); Gfx::IntSize resolution() const; - void set_active_window(Window*); + void set_active_window(Window*, bool make_input = true); void set_hovered_button(Button*); const Button* cursor_tracking_button() const { return m_cursor_tracking_button.ptr(); } @@ -159,6 +159,8 @@ public: void tell_wm_listeners_window_icon_changed(Window&); void tell_wm_listeners_window_rect_changed(Window&); + bool is_active_window_or_accessory(Window&) const; + void start_window_resize(Window&, const Gfx::IntPoint&, MouseButton); void start_window_resize(Window&, const MouseEvent&); @@ -205,7 +207,9 @@ private: void tell_wm_listener_about_window(Window& listener, Window&); void tell_wm_listener_about_window_icon(Window& listener, Window&); void tell_wm_listener_about_window_rect(Window& listener, Window&); - void pick_new_active_window(); + void pick_new_active_window(Window&); + + void do_move_to_front(Window&, bool, bool); RefPtr m_arrow_cursor; RefPtr m_hand_cursor; @@ -262,6 +266,7 @@ private: WeakPtr m_hovered_window; WeakPtr m_highlight_window; WeakPtr m_active_input_window; + WeakPtr m_active_input_tracking_window; WeakPtr m_move_window; Gfx::IntPoint m_move_origin; diff --git a/Services/WindowServer/WindowServer.ipc b/Services/WindowServer/WindowServer.ipc index 8fb0b93318..a0b34bf9ee 100644 --- a/Services/WindowServer/WindowServer.ipc +++ b/Services/WindowServer/WindowServer.ipc @@ -38,6 +38,7 @@ endpoint WindowServer = 2 bool resizable, bool fullscreen, bool frameless, + bool accessory, float opacity, Gfx::IntSize base_size, Gfx::IntSize size_increment,