Skip to content

Commit 9d0e352

Browse files
leolost2605lenemterzeebok
authored
Use WindowPositioner for panel positions (#2109)
Co-authored-by: Leo <[email protected]> Co-authored-by: Ryan Kornheisl <[email protected]>
1 parent 58e5b42 commit 9d0e352

File tree

5 files changed

+104
-136
lines changed

5 files changed

+104
-136
lines changed

src/PantheonShell.vala

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,7 @@ namespace Gala {
243243
return;
244244
}
245245

246-
Meta.Side side = TOP;
247-
switch (anchor) {
248-
case TOP:
249-
break;
250-
251-
case BOTTOM:
252-
side = BOTTOM;
253-
break;
254-
255-
case LEFT:
256-
side = LEFT;
257-
break;
258-
259-
case RIGHT:
260-
side = RIGHT;
261-
break;
262-
}
263-
264-
ShellClientsManager.get_instance ().set_anchor (window, side);
246+
ShellClientsManager.get_instance ().set_anchor (window, anchor);
265247
}
266248

267249
internal static void focus_panel (Wl.Client client, Wl.Resource resource) {

src/ShellClients/HideTracker.vala

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,7 @@ public class Gala.HideTracker : Object {
1616
public Meta.Display display { get; construct; }
1717
public unowned PanelWindow panel { get; construct; }
1818

19-
private Pantheon.Desktop.HideMode _hide_mode = NEVER;
20-
public Pantheon.Desktop.HideMode hide_mode {
21-
get {
22-
return _hide_mode;
23-
}
24-
set {
25-
_hide_mode = value;
26-
27-
setup_barrier ();
28-
}
29-
}
19+
public Pantheon.Desktop.HideMode hide_mode { get; set; }
3020

3121
private Clutter.PanAction pan_action;
3222

@@ -97,6 +87,16 @@ public class Gala.HideTracker : Object {
9787
pan_action.pan.connect (on_pan);
9888

9989
display.get_stage ().add_action_full ("panel-swipe-gesture", CAPTURE, pan_action);
90+
91+
panel.notify["anchor"].connect (setup_barrier);
92+
93+
var monitor_manager = display.get_context ().get_backend ().get_monitor_manager ();
94+
monitor_manager.monitors_changed.connect (() => {
95+
setup_barrier (); //Make sure barriers are still on the primary monitor
96+
schedule_update ();
97+
});
98+
99+
setup_barrier ();
100100
}
101101

102102
#if !HAS_MUTTER45
@@ -171,7 +171,7 @@ public class Gala.HideTracker : Object {
171171
continue;
172172
}
173173

174-
if (!panel.get_custom_window_rect ().overlap (window.get_frame_rect ())) {
174+
if (!panel.window.get_frame_rect ().overlap (window.get_frame_rect ())) {
175175
continue;
176176
}
177177

src/ShellClients/PanelWindow.vala

Lines changed: 30 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,21 @@ public class Gala.PanelWindow : Object {
1010

1111
public WindowManager wm { get; construct; }
1212
public Meta.Window window { get; construct; }
13+
public Pantheon.Desktop.Anchor anchor { get; construct set; }
1314

14-
public bool hidden { get; private set; default = false; }
15-
16-
public Meta.Side anchor;
15+
private WindowPositioner window_positioner;
1716

1817
private PanelClone clone;
1918

20-
private uint idle_move_id = 0;
21-
2219
private int width = -1;
2320
private int height = -1;
2421

25-
public PanelWindow (WindowManager wm, Meta.Window window, Meta.Side anchor) {
26-
Object (wm: wm, window: window);
27-
28-
// Meta.Side seems to be currently not supported as GLib.Object property ...?
29-
// At least it always crashed for me with some paramspec, g_type_fundamental backtrace
30-
this.anchor = anchor;
22+
public PanelWindow (WindowManager wm, Meta.Window window, Pantheon.Desktop.Anchor anchor) {
23+
Object (wm: wm, window: window, anchor: anchor);
3124
}
3225

3326
construct {
34-
window.size_changed.connect (position_window);
35-
3627
window.unmanaging.connect (() => {
37-
if (idle_move_id != 0) {
38-
Source.remove (idle_move_id);
39-
}
40-
4128
if (window_struts.remove (window)) {
4229
update_struts ();
4330
}
@@ -47,13 +34,18 @@ public class Gala.PanelWindow : Object {
4734

4835
clone = new PanelClone (wm, this);
4936

50-
var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager ();
51-
monitor_manager.monitors_changed.connect (() => update_anchor (anchor));
52-
monitor_manager.monitors_changed_internal.connect (() => update_anchor (anchor));
37+
unowned var display = wm.get_display ();
5338

54-
var workspace_manager = wm.get_display ().get_workspace_manager ();
39+
unowned var workspace_manager = display.get_workspace_manager ();
5540
workspace_manager.workspace_added.connect (update_strut);
5641
workspace_manager.workspace_removed.connect (update_strut);
42+
43+
window.size_changed.connect (update_strut);
44+
window.position_changed.connect (update_strut);
45+
46+
window_positioner = new WindowPositioner (display, window, WindowPositioner.Position.from_anchor (anchor));
47+
48+
notify["anchor"].connect (() => window_positioner.position = WindowPositioner.Position.from_anchor (anchor));
5749
}
5850

5951
#if HAS_MUTTER45
@@ -83,73 +75,9 @@ public class Gala.PanelWindow : Object {
8375
this.width = width;
8476
this.height = height;
8577

86-
position_window ();
87-
set_hide_mode (clone.hide_mode); // Resetup barriers etc.
88-
}
89-
90-
public void update_anchor (Meta.Side anchor) {
91-
this.anchor = anchor;
92-
93-
position_window ();
94-
set_hide_mode (clone.hide_mode); // Resetup barriers etc.
95-
}
96-
97-
private void position_window () {
98-
var display = wm.get_display ();
99-
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
100-
var window_rect = window.get_frame_rect ();
101-
102-
switch (anchor) {
103-
case TOP:
104-
position_window_top (monitor_geom, window_rect);
105-
break;
106-
107-
case BOTTOM:
108-
position_window_bottom (monitor_geom, window_rect);
109-
break;
110-
111-
default:
112-
warning ("Side not supported yet");
113-
break;
114-
}
115-
11678
update_strut ();
11779
}
11880

119-
#if HAS_MUTTER45
120-
private void position_window_top (Mtk.Rectangle monitor_geom, Mtk.Rectangle window_rect) {
121-
#else
122-
private void position_window_top (Meta.Rectangle monitor_geom, Meta.Rectangle window_rect) {
123-
#endif
124-
var x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
125-
126-
move_window_idle (x, monitor_geom.y);
127-
}
128-
129-
#if HAS_MUTTER45
130-
private void position_window_bottom (Mtk.Rectangle monitor_geom, Mtk.Rectangle window_rect) {
131-
#else
132-
private void position_window_bottom (Meta.Rectangle monitor_geom, Meta.Rectangle window_rect) {
133-
#endif
134-
var x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
135-
var y = monitor_geom.y + monitor_geom.height - window_rect.height;
136-
137-
move_window_idle (x, y);
138-
}
139-
140-
private void move_window_idle (int x, int y) {
141-
if (idle_move_id != 0) {
142-
Source.remove (idle_move_id);
143-
}
144-
145-
idle_move_id = Idle.add (() => {
146-
window.move_frame (false, x, y);
147-
148-
idle_move_id = 0;
149-
return Source.REMOVE;
150-
});
151-
}
152-
15381
public void set_hide_mode (Pantheon.Desktop.HideMode hide_mode) {
15482
clone.hide_mode = hide_mode;
15583

@@ -173,7 +101,7 @@ public class Gala.PanelWindow : Object {
173101

174102
Meta.Strut strut = {
175103
rect,
176-
anchor
104+
side_from_anchor (anchor)
177105
};
178106

179107
window_struts[window] = strut;
@@ -199,4 +127,20 @@ public class Gala.PanelWindow : Object {
199127
update_struts ();
200128
}
201129
}
130+
131+
private Meta.Side side_from_anchor (Pantheon.Desktop.Anchor anchor) {
132+
switch (anchor) {
133+
case BOTTOM:
134+
return BOTTOM;
135+
136+
case LEFT:
137+
return LEFT;
138+
139+
case RIGHT:
140+
return RIGHT;
141+
142+
default:
143+
return TOP;
144+
}
145+
}
202146
}

src/ShellClients/ShellClientsManager.vala

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,16 @@ public class Gala.ShellClientsManager : Object {
143143
xdisplay.change_property (x_window, atom, (X.Atom) 4, 32, 0, (uchar[]) dock_atom, 1);
144144
}
145145

146-
public void set_anchor (Meta.Window window, Meta.Side side) {
146+
public void set_anchor (Meta.Window window, Pantheon.Desktop.Anchor anchor) {
147147
if (window in panel_windows) {
148-
panel_windows[window].update_anchor (side);
148+
panel_windows[window].anchor = anchor;
149149
return;
150150
}
151151

152152
make_dock (window);
153153
// TODO: Return if requested by window that's not a trusted client?
154154

155-
panel_windows[window] = new PanelWindow (wm, window, side);
155+
panel_windows[window] = new PanelWindow (wm, window, anchor);
156156

157157
// connect_after so we make sure the PanelWindow can destroy its barriers and struts
158158
window.unmanaging.connect_after ((_window) => panel_windows.remove (_window));
@@ -226,8 +226,30 @@ public class Gala.ShellClientsManager : Object {
226226

227227
switch (key) {
228228
case "anchor":
229-
int parsed; // Will be used as Meta.Side which is a 4 value bitfield so check bounds for that
230-
if (int.try_parse (val, out parsed) && 0 <= parsed && parsed <= 15) {
229+
int meta_side_parsed; // Will be used as Meta.Side which is a 4 value bitfield so check bounds for that
230+
if (int.try_parse (val, out meta_side_parsed) && 0 <= meta_side_parsed && meta_side_parsed <= 15) {
231+
//FIXME: Next major release change dock and wingpanel calls to get rid of this
232+
Pantheon.Desktop.Anchor parsed = TOP;
233+
switch ((Meta.Side) meta_side_parsed) {
234+
case BOTTOM:
235+
parsed = BOTTOM;
236+
break;
237+
238+
case LEFT:
239+
parsed = LEFT;
240+
break;
241+
242+
case RIGHT:
243+
parsed = RIGHT;
244+
break;
245+
246+
default:
247+
break;
248+
}
249+
250+
set_anchor (window, parsed);
251+
// We need to set a second time because the intention is to call this before the window is shown which it is on wayland
252+
// but on X the window was already shown when we get here so we have to call again to instantly apply it.
231253
set_anchor (window, parsed);
232254
} else {
233255
warning ("Failed to parse %s as anchor", val);

src/ShellClients/WindowPositioner.vala

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,28 @@
77

88
public class Gala.WindowPositioner : Object {
99
public enum Position {
10-
CENTER
10+
TOP,
11+
BOTTOM,
12+
CENTER;
13+
14+
public static Position from_anchor (Pantheon.Desktop.Anchor anchor) {
15+
if (anchor > 1) {
16+
warning ("Position %s not supported yet", anchor.to_string ());
17+
return CENTER;
18+
}
19+
20+
return (Position) anchor;
21+
}
1122
}
1223

1324
public Meta.Display display { get; construct; }
1425
public Meta.Window window { get; construct; }
15-
public Position position { get; private set; }
16-
public Variant? position_data { get; private set; }
26+
/**
27+
* This may only be set after the window was shown.
28+
* The initial position should only be given in the constructor.
29+
*/
30+
public Position position { get; construct set; }
31+
public Variant? position_data { get; construct set; }
1732

1833
public WindowPositioner (Meta.Display display, Meta.Window window, Position position, Variant? position_data = null) {
1934
Object (display: display, window: window, position: position, position_data: position_data);
@@ -29,29 +44,34 @@ public class Gala.WindowPositioner : Object {
2944
unowned var monitor_manager = display.get_context ().get_backend ().get_monitor_manager ();
3045
monitor_manager.monitors_changed.connect (position_window);
3146
monitor_manager.monitors_changed_internal.connect (position_window);
32-
}
3347

34-
/**
35-
* This may only be called after the window was shown.
36-
*/
37-
public void update_position (Position new_position, Variant? new_position_data = null) {
38-
position = new_position;
39-
position_data = new_position_data;
40-
41-
position_window ();
48+
notify["position"].connect (position_window);
49+
notify["position-data"].connect (position_window);
4250
}
4351

4452
private void position_window () {
4553
int x = 0, y = 0;
4654

55+
var window_rect = window.get_frame_rect ();
56+
4757
switch (position) {
4858
case CENTER:
4959
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
50-
var window_rect = window.get_frame_rect ();
51-
5260
x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
5361
y = monitor_geom.y + (monitor_geom.height - window_rect.height) / 2;
5462
break;
63+
64+
case TOP:
65+
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
66+
x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
67+
y = monitor_geom.y;
68+
break;
69+
70+
case BOTTOM:
71+
var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ());
72+
x = monitor_geom.x + (monitor_geom.width - window_rect.width) / 2;
73+
y = monitor_geom.y + monitor_geom.height - window_rect.height;
74+
break;
5575
}
5676

5777
window.move_frame (false, x, y);

0 commit comments

Comments
 (0)