Skip to content

Commit 9976838

Browse files
committed
Use WindowPositioner for panel positions
1 parent f21d780 commit 9976838

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

@@ -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 & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,22 @@ 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
public DelegateActor delegate_actor;
1919
private PanelClone clone;
2020

21-
private uint idle_move_id = 0;
22-
2321
private int width = -1;
2422
private int height = -1;
2523

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

3428
construct {
35-
window.size_changed.connect (position_window);
36-
3729
window.unmanaging.connect (() => {
38-
if (idle_move_id != 0) {
39-
Source.remove (idle_move_id);
40-
}
41-
4230
if (window_struts.remove (window)) {
4331
update_struts ();
4432
}
@@ -49,13 +37,18 @@ public class Gala.PanelWindow : Object {
4937
delegate_actor = new DelegateActor ((Meta.WindowActor) window.get_compositor_private ());
5038
clone = new PanelClone (wm, this);
5139

52-
var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager ();
53-
monitor_manager.monitors_changed.connect (() => update_anchor (anchor));
54-
monitor_manager.monitors_changed_internal.connect (() => update_anchor (anchor));
40+
var display = wm.get_display ();
5541

56-
var workspace_manager = wm.get_display ().get_workspace_manager ();
42+
var workspace_manager = display.get_workspace_manager ();
5743
workspace_manager.workspace_added.connect (update_strut);
5844
workspace_manager.workspace_removed.connect (update_strut);
45+
46+
window.size_changed.connect (update_strut);
47+
window.position_changed.connect (update_strut);
48+
49+
window_positioner = new WindowPositioner (display, window, WindowPositioner.Position.from_anchor (anchor));
50+
51+
notify["anchor"].connect (() => window_positioner.position = WindowPositioner.Position.from_anchor (anchor));
5952
}
6053

6154
#if HAS_MUTTER45
@@ -87,73 +80,9 @@ public class Gala.PanelWindow : Object {
8780
this.width = width;
8881
this.height = height;
8982

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

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

@@ -177,7 +106,7 @@ public class Gala.PanelWindow : Object {
177106

178107
Meta.Strut strut = {
179108
rect,
180-
anchor
109+
side_from_anchor (anchor)
181110
};
182111

183112
window_struts[window] = strut;
@@ -203,4 +132,20 @@ public class Gala.PanelWindow : Object {
203132
update_struts ();
204133
}
205134
}
135+
136+
private Meta.Side side_from_anchor (Pantheon.Desktop.Anchor anchor) {
137+
switch (anchor) {
138+
case BOTTOM:
139+
return BOTTOM;
140+
141+
case LEFT:
142+
return LEFT;
143+
144+
case RIGHT:
145+
return RIGHT;
146+
147+
default:
148+
return TOP;
149+
}
150+
}
206151
}

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)