-
-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathPanelWindow.vala
More file actions
149 lines (115 loc) · 4.6 KB
/
PanelWindow.vala
File metadata and controls
149 lines (115 loc) · 4.6 KB
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
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
*/
public class GreeterCompositor.PanelWindow : ShellWindow {
private static HashTable<Meta.Window, Meta.Strut?> window_struts = new HashTable<Meta.Window, Meta.Strut?> (null, null);
public WindowManager wm { get; construct; }
public Pantheon.Desktop.Anchor anchor { get; construct set; }
private int width = -1;
private int height = -1;
public PanelWindow (WindowManager wm, Meta.Window window, Pantheon.Desktop.Anchor anchor) {
Object (wm: wm, window: window, anchor: anchor);
}
construct {
window.unmanaging.connect (() => {
if (window_struts.remove (window)) {
update_struts ();
}
});
notify["anchor"].connect (position_window);
unowned var workspace_manager = window.display.get_workspace_manager ();
workspace_manager.workspace_added.connect (update_strut);
workspace_manager.workspace_removed.connect (update_strut);
window.size_changed.connect (update_strut);
window.position_changed.connect (update_strut);
notify["width"].connect (update_strut);
notify["height"].connect (update_strut);
var window_actor = (Meta.WindowActor) window.get_compositor_private ();
window_actor.notify["width"].connect (update_clip);
window_actor.notify["height"].connect (update_clip);
window_actor.notify["translation-y"].connect (update_clip);
notify["anchor"].connect (update_clip);
}
public Mtk.Rectangle get_custom_window_rect () {
var window_rect = window.get_frame_rect ();
if (width > 0) {
window_rect.width = width;
}
if (height > 0) {
window_rect.height = height;
if (anchor == BOTTOM) {
var geom = wm.get_display ().get_monitor_geometry (window.get_monitor ());
window_rect.y = geom.y + geom.height - height;
}
}
return window_rect;
}
public void set_size (int width, int height) {
this.width = width;
this.height = height;
update_strut ();
}
private void update_strut () {
var rect = get_custom_window_rect ();
Meta.Strut strut = {
rect,
side_from_anchor (anchor)
};
window_struts[window] = strut;
update_struts ();
}
private void update_struts () {
var list = new SList<Meta.Strut?> ();
foreach (var window_strut in window_struts.get_values ()) {
list.append (window_strut);
}
foreach (var workspace in wm.get_display ().get_workspace_manager ().get_workspaces ()) {
workspace.set_builtin_struts (list);
}
}
private Meta.Side side_from_anchor (Pantheon.Desktop.Anchor anchor) {
switch (anchor) {
case BOTTOM:
return BOTTOM;
case LEFT:
return LEFT;
case RIGHT:
return RIGHT;
default:
return TOP;
}
}
protected override void get_window_position (Mtk.Rectangle window_rect, out int x, out int y) {
var monitor_rect = window.display.get_monitor_geometry (window.display.get_primary_monitor ());
switch (anchor) {
case TOP:
x = monitor_rect.x + (monitor_rect.width - window_rect.width) / 2;
y = monitor_rect.y;
break;
case BOTTOM:
x = monitor_rect.x + (monitor_rect.width - window_rect.width) / 2;
y = monitor_rect.y + monitor_rect.height - window_rect.height;
break;
default:
warning ("Unsupported anchor %s for PanelWindow", anchor.to_string ());
x = 0;
y = 0;
break;
}
}
private void update_clip () {
var monitor_geom = window.display.get_monitor_geometry (window.get_monitor ());
var window_actor = (Meta.WindowActor) window.get_compositor_private ();
var y = window_actor.y + window_actor.translation_y;
if (y + window_actor.height > monitor_geom.y + monitor_geom.height) {
window_actor.set_clip (0, 0, window_actor.width, monitor_geom.y + monitor_geom.height - y);
} else if (y < monitor_geom.y) {
window_actor.set_clip (0, monitor_geom.y - y, window_actor.width, window_actor.height);
} else {
window_actor.remove_clip ();
}
}
}