File: tiling_window_manager.h

package info (click to toggle)
mir 2.20.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,636 kB
  • sloc: cpp: 174,574; xml: 13,422; ansic: 8,221; python: 1,337; sh: 874; makefile: 216; javascript: 37
file content (135 lines) | stat: -rw-r--r-- 5,285 bytes parent folder | download
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
/*
 * Copyright © Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 or 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MIRAL_SHELL_TILING_WINDOW_MANAGER_H
#define MIRAL_SHELL_TILING_WINDOW_MANAGER_H

#include "sw_splash.h"

#include <miral/application.h>
#include <miral/window_management_policy.h>
#include <miral/window_manager_tools.h>

#include <mir/geometry/displacement.h>
#include <miral/internal_client.h>

#include <mir_toolkit/events/enums.h>

#include <functional>
#include <vector>

using namespace mir::geometry;

// Demonstrate implementing a simple tiling algorithm

// simple tiling algorithm:
//  o Switch apps: tap or click on the corresponding tile
//  o Move window: Alt-leftmousebutton drag (three finger drag)
//  o Resize window: Alt-middle_button drag (four finger drag)
//  o Maximize/restore current window (to tile size): Alt-F11
//  o Maximize/restore current window (to tile height): Shift-F11
//  o Maximize/restore current window (to tile width): Ctrl-F11
//  o client requests to maximize, vertically maximize & restore
class TilingWindowManagerPolicy
    : public miral::WindowManagementPolicy
{
public:
    explicit TilingWindowManagerPolicy(miral::WindowManagerTools const& tools, std::shared_ptr<SplashSession> const& spinner,
        miral::InternalClientLauncher const& launcher);

    auto place_new_window(
        miral::ApplicationInfo const& app_info,
        miral::WindowSpecification const& request_parameters)
        -> miral::WindowSpecification override;

    void handle_window_ready(miral::WindowInfo& window_info) override;
    void handle_modify_window(miral::WindowInfo& window_info, miral::WindowSpecification const& modifications) override;
    bool handle_keyboard_event(MirKeyboardEvent const* event) override;
    bool handle_touch_event(MirTouchEvent const* event) override;
    bool handle_pointer_event(MirPointerEvent const* event) override;
    void handle_raise_window(miral::WindowInfo& window_info) override;

    void advise_end() override;

    void advise_new_window(miral::WindowInfo const& window_info) override;
    void advise_focus_gained(miral::WindowInfo const& info) override;
    void advise_new_app(miral::ApplicationInfo& application) override;
    void advise_delete_app(miral::ApplicationInfo const& application) override;

    void handle_request_move(miral::WindowInfo& window_info, MirInputEvent const* input_event) override;
    void handle_request_resize(miral::WindowInfo& window_info, MirInputEvent const* input_event, MirResizeEdge edge) override;

    auto confirm_inherited_move(miral::WindowInfo const& window_info, Displacement movement) -> Rectangle override;

    Rectangle confirm_placement_on_display(const miral::WindowInfo& window_info, MirWindowState new_state,
        Rectangle const& new_placement) override;

private:
    void advise_application_zone_create(miral::Zone const& zone) override;
    void advise_application_zone_update(miral::Zone const& updated, miral::Zone const& original) override;
    void advise_application_zone_delete(miral::Zone const& zone) override;

    static const int modifier_mask =
        mir_input_event_modifier_alt |
        mir_input_event_modifier_shift |
        mir_input_event_modifier_sym |
        mir_input_event_modifier_ctrl |
        mir_input_event_modifier_meta;

    void click(Point cursor);
    void resize(Point cursor);
    void drag(Point cursor);
    void toggle(MirWindowState state);

    miral::Application application_under(Point position);

    void update_tiles(Rectangles const& outputs);
    void update_surfaces(miral::ApplicationInfo& info, Rectangle const& old_tile, Rectangle const& new_tile);

    auto transform_set_state(MirWindowState value) -> MirWindowState;

    static void clip_to_tile(miral::WindowSpecification& parameters, Rectangle const& tile);
    static void resize(miral::Window window, Point cursor, Point old_cursor, Rectangle bounds);

    void constrain_size_and_place(miral::WindowSpecification& mods, miral::Window const& window, Rectangle const& tile) const;

    miral::WindowManagerTools tools;
    std::shared_ptr<SplashSession> spinner;
    miral::InternalClientLauncher const launcher;
    Point old_cursor{};
    Rectangles displays;
    bool dirty_tiles = false;

    class MRUTileList
    {
    public:

        void push(std::shared_ptr<void> const& tile);
        void erase(std::shared_ptr<void> const& tile);

        using Enumerator = std::function<void(std::shared_ptr<void> const& tile)>;

        void enumerate(Enumerator const& enumerator) const;
        auto count() -> size_t { return tiles.size(); }

    private:
        std::vector<std::shared_ptr<void>> tiles;
    };

    MRUTileList tiles;
};

#endif /* MIRAL_SHELL_TILING_WINDOW_MANAGER_H */