Merge lp:~docky-core/plank/respect-struts into lp:plank
- respect-struts
- Merge into trunk
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 |
Related bugs: |
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.
Commit message
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/
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.
Robert Dyer (psybers) wrote : Posted in a previous version of this proposal | # |
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?
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.
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.
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?
- 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 "TitledSeparato
rMenuItem. 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 AnimatedRendere
r-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
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 | * |
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?