Skip to content

Commit 4d8dde4

Browse files
committed
Use WindowPositioner for panel positions
1 parent 0e149e4 commit 4d8dde4

File tree

5 files changed

+104
-135
lines changed

5 files changed

+104
-135
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

@@ -93,6 +83,16 @@ public class Gala.HideTracker : Object {
9383
pan_action.pan.connect (on_pan);
9484

9585
display.get_stage ().add_action_full ("panel-swipe-gesture", CAPTURE, pan_action);
86+
87+
panel.notify["anchor"].connect (setup_barrier);
88+
89+
var monitor_manager = display.get_context ().get_backend ().get_monitor_manager ();
90+
monitor_manager.monitors_changed.connect (() => {
91+
setup_barrier (); //Make sure barriers are still on the primary monitor
92+
schedule_update ();
93+
});
94+
95+
setup_barrier ();
9696
}
9797

9898
//Can be removed with mutter > 45
@@ -166,7 +166,7 @@ public class Gala.HideTracker : Object {
166166
continue;
167167
}
168168

169-
if (!panel.get_custom_window_rect ().overlap (window.get_frame_rect ())) {
169+
if (!panel.window.get_frame_rect ().overlap (window.get_frame_rect ())) {
170170
continue;
171171
}
172172

src/ShellClients/PanelWindow.vala

Lines changed: 30 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,21 @@ public class Gala.PanelWindow : Object {
1111
public WindowManager wm { get; construct; }
1212
public Meta.Window window { get; construct; }
1313

14-
public bool hidden { get; private set; default = false; }
14+
public Pantheon.Desktop.Anchor anchor { get; construct set; }
1515

16-
public Meta.Side anchor;
16+
private WindowPositioner window_positioner;
1717

1818
private PanelClone clone;
1919

20-
private uint idle_move_id = 0;
21-
2220
private int width = -1;
2321
private int height = -1;
2422

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;
23+
public PanelWindow (WindowManager wm, Meta.Window window, Pantheon.Desktop.Anchor anchor) {
24+
Object (wm: wm, window: window, anchor: anchor);
3125
}
3226

3327
construct {
34-
window.size_changed.connect (position_window);
35-
3628
window.unmanaging.connect (() => {
37-
if (idle_move_id != 0) {
38-
Source.remove (idle_move_id);
39-
}
40-
4129
if (window_struts.remove (window)) {
4230
update_struts ();
4331
}
@@ -47,13 +35,18 @@ public class Gala.PanelWindow : Object {
4735

4836
clone = new PanelClone (wm, this);
4937

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));
38+
var display = wm.get_display ();
5339

54-
var workspace_manager = wm.get_display ().get_workspace_manager ();
40+
var workspace_manager = display.get_workspace_manager ();
5541
workspace_manager.workspace_added.connect (update_strut);
5642
workspace_manager.workspace_removed.connect (update_strut);
43+
44+
window.size_changed.connect (update_strut);
45+
window.position_changed.connect (update_strut);
46+
47+
window_positioner = new WindowPositioner (display, window, WindowPositioner.Position.from_anchor (anchor));
48+
49+
notify["anchor"].connect (() => window_positioner.position = WindowPositioner.Position.from_anchor (anchor));
5750
}
5851

5952
#if HAS_MUTTER45
@@ -83,73 +76,9 @@ public class Gala.PanelWindow : Object {
8376
this.width = width;
8477
this.height = height;
8578

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-
11679
update_strut ();
11780
}
11881

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-
15382
public void set_hide_mode (Pantheon.Desktop.HideMode hide_mode) {
15483
clone.hide_mode = hide_mode;
15584

@@ -173,7 +102,7 @@ public class Gala.PanelWindow : Object {
173102

174103
Meta.Strut strut = {
175104
rect,
176-
anchor
105+
side_from_anchor (anchor)
177106
};
178107

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

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)