summaryrefslogtreecommitdiff
path: root/Servers/WindowServer/WSWindow.h
blob: 951a11f3498e6c4d43b48eed89a2d80fd64ae93a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#pragma once

#include <AK/InlineLinkedList.h>
#include <AK/String.h>
#include <LibCore/CObject.h>
#include <LibDraw/DisjointRectSet.h>
#include <LibDraw/GraphicsBitmap.h>
#include <LibDraw/Rect.h>
#include <WindowServer/WSWindowFrame.h>
#include <WindowServer/WSWindowType.h>

class WSClientConnection;
class WSCursor;
class WSMenu;
class WSMouseEvent;

enum WSWMEventMask {
    WindowRectChanges = 1 << 0,
    WindowStateChanges = 1 << 1,
    WindowIconChanges = 1 << 2,
    WindowRemovals = 1 << 3,
};

enum class WindowTileType {
    None = 0,
    Left,
    Right,
};

class WSWindow final : public CObject
    , public InlineLinkedListNode<WSWindow> {
    C_OBJECT(WSWindow)
public:
    WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool resizable, bool fullscreen);
    WSWindow(CObject&, WSWindowType);
    virtual ~WSWindow() override;

    void popup_window_menu(const Point&);
    void request_close();

    unsigned wm_event_mask() const { return m_wm_event_mask; }
    void set_wm_event_mask(unsigned mask) { m_wm_event_mask = mask; }

    bool is_minimized() const { return m_minimized; }
    void set_minimized(bool);

    bool is_maximized() const { return m_maximized; }
    void set_maximized(bool);

    bool is_fullscreen() const { return m_fullscreen; }
    void set_fullscreen(bool);

    WindowTileType tiled() const { return m_tiled; }
    void set_tiled(WindowTileType);

    bool is_occluded() const { return m_occluded; }
    void set_occluded(bool);

    bool show_titlebar() const { return m_show_titlebar; }
    void set_show_titlebar(bool show) { m_show_titlebar = show; }

    bool is_movable() const
    {
        return m_type == WSWindowType::Normal;
    }

    WSWindowFrame& frame() { return m_frame; }
    const WSWindowFrame& frame() const { return m_frame; }

    bool is_blocked_by_modal_window() const;

    bool listens_to_wm_events() const { return m_listens_to_wm_events; }

    WSClientConnection* client() { return m_client; }
    const WSClientConnection* client() const { return m_client; }

    WSWindowType type() const { return m_type; }
    int window_id() const { return m_window_id; }

    String title() const { return m_title; }
    void set_title(const String&);

    float opacity() const { return m_opacity; }
    void set_opacity(float);

    int x() const { return m_rect.x(); }
    int y() const { return m_rect.y(); }
    int width() const { return m_rect.width(); }
    int height() const { return m_rect.height(); }

    bool is_active() const;

    bool is_visible() const { return m_visible; }
    void set_visible(bool);

    bool is_modal() const { return m_modal; }

    bool is_resizable() const { return m_resizable && !m_fullscreen; }

    Rect rect() const { return m_rect; }
    void set_rect(const Rect&);
    void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); }
    void set_rect_without_repaint(const Rect& rect)
    {
        if (m_rect == rect)
            return;
        auto old_rect = m_rect;
        m_rect = rect;
        m_frame.notify_window_rect_changed(old_rect, rect);
    }

    void set_rect_from_window_manager_resize(const Rect&);

    void set_taskbar_rect(const Rect& rect) { m_taskbar_rect = rect; }
    const Rect& taskbar_rect() const { return m_taskbar_rect; }

    void move_to(const Point& position) { set_rect({ position, size() }); }
    void move_to(int x, int y) { move_to({ x, y }); }

    Point position() const { return m_rect.location(); }
    void set_position(const Point& position) { set_rect({ position.x(), position.y(), width(), height() }); }
    void set_position_without_repaint(const Point& position) { set_rect_without_repaint({ position.x(), position.y(), width(), height() }); }

    Size size() const { return m_rect.size(); }

    void invalidate();
    void invalidate(const Rect&);

    virtual void event(CEvent&) override;

    // Only used by WSWindowType::MenuApplet. Perhaps it could be a WSWindow subclass? I don't know.
    void set_rect_in_menubar(const Rect& rect) { m_rect_in_menubar = rect; }
    const Rect& rect_in_menubar() const { return m_rect_in_menubar; }

    const GraphicsBitmap* backing_store() const { return m_backing_store.ptr(); }
    GraphicsBitmap* backing_store() { return m_backing_store.ptr(); }

    void set_backing_store(RefPtr<GraphicsBitmap>&& backing_store)
    {
        m_last_backing_store = move(m_backing_store);
        m_backing_store = move(backing_store);
    }

    void swap_backing_stores()
    {
        swap(m_backing_store, m_last_backing_store);
    }

    GraphicsBitmap* last_backing_store() { return m_last_backing_store.ptr(); }

    void set_global_cursor_tracking_enabled(bool);
    void set_automatic_cursor_tracking_enabled(bool enabled) { m_automatic_cursor_tracking_enabled = enabled; }
    bool global_cursor_tracking() const { return m_global_cursor_tracking_enabled || m_automatic_cursor_tracking_enabled; }

    bool has_alpha_channel() const { return m_has_alpha_channel; }
    void set_has_alpha_channel(bool value) { m_has_alpha_channel = value; }

    Size size_increment() const { return m_size_increment; }
    void set_size_increment(const Size& increment) { m_size_increment = increment; }

    Size base_size() const { return m_base_size; }
    void set_base_size(const Size& size) { m_base_size = size; }

    const GraphicsBitmap& icon() const { return *m_icon; }
    void set_icon(NonnullRefPtr<GraphicsBitmap>&& icon) { m_icon = move(icon); }

    void set_default_icon();

    const WSCursor* override_cursor() const { return m_override_cursor.ptr(); }
    void set_override_cursor(RefPtr<WSCursor>&& cursor) { m_override_cursor = move(cursor); }

    void request_update(const Rect&);
    DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }

    bool in_minimize_animation() const { return m_minimize_animation_step != -1; }

    int minimize_animation_index() const { return m_minimize_animation_step; }
    void step_minimize_animation() { m_minimize_animation_step += 1; }
    void start_minimize_animation() { m_minimize_animation_step = 0; }
    void end_minimize_animation() { m_minimize_animation_step = -1; }

    // For InlineLinkedList.
    // FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that.
    WSWindow* m_next { nullptr };
    WSWindow* m_prev { nullptr };

private:
    void handle_mouse_event(const WSMouseEvent&);

    WSClientConnection* m_client { nullptr };
    String m_title;
    Rect m_rect;
    Rect m_saved_nonfullscreen_rect;
    Rect m_taskbar_rect;
    WSWindowType m_type { WSWindowType::Normal };
    bool m_global_cursor_tracking_enabled { false };
    bool m_automatic_cursor_tracking_enabled { false };
    bool m_visible { true };
    bool m_has_alpha_channel { false };
    bool m_modal { false };
    bool m_resizable { false };
    bool m_listens_to_wm_events { false };
    bool m_minimized { false };
    bool m_maximized { false };
    bool m_fullscreen { false };
    WindowTileType m_tiled { WindowTileType::None };
    Rect m_untiled_rect;
    bool m_occluded { false };
    bool m_show_titlebar { true };
    RefPtr<GraphicsBitmap> m_backing_store;
    RefPtr<GraphicsBitmap> m_last_backing_store;
    int m_window_id { -1 };
    float m_opacity { 1 };
    Size m_size_increment;
    Size m_base_size;
    NonnullRefPtr<GraphicsBitmap> m_icon;
    RefPtr<WSCursor> m_override_cursor;
    WSWindowFrame m_frame;
    unsigned m_wm_event_mask { 0 };
    DisjointRectSet m_pending_paint_rects;
    Rect m_unmaximized_rect;
    Rect m_rect_in_menubar;
    RefPtr<WSMenu> m_window_menu;
    int m_minimize_animation_step { -1 };
};