Merge lp:~docky-core/plank/respect-struts into lp:plank

Proposed by Rico Tzschichholz
Status: Work in progress
Proposed branch: lp:~docky-core/plank/respect-struts
Merge into: lp:plank
Diff against target: 415 lines (+242/-27)
1 file modified
lib/PositionManager.vala (+242/-27)
To merge this branch: bzr merge lp:~docky-core/plank/respect-struts
Reviewer Review Type Date Requested Status
Docky Core Pending
Review via email: mp+255871@code.launchpad.net

This proposal supersedes a proposal from 2013-10-27.

Description of the change

Make plank avoid taking up reserved space by other potential panel/dock windows.

"get_work_area ()" will get called once per start and on monitor/resolution-changes. So there are no performance concerns. To force an update plank will have to be restarted currently. Ideally we should watch for new/removed struts on runtime.

Taking the struts of other already running panels/dock into account will result in positioning plank inside this restricted area on the chosen monitor. If you chose an edge which is already taken by another panel/dock it will be stacked on top of it and working normal from there on.

To post a comment you must log in.
Revision history for this message
Robert Dyer (psybers) wrote : Posted in a previous version of this proposal

What happens if the dock is 'stacked on top' of another dock/panel, and also set to autohide? Wouldn't there be a 1 pixel tall area to trigger a reveal, and that 1 pixel area is floating away from an edge and pretty much impossible to hit?

review: Needs Information
Revision history for this message
Robert Dyer (psybers) wrote : Posted in a previous version of this proposal

You update the foreign struts on a delay - what happens if you wait for another dock/panel to set their struts, then we find those, update our geo (thereby possibly setting our own struts depending on hide mode), which may trigger the *other* dock to update their own struts etc? Will they possibly get into some odd behavior where they are constantly re-triggering each other's positioning code?

review: Needs Information
Revision history for this message
Rico Tzschichholz (ricotz) wrote : Posted in a previous version of this proposal

> What happens if the dock is 'stacked on top' of another dock/panel, and also
> set to autohide? Wouldn't there be a 1 pixel tall area to trigger a reveal,
> and that 1 pixel area is floating away from an edge and pretty much impossible
> to hit?

That is pretty much what is expected to happen now, yeah.

Revision history for this message
Rico Tzschichholz (ricotz) wrote : Posted in a previous version of this proposal

> You update the foreign struts on a delay - what happens if you wait for
> another dock/panel to set their struts, then we find those, update our geo
> (thereby possibly setting our own struts depending on hide mode), which may
> trigger the *other* dock to update their own struts etc? Will they possibly
> get into some odd behavior where they are constantly re-triggering each
> other's positioning code?

It only looks for new windows and their possible struts, so it will find already "started" docks/panels and those which will appear later. Strut-changes of open windows are not discovered and therefore not handled.

Revision history for this message
Robert Dyer (psybers) wrote : Posted in a previous version of this proposal

> > What happens if the dock is 'stacked on top' of another dock/panel, and also
> > set to autohide? Wouldn't there be a 1 pixel tall area to trigger a reveal,
> > and that 1 pixel area is floating away from an edge and pretty much
> impossible
> > to hit?
>
> That is pretty much what is expected to happen now, yeah.

This behavior won't suffice. What if the cursor area was extended from the dock's '1 pixel' line all the way to the nearest screen edge?

review: Needs Fixing
lp:~docky-core/plank/respect-struts updated
1247. By Rico Tzschichholz

lib: Make the Preferences menu-item visible in Pantheon too

1248. By Rico Tzschichholz

Update symbols

1249. By Rico Tzschichholz

Add some hidden menu-items for easier debugging

1250. By Rico Tzschichholz

dockwindow: Fix build with gee-1.0

1251. By Rico Tzschichholz

coverage-html: Make sure to reference files located in builddir

1252. By Rico Tzschichholz

Prepare 0.9.0 release

1253. By Rico Tzschichholz

Back to development

1254. By Rico Tzschichholz

src: Initialize i18n as suggested

1255. By Rico Tzschichholz

vapi: Add libbamf3.deps

1256. By Rico Tzschichholz

HACKING: Mention ppa:docky-core/stable containing release builds

1257. By Rico Tzschichholz

po: Update translations

1258. By Rico Tzschichholz

renderer: Make sure to unhide the dock on login when there are no windows

After transparently filling window on start-up make sure to force a
redraw and a following unhide animation.

1259. By Rico Tzschichholz

controller: launchers_folder is not a public/construct property

1260. By Rico Tzschichholz

lib: Explictly request/specify the FileMonitor-type which is needed

1261. By Rico Tzschichholz

po: Update translations

1262. By Rico Tzschichholz

The 'This file is part of Plank' commit

Add references to 'Plank' in copyright-headers where possible.

1263. By Rico Tzschichholz

Add LGPL v2.1 for "TitledSeparatorMenuItem.vala"

1264. By Rico Tzschichholz

Use Cairo.Operator.CLEAR instead of Cairo.Operator.SOURCE/set_source_rgba

1265. By Rico Tzschichholz

docksurface: Cache "Context" property

1266. By Rico Tzschichholz

defaultprovider: Use add_items instead of add_item_without_signaling

1267. By Rico Tzschichholz

dockcontainer: Synchronize Add-/RemoveTime with existing child-items

1268. By Rico Tzschichholz

renderer: Don't add-animate an item if its container got added later

E.g. this avoids animating *all* items on startup.

1269. By Rico Tzschichholz

renderer: Split-out item_animation_needed()

1270. By Rico Tzschichholz

dragmanager: Tweak internal callbacks

1271. By Rico Tzschichholz

renderer: Fix typos in documentation

1272. By Rico Tzschichholz

dockelement: Use Gdk.BUTTON_* constants

1273. By Rico Tzschichholz

dockitem: Start icon-file-monitor as soon as possible if needed

1274. By Rico Tzschichholz

Prepare 0.9.1 release

1275. By Rico Tzschichholz

Back to development

1276. By Rico Tzschichholz

poofwindow: Retrieve size and frame-count from given animation-file

1277. By Danielle Foré

data: New and more detailed poof animation with 8 frames

1278. By Rico Tzschichholz

items: Collect item-related enums in their own source-file

1279. By Rico Tzschichholz

dockcontainer: Add prepend_item()

1280. By Rico Tzschichholz

Allow DockItems to be added to the DockController directly

1281. By Rico Tzschichholz

Make "Item for Dock" really special and add setting to show/hide it

1282. By Rico Tzschichholz

items: Refactor public API to reflect its generality

1283. By Rico Tzschichholz

Automatically remove invalid items and their corresponding dockitem-file

Additionally to the validity check of dockitem-files invalid one will be
deleted. On runtime indicate broken-items and remove them after 3 seconds
without further actions needed.

1284. By Rico Tzschichholz

items: Pass-through the event_time of click/scroll events if available

This will result in passing proper timestamps to Wnck-based calls.

1285. By Rico Tzschichholz

renderer: Make hide-animation non-linear and default to 250ms

1286. By Rico Tzschichholz

drawing: Small optimization in ar_scale()

1287. By Rico Tzschichholz

docksurface: Cache kernel[k] in gaussian_blur_*

1288. By Rico Tzschichholz

logger: Adjust LogLevel-naming, ERROR -> CRITICAL and FATAL -> ERROR

1289. By Rico Tzschichholz

items: Make DockItem abstract

1290. By Rico Tzschichholz

dockitem: Use dedicated callback to handle icon-file-changes

1291. By Rico Tzschichholz

controller: No need to specialize default-provider as AppDockItemProvider

1292. By Rico Tzschichholz

preferences: GLib.File.replace() is creating non-existing files already

1293. By Rico Tzschichholz

lib: Simplify initialization of some structs

"var f = Foo ()" will cause a superfluous memset.
"Foo f = {0}" will additionally set the first field (if it is an integer)
and doesn't translate to C-equivalent.

1294. By Rico Tzschichholz

positionmanager: Use Gdk.Rectangle.union()

This additionally catches the case where first_rect is actually located
on the "right" of last_rect.

1295. By Rico Tzschichholz

po: Update translations

1296. By Rico Tzschichholz

theme: Small clean up of draw_background()

1297. By Rico Tzschichholz

build: Fix autoconf warning about ignoring --datarootdir

1298. By Rico Tzschichholz

po: Update translations

1299. By Rico Tzschichholz

services: Add ThreadPool-based Worker to run tasks without blocking GUI

1300. By Rico Tzschichholz

filedockitem: Use Worker to load and draw file-icons for pinned folders

1301. By Rico Tzschichholz

dragmanager: Update drag-icon if the drag-item's icon got changed

1302. By Rico Tzschichholz

worker: Add asynchronous add_task_with_result()

1303. By Rico Tzschichholz

items: Use threaded icon-drawing for all item and add draw_icon_fast()

Makes use of Worker.add_task_with_result().

Prevent foreground and background drawing until the final icon is done.

draw_icon_fast() will be used before the real icon is ready.
It allows items to draw a specific shape for a smoother transitions
between placeholder and final icon.

1304. By Rico Tzschichholz

abstractmain: Force "deep" initializtion of Gtk.IconTheme early

1305. By Rico Tzschichholz

abstractmain: Bail early if this is not running in a X11 session

1306. By Rico Tzschichholz

Update symbols

1307. By Rico Tzschichholz

build: Fix docs build

1308. By Rico Tzschichholz

worker: Schedule async-callback with priority HIGH_IDLE

1309. By Rico Tzschichholz

dockitem: Rework threaded-drawing of internal surface

1310. By Rico Tzschichholz

drawing: Use Gtk.IconTheme in a thread-safe way

1311. By Rico Tzschichholz

lib: Avoid some superfluous string-copying

1312. By Rico Tzschichholz

dockitem: Add the "surface == null" surface-status

1313. By Rico Tzschichholz

logger: Partial rewrite, with strip down to the "nearly" bare minimum

1314. By Rico Tzschichholz

worker: Make ThreadPool non-exclusive and use GLib.get_num_processors()

1315. By Rico Tzschichholz

filedockitem: Drop unused code

1316. By Rico Tzschichholz

build: Fix make distcheck

1317. By Rico Tzschichholz

drawingservice: Use string-array directly and don't copy to Gee.ArrayList

1318. By Rico Tzschichholz

po: Update translations

1319. By Rico Tzschichholz

src: Use more reasonable class-name and namespace-structure

1320. By Rico Tzschichholz

renderer: Schedule unhide-on-start callback "as late as possible"

1321. By Rico Tzschichholz

dockitem: Schedule icon-theme-changed callback "as late as possible"

1322. By Rico Tzschichholz

drawingservice: Make icon_theme creation thread-safe

1323. By Rico Tzschichholz

renderer: Move frame-time handling into AnimatedRenderer

Make AnimatedRenderer-class responsible to perform and schedule redraws.

1324. By Rico Tzschichholz

animatedrenderer: Use Gdk.FrameClock to determine frame-time

Conditionally use Gdk.FrameClock if Gtk+ >= 3.8 is available

1325. By Rico Tzschichholz

Revert "items: Use threaded icon-drawing for all items"

Too unstable for being usable!

1326. By Rico Tzschichholz

Add RTL support and enable it depending on the locale setting

Reverse items placement.
Mirror position for vertical docks.
Invert alignments for horizonzal docks.
Mirror badge and progress-bar.

1327. By Rico Tzschichholz

po: Update translations

1328. By Rico Tzschichholz

animatedrenderer: Always initialize frame if a redraw is scheduled

1329. By Rico Tzschichholz

po: Update translations

1330. By Rico Tzschichholz

dockrenderer: Guard duration-calculations which are used for animations

1331. By Rico Tzschichholz

Update symbols

1332. By Rico Tzschichholz

color: Avoid double setting of out-vars in hsv_to_rgb

1333. By Rico Tzschichholz

color: Clarify documention of set_min/max_* methods

1334. By Rico Tzschichholz

hidemanager: Add dodge-active hide-mode

1335. By Rico Tzschichholz

prefswindow: Use Gtk.Stack if available

1336. By Rico Tzschichholz

build: Drop dependency on gnome-common

1337. By Rico Tzschichholz

prefswindow: Allow closing the window using "Escape"

1338. By Rico Tzschichholz

po: Update translations

1339. By Rico Tzschichholz

ui: Tweak minimum gtk+ version for conditional 3.4 support

1340. By Rico Tzschichholz

build: Make sure to enable maintainer-mode by default

1341. By Rico Tzschichholz

Add icon-zoom preferences and expose gui-settings

1342. By Rico Tzschichholz

Add optional zoom animation when hovering dock-items

1343. By Rico Tzschichholz

Add ability to cache multiple sizes of drawn items

1344. By Rico Tzschichholz

Update symbols

1345. By Rico Tzschichholz

po: Update translation template

1346. By Rico Tzschichholz

surfacecache: Add missing mutex-unlock

1347. By Rico Tzschichholz

po: Update translations

1348. By Rico Tzschichholz

lib: Make sure to bind "plank" textdomain for library users

1349. By Rico Tzschichholz

lib: Replace non-constant string-concatenation with string.printf()

1350. By Rico Tzschichholz

positionmanager: Respect struts set by other windows

Make plank avoid taking up reserved space by other potential panel/dock
windows.

1351. By Rico Tzschichholz

WIP

Unmerged revisions

1351. By Rico Tzschichholz

WIP

1350. By Rico Tzschichholz

positionmanager: Respect struts set by other windows

Make plank avoid taking up reserved space by other potential panel/dock
windows.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/PositionManager.vala'
2--- lib/PositionManager.vala 2015-07-02 10:31:07 +0000
3+++ lib/PositionManager.vala 2015-07-21 19:23:43 +0000
4@@ -21,6 +21,7 @@
5 using Plank.Drawing;
6 using Plank.Services;
7 using Plank.Services.Windows;
8+using Plank.Widgets;
9
10 namespace Plank
11 {
12@@ -142,6 +143,21 @@
13 }
14 }
15
16+ struct Strut {
17+ ulong left;
18+ ulong right;
19+ ulong top;
20+ ulong bottom;
21+ ulong left_start;
22+ ulong left_end;
23+ ulong right_start;
24+ ulong right_end;
25+ ulong top_start;
26+ ulong top_end;
27+ ulong bottom_start;
28+ ulong bottom_end;
29+ }
30+
31 public DockController controller { private get; construct; }
32
33 public bool screen_is_composited { get; private set; }
34@@ -150,8 +166,11 @@
35 Gee.HashMap<DockElement, DockItemDrawValue> draw_values;
36
37 Gdk.Rectangle monitor_geo;
38+ Gdk.Rectangle work_area;
39
40 int window_scale_factor = 1;
41+
42+ Gee.HashMap<ulong, Strut?> foreign_struts;
43
44 /**
45 * Creates a new position manager.
46@@ -167,6 +186,7 @@
47 {
48 static_dock_region = {};
49 draw_values = new Gee.HashMap<DockElement, DockItemDrawValue> ();
50+ foreign_struts = new Gee.HashMap<ulong, Strut?> ();
51
52 controller.prefs.notify.connect (prefs_changed);
53 }
54@@ -178,6 +198,7 @@
55 requires (controller.window != null)
56 {
57 unowned Gdk.Screen screen = controller.window.get_screen ();
58+ unowned Wnck.Screen wnck_screen = Wnck.Screen.get_default ();
59
60 screen.monitors_changed.connect (screen_changed);
61 screen.size_changed.connect (screen_changed);
62@@ -186,6 +207,13 @@
63 // NOTE don't call update_monitor_geo to avoid a double-call of dockwindow.set_size on startup
64 screen.get_monitor_geometry (find_monitor_number (screen, controller.prefs.Monitor), out monitor_geo);
65
66+ init_foreign_struts ();
67+ wnck_screen.window_opened.connect (foreign_struts_add);
68+ wnck_screen.window_closed.connect (foreign_struts_remove);
69+
70+ work_area = get_work_area ();
71+ print ("%i,%i-%ix%i\n", work_area.x, work_area.y, work_area.width, work_area.height);
72+
73 screen_is_composited = screen.is_composited ();
74 }
75
76@@ -261,6 +289,10 @@
77
78 freeze_notify ();
79
80+ init_foreign_struts ();
81+ work_area = get_work_area ();
82+ print ("%i,%i-%ix%i\n", work_area.x, work_area.y, work_area.width, work_area.height);
83+
84 update_dimensions ();
85 update_regions ();
86
87@@ -519,7 +551,7 @@
88 // Check if the dock is oversized and doesn't fit the targeted screen-edge
89 var item_count = controller.VisibleItems.size;
90 var width = item_count * (ItemPadding + IconSize) + 2 * HorizPadding + 4 * LineWidth;
91- var max_width = (is_horizontal_dock () ? monitor_geo.width : monitor_geo.height);
92+ var max_width = (is_horizontal_dock () ? work_area.width : work_area.height);
93 var step_size = int.max (1, (int) (Math.fabs (width - max_width) / item_count));
94
95 if (width > max_width && MaxIconSize > DockPreferences.MIN_ICON_SIZE) {
96@@ -565,9 +597,9 @@
97 break;
98 case Gtk.Align.FILL:
99 if (is_horizontal_dock ())
100- width = monitor_geo.width;
101+ width = work_area.width;
102 else
103- width = monitor_geo.height;
104+ width = work_area.height;
105 break;
106 }
107
108@@ -579,23 +611,23 @@
109 width -= 2 * HorizPadding;
110
111 if (is_horizontal_dock ()) {
112- width = int.min (monitor_geo.width, width);
113+ width = int.min (work_area.width, width);
114 VisibleDockHeight = height;
115 VisibleDockWidth = width;
116 DockHeight = dock_height;
117- DockWidth = (screen_is_composited ? monitor_geo.width : width);
118+ DockWidth = (screen_is_composited ? work_area.width : width);
119 DockBackgroundHeight = background_height;
120 DockBackgroundWidth = background_width;
121- MaxItemCount = (int) Math.floor ((double) (monitor_geo.width - 2 * HorizPadding + 4 * LineWidth) / (ItemPadding + IconSize));
122+ MaxItemCount = (int) Math.floor ((double) (work_area.width - 2 * HorizPadding + 4 * LineWidth) / (ItemPadding + IconSize));
123 } else {
124- width = int.min (monitor_geo.height, width);
125+ width = int.min (work_area.height, width);
126 VisibleDockHeight = width;
127 VisibleDockWidth = height;
128- DockHeight = (screen_is_composited ? monitor_geo.height : width);
129+ DockHeight = (screen_is_composited ? work_area.height : width);
130 DockWidth = dock_height;
131 DockBackgroundHeight = background_width;
132 DockBackgroundWidth = background_height;
133- MaxItemCount = (int) Math.floor ((double) (monitor_geo.height - 2 * HorizPadding + 4 * LineWidth) / (ItemPadding + IconSize));
134+ MaxItemCount = (int) Math.floor ((double) (work_area.height - 2 * HorizPadding + 4 * LineWidth) / (ItemPadding + IconSize));
135 }
136 }
137
138@@ -720,19 +752,19 @@
139 case Gtk.Align.START:
140 if (is_horizontal_dock ()) {
141 xoffset = 0;
142- yoffset = (monitor_geo.height - static_dock_region.height);
143+ yoffset = (work_area.height - static_dock_region.height);
144 } else {
145- xoffset = (monitor_geo.width - static_dock_region.width);
146+ xoffset = (work_area.width - static_dock_region.width);
147 yoffset = 0;
148 }
149 break;
150 case Gtk.Align.END:
151 if (is_horizontal_dock ()) {
152- xoffset = (monitor_geo.width - static_dock_region.width);
153+ xoffset = (work_area.width - static_dock_region.width);
154 yoffset = 0;
155 } else {
156 xoffset = 0;
157- yoffset = (monitor_geo.height - static_dock_region.height);
158+ yoffset = (work_area.height - static_dock_region.height);
159 }
160 break;
161 }
162@@ -1263,8 +1295,8 @@
163
164 if (!screen_is_composited) {
165 var offset = Offset;
166- xoffset = (int) ((1 + offset / 100.0) * (monitor_geo.width - DockWidth) / 2);
167- yoffset = (int) ((1 + offset / 100.0) * (monitor_geo.height - DockHeight) / 2);
168+ xoffset = (int) ((1 + offset / 100.0) * (work_area.width - DockWidth) / 2);
169+ yoffset = (int) ((1 + offset / 100.0) * (work_area.height - DockHeight) / 2);
170
171 switch (Alignment) {
172 default:
173@@ -1274,19 +1306,19 @@
174 case Gtk.Align.START:
175 if (is_horizontal_dock ()) {
176 xoffset = 0;
177- yoffset = (monitor_geo.height - static_dock_region.height);
178+ yoffset = (work_area.height - static_dock_region.height);
179 } else {
180- xoffset = (monitor_geo.width - static_dock_region.width);
181+ xoffset = (work_area.width - static_dock_region.width);
182 yoffset = 0;
183 }
184 break;
185 case Gtk.Align.END:
186 if (is_horizontal_dock ()) {
187- xoffset = (monitor_geo.width - static_dock_region.width);
188+ xoffset = (work_area.width - static_dock_region.width);
189 yoffset = 0;
190 } else {
191 xoffset = 0;
192- yoffset = (monitor_geo.height - static_dock_region.height);
193+ yoffset = (work_area.height - static_dock_region.height);
194 }
195 break;
196 }
197@@ -1295,20 +1327,20 @@
198 switch (Position) {
199 default:
200 case Gtk.PositionType.BOTTOM:
201- win_x = monitor_geo.x + xoffset;
202- win_y = monitor_geo.y + monitor_geo.height - DockHeight;
203+ win_x = work_area.x + xoffset;
204+ win_y = work_area.y + work_area.height - DockHeight;
205 break;
206 case Gtk.PositionType.TOP:
207- win_x = monitor_geo.x + xoffset;
208- win_y = monitor_geo.y;
209+ win_x = work_area.x + xoffset;
210+ win_y = work_area.y;
211 break;
212 case Gtk.PositionType.LEFT:
213- win_y = monitor_geo.y + yoffset;
214- win_x = monitor_geo.x;
215+ win_y = work_area.y + yoffset;
216+ win_x = work_area.x;
217 break;
218 case Gtk.PositionType.RIGHT:
219- win_y = monitor_geo.y + yoffset;
220- win_x = monitor_geo.x + monitor_geo.width - DockWidth;
221+ win_y = work_area.y + yoffset;
222+ win_x = work_area.x + work_area.width - DockWidth;
223 break;
224 }
225
226@@ -1506,6 +1538,189 @@
227 return { x, y, 0, 0 };
228 }
229
230+ Gdk.Rectangle get_work_area ()
231+ {
232+ if (foreign_struts.size <= 0)
233+ return monitor_geo;
234+
235+ var result = monitor_geo;
236+
237+ Gdk.Rectangle rect;
238+
239+ foreach (var strut in foreign_struts.values) {
240+ Gdk.Rectangle left = { monitor_geo.x,
241+ monitor_geo.y + (int) strut.left_start,
242+ (int) strut.left,
243+ (int) (strut.left_end - strut.left_start) };
244+
245+ if (result.intersect (left, out rect)) {
246+ result.x = left.width;
247+ result.width -= left.width;
248+ }
249+
250+ Gdk.Rectangle right = { monitor_geo.x + monitor_geo.width - (int) strut.right,
251+ monitor_geo.y + (int) strut.right_start,
252+ (int) strut.right,
253+ (int) (strut.right_end - strut.right_start) };
254+
255+ if (result.intersect (right, out rect))
256+ result.width = right.x - result.x;
257+
258+ Gdk.Rectangle top = { monitor_geo.x + (int) strut.top_start,
259+ monitor_geo.y,
260+ (int) (strut.top_end - strut.top_start),
261+ (int) strut.top };
262+
263+ if (result.intersect (top, out rect)) {
264+ result.y = top.height;
265+ result.height -= top.height;
266+ }
267+
268+ Gdk.Rectangle bottom = { monitor_geo.x + (int) strut.bottom_start,
269+ monitor_geo.y + monitor_geo.height - (int) strut.bottom,
270+ (int) (strut.bottom_end - strut.bottom_start),
271+ (int) strut.bottom };
272+
273+ if (result.intersect (bottom, out rect))
274+ result.height = bottom.y - result.y;
275+ }
276+
277+ print ("%i,%i-%ix%i\n", result.x, result.y, result.width, result.height);
278+
279+ return result;
280+ }
281+
282+ void init_foreign_struts ()
283+ {
284+ unowned DockWindow window = controller.window;
285+
286+ foreign_struts = new Gee.HashMap<ulong, Strut?> ();
287+
288+ unowned Gdk.X11.Display gdk_display = (window.get_display () as Gdk.X11.Display);
289+ if (gdk_display == null)
290+ return;
291+
292+ unowned Gdk.X11.Window gdk_window = (window.get_window () as Gdk.X11.Window);
293+ if (gdk_window == null)
294+ return;
295+
296+ unowned X.Display display = gdk_display.get_xdisplay ();
297+ X.Window dock_xid = 0;
298+ if (window.get_realized ())
299+ dock_xid = gdk_window.get_xid ();
300+
301+ X.Atom ret;
302+ int format, status;
303+ uchar* data = null;
304+ ulong nitems, after;
305+
306+ Gdk.error_trap_push ();
307+
308+ status = display.get_window_property (display.default_root_window (),
309+ display.intern_atom ("_NET_CLIENT_LIST", false), 0L, ~0L, false, X.XA_WINDOW,
310+ out ret, out format, out nitems, out after, out data);
311+
312+ if (status == X.Success && ret == X.XA_WINDOW && format == 32 && nitems > 0) {
313+ unowned X.Window[] xids = (X.Window[]) data;
314+ for (uint32 i = 0; i < nitems; i++) {
315+ // Ignore our own dockwindow
316+ if (dock_xid == xids[i])
317+ continue;
318+
319+ Strut? strut;
320+ if (get_struts_for_xid (display, xids[i], out strut))
321+ foreign_struts.set (xids[i], strut);
322+ }
323+ }
324+
325+ Gdk.error_trap_pop ();
326+ }
327+
328+ static bool get_struts_for_xid (X.Display display, X.Window xid, out Strut? result)
329+ {
330+ X.Atom ret;
331+ int format, status;
332+ uchar* data = null;
333+ ulong nitems, after;
334+
335+ status = display.get_window_property (xid,
336+ display.intern_atom ("_NET_WM_STRUT_PARTIAL", false), 0L, 12L, false, X.XA_CARDINAL,
337+ out ret, out format, out nitems, out after, out data);
338+
339+ if (status == X.Success && ret == X.XA_CARDINAL && format == 32 && nitems == 12L) {
340+ result = Strut ();
341+ GLib.Memory.copy ((void*)result, data, sizeof (Strut));
342+ } else {
343+ result = null;
344+ }
345+
346+ if (data != null)
347+ X.free (data);
348+
349+ if (result != null)
350+ return true;
351+
352+ status = display.get_window_property (xid,
353+ display.intern_atom ("_NET_WM_STRUT", false), 0L, 4L, false, X.XA_CARDINAL,
354+ out ret, out format, out nitems, out after, out data);
355+
356+ if (status == X.Success && ret == X.XA_CARDINAL && format == 32 && nitems == 4L) {
357+ result = Strut ();
358+ GLib.Memory.copy ((void*)result, data, sizeof (Strut) / 3);
359+ } else {
360+ result = null;
361+ }
362+
363+ if (data != null)
364+ X.free (data);
365+
366+ return (result != null);
367+ }
368+
369+ void foreign_struts_add (Wnck.Window wnck_window)
370+ {
371+ unowned DockWindow window = controller.window;
372+
373+ unowned Gdk.X11.Display gdk_display = (window.get_display () as Gdk.X11.Display);
374+ if (gdk_display == null)
375+ return;
376+
377+ unowned Gdk.X11.Window gdk_window = (window.get_window () as Gdk.X11.Window);
378+ if (gdk_window == null)
379+ return;
380+
381+ unowned X.Display display = gdk_display.get_xdisplay ();
382+ X.Window xid = wnck_window.get_xid ();
383+ X.Window dock_xid = 0;
384+ if (window.get_realized ())
385+ dock_xid = gdk_window.get_xid ();
386+
387+ // Ignore our own dockwindow
388+ if (dock_xid == xid)
389+ return;
390+
391+ // Wait a bit for possible struts to be set on the realized window
392+ Timeout.add (500, () => {
393+ Gdk.error_trap_push ();
394+
395+ Strut? strut;
396+ if (get_struts_for_xid (display, xid, out strut)) {
397+ foreign_struts.set (xid, strut);
398+ screen_changed (controller.window.get_screen ());
399+ }
400+
401+ Gdk.error_trap_pop ();
402+
403+ return false;
404+ });
405+ }
406+
407+ void foreign_struts_remove (Wnck.Window wnck_window)
408+ {
409+ if (foreign_struts.unset (wnck_window.get_xid ()))
410+ screen_changed (controller.window.get_screen ());
411+ }
412+
413 /**
414 * Computes the struts for the dock.
415 *

Subscribers

People subscribed via source and target branches

to status/vote changes: