summaryrefslogtreecommitdiff
path: root/Services/WindowServer/WindowManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'Services/WindowServer/WindowManager.h')
-rw-r--r--Services/WindowServer/WindowManager.h479
1 files changed, 0 insertions, 479 deletions
diff --git a/Services/WindowServer/WindowManager.h b/Services/WindowServer/WindowManager.h
deleted file mode 100644
index 94e1f212d7..0000000000
--- a/Services/WindowServer/WindowManager.h
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/HashMap.h>
-#include <AK/HashTable.h>
-#include <AK/InlineLinkedList.h>
-#include <AK/WeakPtr.h>
-#include <LibCore/ConfigFile.h>
-#include <LibCore/ElapsedTimer.h>
-#include <LibGfx/Color.h>
-#include <LibGfx/DisjointRectSet.h>
-#include <LibGfx/Painter.h>
-#include <LibGfx/Palette.h>
-#include <LibGfx/Rect.h>
-#include <WindowServer/Cursor.h>
-#include <WindowServer/Event.h>
-#include <WindowServer/MenuBar.h>
-#include <WindowServer/MenuManager.h>
-#include <WindowServer/Window.h>
-#include <WindowServer/WindowSwitcher.h>
-#include <WindowServer/WindowType.h>
-
-namespace WindowServer {
-
-class Screen;
-class MouseEvent;
-class Window;
-class ClientConnection;
-class WindowSwitcher;
-class Button;
-
-enum class ResizeDirection {
- None,
- Left,
- UpLeft,
- Up,
- UpRight,
- Right,
- DownRight,
- Down,
- DownLeft
-};
-
-class WindowManager : public Core::Object {
- C_OBJECT(WindowManager)
-
- friend class Compositor;
- friend class WindowFrame;
- friend class WindowSwitcher;
-
-public:
- static WindowManager& the();
-
- explicit WindowManager(const Gfx::PaletteImpl&);
- virtual ~WindowManager() override;
-
- Palette palette() const { return Palette(*m_palette); }
-
- RefPtr<Core::ConfigFile> config() const { return m_config; }
- void reload_config(bool);
-
- void add_window(Window&);
- void remove_window(Window&);
-
- void notify_title_changed(Window&);
- void notify_modal_unparented(Window&);
- void notify_rect_changed(Window&, const Gfx::IntRect& oldRect, const Gfx::IntRect& newRect);
- void notify_minimization_state_changed(Window&);
- void notify_opacity_changed(Window&);
- void notify_occlusion_state_changed(Window&);
- void notify_progress_changed(Window&);
- void notify_client_changed_app_menubar(ClientConnection&);
-
- Gfx::IntRect maximized_window_rect(const Window&) const;
-
- const ClientConnection* dnd_client() const { return m_dnd_client.ptr(); }
- const String& dnd_text() const { return m_dnd_text; }
- const Core::MimeData& dnd_mime_data() const { return *m_dnd_mime_data; }
- const Gfx::Bitmap* dnd_bitmap() const { return m_dnd_bitmap; }
- Gfx::IntRect dnd_rect() const;
-
- void start_dnd_drag(ClientConnection&, const String& text, Gfx::Bitmap*, const Core::MimeData&);
- void end_dnd_drag();
-
- Window* active_window() { return m_active_window.ptr(); }
- const Window* active_window() const { return m_active_window.ptr(); }
- Window* active_input_window() { return m_active_input_window.ptr(); }
- const Window* active_input_window() const { return m_active_input_window.ptr(); }
- const ClientConnection* active_client() const;
-
- const Window* highlight_window() const { return m_highlight_window.ptr(); }
- void set_highlight_window(Window*);
-
- void move_to_front_and_make_active(Window&);
-
- Gfx::IntRect menubar_rect() const;
- Gfx::IntRect desktop_rect() const;
-
- const Cursor& active_cursor() const;
- const Cursor& hidden_cursor() const { return *m_hidden_cursor; }
- const Cursor& arrow_cursor() const { return *m_arrow_cursor; }
- const Cursor& crosshair_cursor() const { return *m_crosshair_cursor; }
- const Cursor& hand_cursor() const { return *m_hand_cursor; }
- const Cursor& help_cursor() const { return *m_help_cursor; }
- const Cursor& resize_horizontally_cursor() const { return *m_resize_horizontally_cursor; }
- const Cursor& resize_vertically_cursor() const { return *m_resize_vertically_cursor; }
- const Cursor& resize_diagonally_tlbr_cursor() const { return *m_resize_diagonally_tlbr_cursor; }
- const Cursor& resize_diagonally_bltr_cursor() const { return *m_resize_diagonally_bltr_cursor; }
- const Cursor& resize_column_cursor() const { return *m_resize_column_cursor; }
- const Cursor& resize_row_cursor() const { return *m_resize_row_cursor; }
- const Cursor& i_beam_cursor() const { return *m_i_beam_cursor; }
- const Cursor& disallowed_cursor() const { return *m_disallowed_cursor; }
- const Cursor& move_cursor() const { return *m_move_cursor; }
- const Cursor& drag_cursor() const { return *m_drag_cursor; }
- const Cursor& wait_cursor() const { return *m_wait_cursor; }
-
- const Gfx::Font& font() const;
- const Gfx::Font& window_title_font() const;
-
- bool set_resolution(int width, int height);
- Gfx::IntSize resolution() const;
-
- void set_acceleration_factor(double);
- void set_scroll_step_size(unsigned);
-
- Window* set_active_input_window(Window*);
- void restore_active_input_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(); }
- void set_cursor_tracking_button(Button*);
-
- void set_resize_candidate(Window&, ResizeDirection);
- void clear_resize_candidate();
- ResizeDirection resize_direction_of_window(const Window&);
-
- void tell_wm_listeners_window_state_changed(Window&);
- 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&);
-
- const Window* active_fullscreen_window() const
- {
- if (m_active_window && m_active_window->is_fullscreen()) {
- return m_active_window;
- }
- return nullptr;
- };
-
- Window* active_fullscreen_window()
- {
- if (m_active_window && m_active_window->is_fullscreen()) {
- return m_active_window;
- }
- return nullptr;
- }
-
- bool update_theme(String theme_path, String theme_name);
-
- void set_hovered_window(Window*);
- void deliver_mouse_event(Window& window, MouseEvent& event);
-
- void did_popup_a_menu(Badge<Menu>);
-
- void start_menu_doubleclick(Window& window, const MouseEvent& event);
- bool is_menu_doubleclick(Window& window, const MouseEvent& event) const;
-
- void minimize_windows(Window&, bool);
- void maximize_windows(Window&, bool);
-
- template<typename Function>
- IterationDecision for_each_window_in_modal_stack(Window& window, Function f)
- {
- auto* blocking_modal_window = window.blocking_modal_window();
- if (blocking_modal_window || window.is_modal()) {
- Vector<Window*> modal_stack;
- auto* modal_stack_top = blocking_modal_window ? blocking_modal_window : &window;
- for (auto* parent = modal_stack_top->parent_window(); parent; parent = parent->parent_window()) {
- auto* blocked_by = parent->blocking_modal_window();
- if (!blocked_by || (blocked_by != modal_stack_top && !modal_stack_top->is_descendant_of(*blocked_by)))
- break;
- modal_stack.append(parent);
- if (!parent->is_modal())
- break;
- }
- if (!modal_stack.is_empty()) {
- for (size_t i = modal_stack.size(); i > 0; i--) {
- IterationDecision decision = f(*modal_stack[i - 1], false);
- if (decision != IterationDecision::Continue)
- return decision;
- }
- }
- return f(*modal_stack_top, true);
- } else {
- // Not a modal window stack, just "iterate" over this window
- return f(window, true);
- }
- }
-
- Gfx::IntPoint get_recommended_window_position(const Gfx::IntPoint& desired);
-
-private:
- NonnullRefPtr<Cursor> get_cursor(const String& name);
-
- void process_mouse_event(MouseEvent&, Window*& hovered_window);
- void process_event_for_doubleclick(Window& window, MouseEvent& event);
- bool process_ongoing_window_resize(const MouseEvent&, Window*& hovered_window);
- bool process_ongoing_window_move(MouseEvent&, Window*& hovered_window);
- bool process_ongoing_drag(MouseEvent&, Window*& hovered_window);
- void start_window_move(Window&, const MouseEvent&);
- template<typename Callback>
- IterationDecision for_each_visible_window_of_type_from_back_to_front(WindowType, Callback, bool ignore_highlight = false);
- template<typename Callback>
- IterationDecision for_each_visible_window_of_type_from_front_to_back(WindowType, Callback, bool ignore_highlight = false);
- template<typename Callback>
- IterationDecision for_each_visible_window_from_front_to_back(Callback);
- template<typename Callback>
- IterationDecision for_each_visible_window_from_back_to_front(Callback);
- template<typename Callback>
- void for_each_window_listening_to_wm_events(Callback);
- template<typename Callback>
- void for_each_window(Callback);
- template<typename Callback>
- IterationDecision for_each_window_of_type_from_front_to_back(WindowType, Callback, bool ignore_highlight = false);
-
- virtual void event(Core::Event&) override;
- void paint_window_frame(const Window&);
- 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&);
- bool pick_new_active_window(Window*);
-
- void do_move_to_front(Window&, bool, bool);
-
- RefPtr<Cursor> m_hidden_cursor;
- RefPtr<Cursor> m_arrow_cursor;
- RefPtr<Cursor> m_hand_cursor;
- RefPtr<Cursor> m_help_cursor;
- RefPtr<Cursor> m_resize_horizontally_cursor;
- RefPtr<Cursor> m_resize_vertically_cursor;
- RefPtr<Cursor> m_resize_diagonally_tlbr_cursor;
- RefPtr<Cursor> m_resize_diagonally_bltr_cursor;
- RefPtr<Cursor> m_resize_column_cursor;
- RefPtr<Cursor> m_resize_row_cursor;
- RefPtr<Cursor> m_i_beam_cursor;
- RefPtr<Cursor> m_disallowed_cursor;
- RefPtr<Cursor> m_move_cursor;
- RefPtr<Cursor> m_drag_cursor;
- RefPtr<Cursor> m_wait_cursor;
- RefPtr<Cursor> m_crosshair_cursor;
-
- InlineLinkedList<Window> m_windows_in_order;
-
- struct DoubleClickInfo {
- struct ClickMetadata {
- Core::ElapsedTimer clock;
- Gfx::IntPoint last_position;
- };
-
- const ClickMetadata& metadata_for_button(MouseButton) const;
- ClickMetadata& metadata_for_button(MouseButton);
-
- void reset()
- {
- m_left = {};
- m_right = {};
- m_middle = {};
- m_back = {};
- m_forward = {};
- }
-
- WeakPtr<Window> m_clicked_window;
-
- private:
- ClickMetadata m_left;
- ClickMetadata m_right;
- ClickMetadata m_middle;
- ClickMetadata m_back;
- ClickMetadata m_forward;
- };
-
- bool is_considered_doubleclick(const MouseEvent& event, const DoubleClickInfo::ClickMetadata& metadata) const;
-
- DoubleClickInfo m_double_click_info;
- int m_double_click_speed { 0 };
- int m_max_distance_for_double_click { 4 };
-
- WeakPtr<Window> m_active_window;
- WeakPtr<Window> m_hovered_window;
- WeakPtr<Window> m_highlight_window;
- WeakPtr<Window> m_active_input_window;
- WeakPtr<Window> m_active_input_tracking_window;
-
- WeakPtr<Window> m_move_window;
- Gfx::IntPoint m_move_origin;
- Gfx::IntPoint m_move_window_origin;
-
- WeakPtr<Window> m_resize_window;
- WeakPtr<Window> m_resize_candidate;
- MouseButton m_resizing_mouse_button { MouseButton::None };
- Gfx::IntRect m_resize_window_original_rect;
- Gfx::IntPoint m_resize_origin;
- ResizeDirection m_resize_direction { ResizeDirection::None };
-
- u8 m_keyboard_modifiers { 0 };
-
- WindowSwitcher m_switcher;
-
- WeakPtr<Button> m_cursor_tracking_button;
- WeakPtr<Button> m_hovered_button;
-
- NonnullRefPtr<Gfx::PaletteImpl> m_palette;
-
- RefPtr<Core::ConfigFile> m_config;
-
- WeakPtr<ClientConnection> m_dnd_client;
- String m_dnd_text;
- RefPtr<Core::MimeData> m_dnd_mime_data;
- RefPtr<Gfx::Bitmap> m_dnd_bitmap;
-};
-
-template<typename Callback>
-IterationDecision WindowManager::for_each_visible_window_of_type_from_back_to_front(WindowType type, Callback callback, bool ignore_highlight)
-{
- bool do_highlight_window_at_end = false;
- for (auto& window : m_windows_in_order) {
- if (!window.is_visible())
- continue;
- if (window.is_minimized())
- continue;
- if (window.type() != type)
- continue;
- if (!ignore_highlight && m_highlight_window == &window) {
- do_highlight_window_at_end = true;
- continue;
- }
- if (callback(window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
- if (do_highlight_window_at_end) {
- if (callback(*m_highlight_window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
- return IterationDecision::Continue;
-}
-
-template<typename Callback>
-IterationDecision WindowManager::for_each_visible_window_from_back_to_front(Callback callback)
-{
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Desktop, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Normal, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Taskbar, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Notification, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Tooltip, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Menubar, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_back_to_front(WindowType::Menu, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- return for_each_visible_window_of_type_from_back_to_front(WindowType::WindowSwitcher, callback);
-}
-
-template<typename Callback>
-IterationDecision WindowManager::for_each_visible_window_of_type_from_front_to_back(WindowType type, Callback callback, bool ignore_highlight)
-{
- if (!ignore_highlight && m_highlight_window && m_highlight_window->type() == type && m_highlight_window->is_visible()) {
- if (callback(*m_highlight_window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
-
- for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
- if (!window->is_visible())
- continue;
- if (window->is_minimized())
- continue;
- if (window->type() != type)
- continue;
- if (!ignore_highlight && window == m_highlight_window)
- continue;
- if (callback(*window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
- return IterationDecision::Continue;
-}
-
-template<typename Callback>
-IterationDecision WindowManager::for_each_visible_window_from_front_to_back(Callback callback)
-{
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::WindowSwitcher, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Menu, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Menubar, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Tooltip, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Notification, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Taskbar, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- if (for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, callback) == IterationDecision::Break)
- return IterationDecision::Break;
- return for_each_visible_window_of_type_from_front_to_back(WindowType::Desktop, callback);
-}
-
-template<typename Callback>
-void WindowManager::for_each_window_listening_to_wm_events(Callback callback)
-{
- for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
- if (!window->listens_to_wm_events())
- continue;
- if (callback(*window) == IterationDecision::Break)
- return;
- }
-}
-
-template<typename Callback>
-void WindowManager::for_each_window(Callback callback)
-{
- for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
- if (callback(*window) == IterationDecision::Break)
- return;
- }
-}
-
-template<typename Callback>
-IterationDecision WindowManager::for_each_window_of_type_from_front_to_back(WindowType type, Callback callback, bool ignore_highlight)
-{
- if (!ignore_highlight && m_highlight_window && m_highlight_window->type() == type && m_highlight_window->is_visible()) {
- if (callback(*m_highlight_window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
-
- for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
- if (window->type() != type)
- continue;
- if (!ignore_highlight && window == m_highlight_window)
- continue;
- if (callback(*window) == IterationDecision::Break)
- return IterationDecision::Break;
- }
- return IterationDecision::Continue;
-}
-
-}