Merge lp:~jassmith/do/glitch-free-docky into lp:do
- glitch-free-docky
- Merge into trunk
Proposed by
Jason Smith
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jassmith/do/glitch-free-docky |
Merge into: | lp:do |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~jassmith/do/glitch-free-docky |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alex Launi (community) | Approve | ||
Review via email: mp+5092@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 1135. By Jason Smith
-
remove debug
- 1136. By Jason Smith
-
Fix issues found in review
- 1137. By Jason Smith
-
merge trunk
- 1138. By Jason Smith
-
Implement tiling code
- 1139. By Jason Smith
-
Add show desktop command
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config' | |||
2 | --- Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config 2009-01-11 20:30:50 +0000 | |||
3 | +++ Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config 1970-01-01 00:00:00 +0000 | |||
4 | @@ -1,4 +0,0 @@ | |||
5 | 1 | <configuration> | ||
6 | 2 | <dllmap dll="X11" target="libX11.so.6"/> | ||
7 | 3 | <dllmap dll="libgdk-x11" target="libgdk-x11-2.0.so.0"/> | ||
8 | 4 | </configuration> | ||
9 | 5 | 0 | ||
10 | === modified file 'Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp' | |||
11 | --- Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp 2009-03-20 20:43:06 +0000 | |||
12 | +++ Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp 2009-03-31 03:39:44 +0000 | |||
13 | @@ -19,7 +19,6 @@ | |||
14 | 19 | <File name="src" subtype="Directory" buildaction="Compile" /> | 19 | <File name="src" subtype="Directory" buildaction="Compile" /> |
15 | 20 | <File name="Resources" subtype="Directory" buildaction="Compile" /> | 20 | <File name="Resources" subtype="Directory" buildaction="Compile" /> |
16 | 21 | <File name="Resources/Do.Interface.Linux.Docky.addin.xml" subtype="Code" buildaction="EmbedAsResource" /> | 21 | <File name="Resources/Do.Interface.Linux.Docky.addin.xml" subtype="Code" buildaction="EmbedAsResource" /> |
17 | 22 | <File name="src/XLib" subtype="Directory" buildaction="Compile" /> | ||
18 | 23 | <File name="src/Docky.Interface" subtype="Directory" buildaction="Compile" /> | 22 | <File name="src/Docky.Interface" subtype="Directory" buildaction="Compile" /> |
19 | 24 | <File name="src/Docky.Utilities" subtype="Directory" buildaction="Compile" /> | 23 | <File name="src/Docky.Utilities" subtype="Directory" buildaction="Compile" /> |
20 | 25 | <File name="src/Docky.Interface/DockArea.cs" subtype="Code" buildaction="Compile" /> | 24 | <File name="src/Docky.Interface/DockArea.cs" subtype="Code" buildaction="Compile" /> |
21 | @@ -32,8 +31,6 @@ | |||
22 | 32 | <File name="src/Docky.Interface/Docky.Interface.Painters/SummonModeRenderer.cs" subtype="Code" buildaction="Compile" /> | 31 | <File name="src/Docky.Interface/Docky.Interface.Painters/SummonModeRenderer.cs" subtype="Code" buildaction="Compile" /> |
23 | 33 | <File name="src/Docky.Utilities/DockPreferences.cs" subtype="Code" buildaction="Compile" /> | 32 | <File name="src/Docky.Utilities/DockPreferences.cs" subtype="Code" buildaction="Compile" /> |
24 | 34 | <File name="src/Docky.Utilities/GtkUtils.cs" subtype="Code" buildaction="Compile" /> | 33 | <File name="src/Docky.Utilities/GtkUtils.cs" subtype="Code" buildaction="Compile" /> |
25 | 35 | <File name="src/XLib/X11Atoms.cs" subtype="Code" buildaction="Compile" /> | ||
26 | 36 | <File name="src/XLib/Xlib.cs" subtype="Code" buildaction="Compile" /> | ||
27 | 37 | <File name="src/Docky.Interface/IRightClickable.cs" subtype="Code" buildaction="Compile" /> | 34 | <File name="src/Docky.Interface/IRightClickable.cs" subtype="Code" buildaction="Compile" /> |
28 | 38 | <File name="src/Docky.Interface/UpdateRequestArgs.cs" subtype="Code" buildaction="Compile" /> | 35 | <File name="src/Docky.Interface/UpdateRequestArgs.cs" subtype="Code" buildaction="Compile" /> |
29 | 39 | <File name="src/Docky.Interface/DockAnimationState.cs" subtype="Code" buildaction="Compile" /> | 36 | <File name="src/Docky.Interface/DockAnimationState.cs" subtype="Code" buildaction="Compile" /> |
30 | 40 | 37 | ||
31 | === modified file 'Do.Interface.Linux.Docky/Makefile.am' | |||
32 | --- Do.Interface.Linux.Docky/Makefile.am 2009-03-20 20:43:06 +0000 | |||
33 | +++ Do.Interface.Linux.Docky/Makefile.am 2009-03-31 16:33:58 +0000 | |||
34 | @@ -65,9 +65,7 @@ | |||
35 | 65 | src/Docky.Interface/Util.cs \ | 65 | src/Docky.Interface/Util.cs \ |
36 | 66 | src/Docky.Utilities/DockOrientation.cs \ | 66 | src/Docky.Utilities/DockOrientation.cs \ |
37 | 67 | src/Docky.Utilities/DockPreferences.cs \ | 67 | src/Docky.Utilities/DockPreferences.cs \ |
41 | 68 | src/Docky.Utilities/GtkUtils.cs \ | 68 | src/Docky.Utilities/GtkUtils.cs |
39 | 69 | src/XLib/X11Atoms.cs \ | ||
40 | 70 | src/XLib/Xlib.cs | ||
42 | 71 | 69 | ||
43 | 72 | RESOURCES = \ | 70 | RESOURCES = \ |
44 | 73 | Resources/Do.Interface.Linux.Docky.addin.xml \ | 71 | Resources/Do.Interface.Linux.Docky.addin.xml \ |
45 | @@ -91,6 +89,3 @@ | |||
46 | 91 | Do.Interface.Wink \ | 89 | Do.Interface.Wink \ |
47 | 92 | Do.Platform \ | 90 | Do.Platform \ |
48 | 93 | Do.Universe | 91 | Do.Universe |
49 | 94 | |||
50 | 95 | module_DATA += $(ASSEMBLY).dll.config | ||
51 | 96 | EXTRA_DIST += $(ASSEMBLY).dll.config | ||
52 | 97 | 92 | ||
53 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs' | |||
54 | --- Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs 2009-03-20 20:43:06 +0000 | |||
55 | +++ Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs 2009-04-01 01:08:07 +0000 | |||
56 | @@ -199,14 +199,15 @@ | |||
57 | 199 | 199 | ||
58 | 200 | void HandleWindowOpened(object o, WindowOpenedArgs args) | 200 | void HandleWindowOpened(object o, WindowOpenedArgs args) |
59 | 201 | { | 201 | { |
60 | 202 | // we do a delayed update so that we allow a small gap for wnck to catch up | ||
61 | 202 | if (!args.Window.IsSkipTasklist) | 203 | if (!args.Window.IsSkipTasklist) |
63 | 203 | UpdateItems (); | 204 | DelayUpdateItems (); |
64 | 204 | } | 205 | } |
65 | 205 | 206 | ||
66 | 206 | void HandleWindowClosed(object o, WindowClosedArgs args) | 207 | void HandleWindowClosed(object o, WindowClosedArgs args) |
67 | 207 | { | 208 | { |
68 | 208 | if (!args.Window.IsSkipTasklist) | 209 | if (!args.Window.IsSkipTasklist) |
70 | 209 | UpdateItems (); | 210 | DelayUpdateItems (); |
71 | 210 | } | 211 | } |
72 | 211 | 212 | ||
73 | 212 | void HandleUniverseInitialized(object sender, EventArgs e) | 213 | void HandleUniverseInitialized(object sender, EventArgs e) |
74 | @@ -259,17 +260,25 @@ | |||
75 | 259 | item.Position = i++; | 260 | item.Position = i++; |
76 | 260 | } | 261 | } |
77 | 261 | 262 | ||
78 | 263 | void DelayUpdateItems () | ||
79 | 264 | { | ||
80 | 265 | GLib.Timeout.Add (20, delegate { | ||
81 | 266 | UpdateItems (); | ||
82 | 267 | return false; | ||
83 | 268 | }); | ||
84 | 269 | } | ||
85 | 270 | |||
86 | 262 | void UpdateItems () | 271 | void UpdateItems () |
87 | 263 | { | 272 | { |
88 | 264 | if (!UpdatesEnabled) | 273 | if (!UpdatesEnabled) |
89 | 265 | return; | 274 | return; |
90 | 266 | 275 | ||
91 | 267 | UpdateStatItems (); | ||
92 | 268 | |||
93 | 269 | if (!CustomItemsRead) { | 276 | if (!CustomItemsRead) { |
94 | 270 | foreach (string s in ReadCustomItems ()) | 277 | foreach (string s in ReadCustomItems ()) |
95 | 271 | InternalAddItemToDock (s, LastPosition + 1); | 278 | InternalAddItemToDock (s, LastPosition + 1); |
96 | 272 | 279 | ||
97 | 280 | UpdateStatItems (); | ||
98 | 281 | |||
99 | 273 | Dictionary<string, int> sortDictionary = ReadSortDictionary (); | 282 | Dictionary<string, int> sortDictionary = ReadSortDictionary (); |
100 | 274 | foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) { | 283 | foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) { |
101 | 275 | if (sortDictionary.ContainsKey (item.Element.UniqueId)) | 284 | if (sortDictionary.ContainsKey (item.Element.UniqueId)) |
102 | @@ -277,6 +286,8 @@ | |||
103 | 277 | } | 286 | } |
104 | 278 | 287 | ||
105 | 279 | CustomItemsRead = true; | 288 | CustomItemsRead = true; |
106 | 289 | } else { | ||
107 | 290 | UpdateStatItems (); | ||
108 | 280 | } | 291 | } |
109 | 281 | 292 | ||
110 | 282 | UpdateTaskItems (); | 293 | UpdateTaskItems (); |
111 | @@ -329,24 +340,22 @@ | |||
112 | 329 | 340 | ||
113 | 330 | void UpdateTaskItems () | 341 | void UpdateTaskItems () |
114 | 331 | { | 342 | { |
116 | 332 | foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) { | 343 | foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) |
117 | 333 | item.UpdateApplication (); | 344 | item.UpdateApplication (); |
118 | 334 | } | ||
119 | 335 | 345 | ||
120 | 336 | List<ApplicationDockItem> out_items = new List<ApplicationDockItem> (); | 346 | List<ApplicationDockItem> out_items = new List<ApplicationDockItem> (); |
121 | 337 | 347 | ||
123 | 338 | IEnumerable<int> knownPids = OrderedItems | 348 | IEnumerable<Window> knownWindows = OrderedItems |
124 | 339 | .Where (di => di is ItemDockItem) | 349 | .Where (di => di is ItemDockItem) |
125 | 340 | .Cast<ItemDockItem> () | 350 | .Cast<ItemDockItem> () |
135 | 341 | .SelectMany (di => di.Pids); | 351 | .SelectMany (di => di.Windows); |
136 | 342 | 352 | ||
137 | 343 | IEnumerable<Application> prunedApps = WindowUtils.GetApplications () | 353 | var prunedWindows = WindowUtils.GetWindows () |
138 | 344 | .Where (app => app.Windows.Any (w => !w.IsSkipTasklist)) | 354 | .Where (w => !w.IsSkipTasklist && !knownWindows.Contains (w)) |
139 | 345 | .Where (app => !knownPids.Contains (app.Pid) && app.Windows.Any ()); | 355 | .GroupBy (w => SafeResClass (w)); |
140 | 346 | 356 | ||
141 | 347 | foreach (IEnumerable<Wnck.Application> apps in prunedApps | 357 | foreach (IEnumerable<Wnck.Window> windows in prunedWindows) { |
142 | 348 | .GroupBy (app => (app as Wnck.Application).Windows [0].ClassGroup.ResClass)) { | 358 | ApplicationDockItem api = new ApplicationDockItem (windows); |
134 | 349 | ApplicationDockItem api = new ApplicationDockItem (apps); | ||
143 | 350 | 359 | ||
144 | 351 | if (task_items.Any (di => di.Equals (api))) { | 360 | if (task_items.Any (di => di.Equals (api))) { |
145 | 352 | AbstractDockItem match = task_items.Where (di => di.Equals (api)).First (); | 361 | AbstractDockItem match = task_items.Where (di => di.Equals (api)).First (); |
146 | @@ -374,6 +383,13 @@ | |||
147 | 374 | task_items.AddRange (out_items.Cast<AbstractDockItem> ()); | 383 | task_items.AddRange (out_items.Cast<AbstractDockItem> ()); |
148 | 375 | } | 384 | } |
149 | 376 | 385 | ||
150 | 386 | string SafeResClass (Wnck.Window window) | ||
151 | 387 | { | ||
152 | 388 | if (window.ClassGroup != null && window.ClassGroup.ResClass != null) | ||
153 | 389 | return window.ClassGroup.ResClass; | ||
154 | 390 | return string.Empty; | ||
155 | 391 | } | ||
156 | 392 | |||
157 | 377 | void OnDockItemsChanged () | 393 | void OnDockItemsChanged () |
158 | 378 | { | 394 | { |
159 | 379 | output_items.Clear (); | 395 | output_items.Clear (); |
160 | @@ -506,15 +522,6 @@ | |||
161 | 506 | return DockItems.Contains (item) && 0 <= position && position < DockItems.Count; | 522 | return DockItems.Contains (item) && 0 <= position && position < DockItems.Count; |
162 | 507 | } | 523 | } |
163 | 508 | 524 | ||
164 | 509 | int LastNonTaskItemPosition () | ||
165 | 510 | { | ||
166 | 511 | if (!OrderedItems.Any (di => !(di is ApplicationDockItem))) | ||
167 | 512 | return 0; | ||
168 | 513 | return OrderedItems | ||
169 | 514 | .Where (di => !(di is ApplicationDockItem)) | ||
170 | 515 | .Max ((Func<AbstractDockItem, int>) (di => di.Position)); | ||
171 | 516 | } | ||
172 | 517 | |||
173 | 518 | /// <summary> | 525 | /// <summary> |
174 | 519 | /// Returns the most used items out of GNOME Do and does a tiny bit of filtering and sorting on them | 526 | /// Returns the most used items out of GNOME Do and does a tiny bit of filtering and sorting on them |
175 | 520 | /// This is mostly to encourage a better first run experience, but overall this can be improved | 527 | /// This is mostly to encourage a better first run experience, but overall this can be improved |
176 | @@ -616,19 +623,22 @@ | |||
177 | 616 | continue; | 623 | continue; |
178 | 617 | } | 624 | } |
179 | 618 | 625 | ||
181 | 619 | if (item is ApplicationDockItem && position <= LastNonTaskItemPosition ()) { | 626 | if (item is ApplicationDockItem) { |
182 | 620 | ApplicationDockItem api = item as ApplicationDockItem; | 627 | ApplicationDockItem api = item as ApplicationDockItem; |
190 | 621 | string desktop_file = api.DesktopFile; | 628 | |
191 | 622 | 629 | if (api.Launcher == null) continue; | |
192 | 623 | if (string.IsNullOrEmpty (desktop_file)) continue; | 630 | |
193 | 624 | 631 | Item launcher = api.Launcher as Item; | |
194 | 625 | AbstractDockItem newItem = MaybeCreateCustomItem (desktop_file); | 632 | if (launcher == null) |
195 | 626 | 633 | continue; | |
196 | 627 | if (newItem == null) continue; | 634 | |
197 | 635 | AbstractDockItem newItem = new ItemDockItem (launcher); | ||
198 | 628 | 636 | ||
199 | 629 | newItem.Position = item.Position; | 637 | newItem.Position = item.Position; |
200 | 630 | newItem.DockAddItem = item.DockAddItem; | 638 | newItem.DockAddItem = item.DockAddItem; |
202 | 631 | custom_items [desktop_file] = newItem; | 639 | custom_items [launcher.UniqueId] = newItem; |
203 | 640 | |||
204 | 641 | RegisterDockItem (newItem); | ||
205 | 632 | UpdateItems (); | 642 | UpdateItems (); |
206 | 633 | WriteData (); | 643 | WriteData (); |
207 | 634 | } | 644 | } |
208 | 635 | 645 | ||
209 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs' | |||
210 | --- Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs 2009-03-15 17:41:40 +0000 | |||
211 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs 2009-04-01 01:08:07 +0000 | |||
212 | @@ -26,6 +26,7 @@ | |||
213 | 26 | using Gtk; | 26 | using Gtk; |
214 | 27 | 27 | ||
215 | 28 | using Do.Platform; | 28 | using Do.Platform; |
216 | 29 | using Do.Interface.Xlib; | ||
217 | 29 | 30 | ||
218 | 30 | using Docky.Core; | 31 | using Docky.Core; |
219 | 31 | using Docky.Utilities; | 32 | using Docky.Utilities; |
220 | @@ -99,14 +100,14 @@ | |||
221 | 99 | 100 | ||
222 | 100 | switch (DockPreferences.Orientation) { | 101 | switch (DockPreferences.Orientation) { |
223 | 101 | case DockOrientation.Bottom: | 102 | case DockOrientation.Bottom: |
227 | 102 | values [(int) XLib.Struts.Bottom] = (uint) (DockHeight + (Screen.Height - (geo.Y + geo.Height))); | 103 | values [(int) Struts.Bottom] = (uint) (DockHeight + (Screen.Height - (geo.Y + geo.Height))); |
228 | 103 | values [(int) XLib.Struts.BottomStart] = (uint) geo.X; | 104 | values [(int) Struts.BottomStart] = (uint) geo.X; |
229 | 104 | values [(int) XLib.Struts.BottomEnd] = (uint) (geo.X + geo.Width - 1); | 105 | values [(int) Struts.BottomEnd] = (uint) (geo.X + geo.Width - 1); |
230 | 105 | break; | 106 | break; |
231 | 106 | case DockOrientation.Top: | 107 | case DockOrientation.Top: |
235 | 107 | values [(int) XLib.Struts.Top] = (uint) (DockHeight + geo.Y); | 108 | values [(int) Struts.Top] = (uint) (DockHeight + geo.Y); |
236 | 108 | values [(int) XLib.Struts.TopStart] = (uint) geo.X; | 109 | values [(int) Struts.TopStart] = (uint) geo.X; |
237 | 109 | values [(int) XLib.Struts.TopEnd] = (uint) (geo.X + geo.Width - 1); | 110 | values [(int) Struts.TopEnd] = (uint) (geo.X + geo.Width - 1); |
238 | 110 | break; | 111 | break; |
239 | 111 | } | 112 | } |
240 | 112 | return values; | 113 | return values; |
241 | @@ -175,8 +176,11 @@ | |||
242 | 175 | break; | 176 | break; |
243 | 176 | } | 177 | } |
244 | 177 | } | 178 | } |
245 | 179 | |||
246 | 178 | CursorIsOverDockArea = dockRegion.Contains (cursor); | 180 | CursorIsOverDockArea = dockRegion.Contains (cursor); |
247 | 179 | } | 181 | } |
248 | 182 | Console.WriteLine (cursor); | ||
249 | 183 | Console.WriteLine (dockRegion); | ||
250 | 180 | 184 | ||
251 | 181 | // When we change over this boundry, it will normally trigger an animation, we need to be sure to catch it | 185 | // When we change over this boundry, it will normally trigger an animation, we need to be sure to catch it |
252 | 182 | if (CursorIsOverDockArea != cursorIsOverDockArea) { | 186 | if (CursorIsOverDockArea != cursorIsOverDockArea) { |
253 | 183 | 187 | ||
254 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs' | |||
255 | --- Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs 2009-03-11 16:29:55 +0000 | |||
256 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs 2009-04-01 01:08:07 +0000 | |||
257 | @@ -207,6 +207,8 @@ | |||
258 | 207 | 207 | ||
259 | 208 | void DrawDrock (Context cr) | 208 | void DrawDrock (Context cr) |
260 | 209 | { | 209 | { |
261 | 210 | Console.WriteLine (VerticalOffset); | ||
262 | 211 | Console.WriteLine (CursorIsOverDockArea); | ||
263 | 210 | Gdk.Rectangle dockArea = GetDockArea (); | 212 | Gdk.Rectangle dockArea = GetDockArea (); |
264 | 211 | DockBackgroundRenderer.RenderDockBackground (cr, dockArea); | 213 | DockBackgroundRenderer.RenderDockBackground (cr, dockArea); |
265 | 212 | 214 | ||
266 | 213 | 215 | ||
267 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs' | |||
268 | --- Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs 2009-03-15 18:30:41 +0000 | |||
269 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs 2009-04-01 01:09:29 +0000 | |||
270 | @@ -25,11 +25,11 @@ | |||
271 | 25 | using Cairo; | 25 | using Cairo; |
272 | 26 | 26 | ||
273 | 27 | using Docky.Utilities; | 27 | using Docky.Utilities; |
274 | 28 | using Docky.XLib; | ||
275 | 29 | 28 | ||
276 | 30 | using Do.Universe; | 29 | using Do.Universe; |
277 | 31 | using Do.Platform; | 30 | using Do.Platform; |
278 | 32 | using Do.Interface; | 31 | using Do.Interface; |
279 | 32 | using Do.Interface.Xlib; | ||
280 | 33 | using Do.Interface.CairoUtils; | 33 | using Do.Interface.CairoUtils; |
281 | 34 | using Do.Interface.AnimationBase; | 34 | using Do.Interface.AnimationBase; |
282 | 35 | 35 | ||
283 | @@ -243,7 +243,9 @@ | |||
284 | 243 | results_window.Move ((geo.X + geo.Width / 2) - res.Width / 2, geo.Y + dock_area.DockHeight); | 243 | results_window.Move ((geo.X + geo.Width / 2) - res.Width / 2, geo.Y + dock_area.DockHeight); |
285 | 244 | break; | 244 | break; |
286 | 245 | } | 245 | } |
288 | 246 | Display.Sync (); | 246 | |
289 | 247 | if (Display != null) | ||
290 | 248 | Display.Sync (); | ||
291 | 247 | 249 | ||
292 | 248 | is_repositioned_hidden = false; | 250 | is_repositioned_hidden = false; |
293 | 249 | } | 251 | } |
294 | @@ -264,7 +266,8 @@ | |||
295 | 264 | break; | 266 | break; |
296 | 265 | } | 267 | } |
297 | 266 | 268 | ||
299 | 267 | Display.Sync (); | 269 | if (Display != null) |
300 | 270 | Display.Sync (); | ||
301 | 268 | 271 | ||
302 | 269 | is_repositioned_hidden = true; | 272 | is_repositioned_hidden = true; |
303 | 270 | } | 273 | } |
304 | @@ -272,20 +275,21 @@ | |||
305 | 272 | public void WindowHideOffset (out int x, out int y) | 275 | public void WindowHideOffset (out int x, out int y) |
306 | 273 | { | 276 | { |
307 | 274 | x = y = 0; | 277 | x = y = 0; |
315 | 275 | 278 | ||
316 | 276 | if (!is_repositioned_hidden) { | 279 | Gdk.Rectangle main, geo; |
317 | 277 | return; | 280 | main.Width = dock_area.Width; |
318 | 278 | } | 281 | main.Height = dock_area.Height; |
319 | 279 | 282 | GetBufferedPosition (out main.X, out main.Y); | |
320 | 280 | Gdk.Rectangle main; | 283 | geo = LayoutUtils.MonitorGemonetry (); |
321 | 281 | GetSize (out main.Width, out main.Height); | 284 | |
322 | 285 | |||
323 | 282 | switch (DockPreferences.Orientation) { | 286 | switch (DockPreferences.Orientation) { |
324 | 283 | case DockOrientation.Bottom: | 287 | case DockOrientation.Bottom: |
327 | 284 | y = main.Height; | 288 | y = main.Y - ((geo.Y + geo.Height) - main.Height); |
328 | 285 | break; | 289 | return; |
329 | 286 | case DockOrientation.Top: | 290 | case DockOrientation.Top: |
332 | 287 | y = 0 - main.Height; | 291 | y = main.Y - geo.Y; |
333 | 288 | break; | 292 | return; |
334 | 289 | } | 293 | } |
335 | 290 | } | 294 | } |
336 | 291 | 295 | ||
337 | @@ -308,7 +312,7 @@ | |||
338 | 308 | 312 | ||
339 | 309 | public bool SetStruts () | 313 | public bool SetStruts () |
340 | 310 | { | 314 | { |
342 | 311 | X11Atoms atoms = new X11Atoms (GdkWindow); | 315 | X11Atoms atoms = X11Atoms.Instance; |
343 | 312 | 316 | ||
344 | 313 | uint [] struts = dock_area.StrutRequest; | 317 | uint [] struts = dock_area.StrutRequest; |
345 | 314 | uint [] first_struts = new [] { struts [0], struts [1], struts [2], struts [3] }; | 318 | uint [] first_struts = new [] { struts [0], struts [1], struts [2], struts [3] }; |
346 | @@ -318,10 +322,10 @@ | |||
347 | 318 | if (!IsRealized) | 322 | if (!IsRealized) |
348 | 319 | return false; | 323 | return false; |
349 | 320 | Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT_PARTIAL, atoms.XA_CARDINAL, | 324 | Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT_PARTIAL, atoms.XA_CARDINAL, |
351 | 321 | (int) XLib.PropertyMode.PropModeReplace, struts); | 325 | (int) PropertyMode.PropModeReplace, struts); |
352 | 322 | 326 | ||
353 | 323 | Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT, atoms.XA_CARDINAL, | 327 | Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT, atoms.XA_CARDINAL, |
355 | 324 | (int) XLib.PropertyMode.PropModeReplace, first_struts); | 328 | (int) PropertyMode.PropModeReplace, first_struts); |
356 | 325 | 329 | ||
357 | 326 | return false; | 330 | return false; |
358 | 327 | } | 331 | } |
359 | 328 | 332 | ||
360 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs' | |||
361 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs 2009-03-20 20:43:06 +0000 | |||
362 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs 2009-04-01 02:13:22 +0000 | |||
363 | @@ -43,16 +43,6 @@ | |||
364 | 43 | { | 43 | { |
365 | 44 | public event EventHandler RemoveClicked; | 44 | public event EventHandler RemoveClicked; |
366 | 45 | 45 | ||
367 | 46 | static readonly IEnumerable<string> DesktopFilesDirectories = new [] { | ||
368 | 47 | "~/.local/share/applications/wine", | ||
369 | 48 | "~/.local/share/applications", | ||
370 | 49 | "/usr/share/applications", | ||
371 | 50 | "/usr/share/applications/kde", | ||
372 | 51 | "/usr/share/applications/kde4", | ||
373 | 52 | "/usr/share/gdm/applications", | ||
374 | 53 | "/usr/local/share/applications", | ||
375 | 54 | }; | ||
376 | 55 | |||
377 | 56 | string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore"); | 46 | string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore"); |
378 | 57 | string MaximizeText = Catalog.GetString ("Maximize"); | 47 | string MaximizeText = Catalog.GetString ("Maximize"); |
379 | 58 | string CloseText = Catalog.GetString ("Close All"); | 48 | string CloseText = Catalog.GetString ("Close All"); |
380 | @@ -77,33 +67,23 @@ | |||
381 | 77 | Gdk.Rectangle icon_region; | 67 | Gdk.Rectangle icon_region; |
382 | 78 | Gdk.Pixbuf drag_pixbuf; | 68 | Gdk.Pixbuf drag_pixbuf; |
383 | 79 | 69 | ||
390 | 80 | IEnumerable<Wnck.Application> applications; | 70 | IEnumerable<Wnck.Window> windows; |
391 | 81 | 71 | ||
392 | 82 | string desktop_file; | 72 | IApplicationItem launcher; |
393 | 83 | bool checked_desktop_file; | 73 | |
394 | 84 | 74 | public IApplicationItem Launcher { | |
389 | 85 | public string DesktopFile { | ||
395 | 86 | get { | 75 | get { |
403 | 87 | if (desktop_file == null && !checked_desktop_file) { | 76 | if (launcher == null && Exec != null) { |
404 | 88 | checked_desktop_file = true; | 77 | string command = WindowUtils.ProcessExecString (Exec); |
405 | 89 | foreach (string s in GetIconGuesses ()) { | 78 | launcher = Services.UniverseFactory.MaybeApplicationItemFromCommand (command); |
399 | 90 | desktop_file = GetDesktopFile (s); | ||
400 | 91 | if (desktop_file != null) | ||
401 | 92 | break; | ||
402 | 93 | } | ||
406 | 94 | } | 79 | } |
408 | 95 | return desktop_file; | 80 | return launcher; |
409 | 96 | } | 81 | } |
410 | 97 | } | 82 | } |
411 | 98 | 83 | ||
412 | 99 | string Exec { | 84 | string Exec { |
413 | 100 | get { | 85 | get { |
414 | 101 | string exec; | 86 | string exec; |
415 | 102 | foreach (Wnck.Application app in Applications) { | ||
416 | 103 | exec = MaybeGetExecStringForPID (app.Pid); | ||
417 | 104 | if (exec != null) | ||
418 | 105 | return exec; | ||
419 | 106 | } | ||
420 | 107 | 87 | ||
421 | 108 | foreach (Wnck.Window win in VisibleWindows) { | 88 | foreach (Wnck.Window win in VisibleWindows) { |
422 | 109 | exec = MaybeGetExecStringForPID (win.Pid); | 89 | exec = MaybeGetExecStringForPID (win.Pid); |
423 | @@ -130,34 +110,23 @@ | |||
424 | 130 | protected override Gdk.Pixbuf GetSurfacePixbuf (int size) | 110 | protected override Gdk.Pixbuf GetSurfacePixbuf (int size) |
425 | 131 | { | 111 | { |
426 | 132 | Gdk.Pixbuf pbuf = null; | 112 | Gdk.Pixbuf pbuf = null; |
429 | 133 | foreach (string guess in GetIconGuesses ()) { | 113 | |
430 | 134 | if (pbuf != null) { | 114 | if (Launcher == null) { |
431 | 115 | foreach (string guess in GetIconGuesses ()) { | ||
432 | 116 | bool found = IconProvider.PixbufFromIconName (guess, size, out pbuf); | ||
433 | 117 | if (found && (pbuf.Width == size || pbuf.Height == size)) | ||
434 | 118 | break; | ||
435 | 119 | |||
436 | 135 | pbuf.Dispose (); | 120 | pbuf.Dispose (); |
437 | 136 | pbuf = null; | 121 | pbuf = null; |
438 | 137 | } | 122 | } |
457 | 138 | 123 | } else { | |
458 | 139 | bool found = IconProvider.PixbufFromIconName (guess, size, out pbuf); | 124 | IconProvider.PixbufFromIconName (Launcher.Icon, size, out pbuf); |
441 | 140 | if (found && (pbuf.Width == size || pbuf.Height == size)) | ||
442 | 141 | break; | ||
443 | 142 | |||
444 | 143 | pbuf.Dispose (); | ||
445 | 144 | pbuf = null; | ||
446 | 145 | |||
447 | 146 | string desktopPath = GetDesktopFile (guess); | ||
448 | 147 | if (!string.IsNullOrEmpty (desktopPath)) { | ||
449 | 148 | try { | ||
450 | 149 | string icon = Services.UniverseFactory.NewApplicationItem (desktopPath).Icon; | ||
451 | 150 | pbuf = IconProvider.PixbufFromIconName (icon, size); | ||
452 | 151 | break; | ||
453 | 152 | } catch { | ||
454 | 153 | continue; | ||
455 | 154 | } | ||
456 | 155 | } | ||
459 | 156 | } | 125 | } |
460 | 157 | 126 | ||
461 | 158 | // we failed to find an icon, lets use an uggggly one | 127 | // we failed to find an icon, lets use an uggggly one |
462 | 159 | if (pbuf == null) | 128 | if (pbuf == null) |
464 | 160 | pbuf = Applications.First ().Icon; | 129 | pbuf = Windows.First ().Icon; |
465 | 161 | 130 | ||
466 | 162 | if (pbuf.Height != size && pbuf.Width != size ) { | 131 | if (pbuf.Height != size && pbuf.Width != size ) { |
467 | 163 | double scale = (double)size / Math.Max (pbuf.Width, pbuf.Height); | 132 | double scale = (double)size / Math.Max (pbuf.Width, pbuf.Height); |
468 | @@ -170,14 +139,16 @@ | |||
469 | 170 | 139 | ||
470 | 171 | string Name { | 140 | string Name { |
471 | 172 | get { | 141 | get { |
479 | 173 | foreach (Wnck.Application application in Applications) { | 142 | if (NeedsAttention) { |
480 | 174 | if (StringIsValidName (application.IconName)) | 143 | return VisibleWindows.Where (w => w.NeedsAttention ()).First ().Name; |
481 | 175 | return application.IconName; | 144 | } |
482 | 176 | else if (StringIsValidName (application.Name)) | 145 | if (VisibleWindows.Any () && VisibleWindows.Count () == 1) { |
483 | 177 | return application.Name; | 146 | return VisibleWindows.First ().Name; |
484 | 178 | } | 147 | } |
485 | 179 | 148 | ||
486 | 180 | foreach (Wnck.Window window in VisibleWindows) { | 149 | foreach (Wnck.Window window in VisibleWindows) { |
487 | 150 | if (StringIsValidName (window.ClassGroup.ResClass)) | ||
488 | 151 | return window.ClassGroup.ResClass; | ||
489 | 181 | if (StringIsValidName (window.IconName)) | 152 | if (StringIsValidName (window.IconName)) |
490 | 182 | return window.IconName; | 153 | return window.IconName; |
491 | 183 | else if (StringIsValidName (window.Name)) | 154 | else if (StringIsValidName (window.Name)) |
492 | @@ -191,13 +162,13 @@ | |||
493 | 191 | get { return windowCount; } | 162 | get { return windowCount; } |
494 | 192 | } | 163 | } |
495 | 193 | 164 | ||
498 | 194 | protected override IEnumerable<Wnck.Application> Applications { | 165 | public override IEnumerable<Wnck.Window> Windows { |
499 | 195 | get { return applications; } | 166 | get { return windows; } |
500 | 196 | } | 167 | } |
501 | 197 | 168 | ||
503 | 198 | public ApplicationDockItem (IEnumerable<Wnck.Application> applications) : base () | 169 | public ApplicationDockItem (IEnumerable<Wnck.Window> windows) : base () |
504 | 199 | { | 170 | { |
506 | 200 | this.applications = applications; | 171 | this.windows = windows; |
507 | 201 | windowCount = VisibleWindows.Count (); | 172 | windowCount = VisibleWindows.Count (); |
508 | 202 | 173 | ||
509 | 203 | foreach (Wnck.Window w in VisibleWindows) { | 174 | foreach (Wnck.Window w in VisibleWindows) { |
510 | @@ -227,41 +198,49 @@ | |||
511 | 227 | if (VisibleWindows.Count () == 0) | 198 | if (VisibleWindows.Count () == 0) |
512 | 228 | Core.DockServices.ItemsService.ForceUpdate (); | 199 | Core.DockServices.ItemsService.ForceUpdate (); |
513 | 229 | } | 200 | } |
514 | 201 | |||
515 | 202 | SetText (Name); | ||
516 | 230 | } | 203 | } |
517 | 231 | 204 | ||
518 | 232 | IEnumerable<string> GetIconGuesses () | 205 | IEnumerable<string> GetIconGuesses () |
519 | 233 | { | 206 | { |
520 | 234 | List<string> guesses = new List<string> (); | 207 | List<string> guesses = new List<string> (); |
521 | 235 | 208 | ||
525 | 236 | if (!string.IsNullOrEmpty (Exec)) { | 209 | // open office hack... |
526 | 237 | yield return Exec; | 210 | if (VisibleWindows.Any () && |
527 | 238 | yield return Exec.Split ('-')[0]; | 211 | VisibleWindows.First ().ClassGroup != null && |
528 | 212 | VisibleWindows.First ().ClassGroup.ResClass.ToLower ().Contains ("openoffice")) { | ||
529 | 213 | yield return "openoffice"; | ||
530 | 214 | yield break; | ||
531 | 239 | } | 215 | } |
532 | 240 | 216 | ||
538 | 241 | foreach (Wnck.Application app in Applications) { | 217 | string exec = Exec; |
539 | 242 | if (!guesses.Contains (PrepName (app.Name))) | 218 | if (!string.IsNullOrEmpty (exec)) { |
540 | 243 | guesses.Add (PrepName (app.Name)); | 219 | yield return exec; |
541 | 244 | if (!guesses.Contains (PrepName (app.IconName))) | 220 | yield return exec.Split ('-')[0]; |
542 | 245 | guesses.Add (PrepName (app.IconName)); | 221 | yield return WindowUtils.ProcessExecString (exec); |
543 | 246 | } | 222 | } |
544 | 247 | 223 | ||
545 | 248 | foreach (Wnck.Window win in VisibleWindows) { | 224 | foreach (Wnck.Window win in VisibleWindows) { |
546 | 249 | if (!guesses.Contains (PrepName (win.Name))) | 225 | if (!guesses.Contains (PrepName (win.Name))) |
547 | 250 | guesses.Add (PrepName (win.Name)); | 226 | guesses.Add (PrepName (win.Name)); |
548 | 227 | |||
549 | 251 | if (!guesses.Contains (PrepName (win.IconName))) | 228 | if (!guesses.Contains (PrepName (win.IconName))) |
550 | 252 | guesses.Add (PrepName (win.IconName)); | 229 | guesses.Add (PrepName (win.IconName)); |
551 | 230 | |||
552 | 231 | if (win.ClassGroup == null) | ||
553 | 232 | continue; | ||
554 | 233 | |||
555 | 253 | if (!guesses.Contains (PrepName (win.ClassGroup.ResClass))) | 234 | if (!guesses.Contains (PrepName (win.ClassGroup.ResClass))) |
556 | 254 | guesses.Add (PrepName (win.ClassGroup.ResClass)); | 235 | guesses.Add (PrepName (win.ClassGroup.ResClass)); |
557 | 236 | |||
558 | 237 | if (!guesses.Contains (PrepName (win.ClassGroup.Name))) | ||
559 | 238 | guesses.Add (PrepName (win.ClassGroup.Name)); | ||
560 | 255 | } | 239 | } |
561 | 256 | 240 | ||
563 | 257 | foreach (string s in guesses) | 241 | foreach (string s in guesses) { |
564 | 258 | yield return s; | 242 | yield return s; |
571 | 259 | 243 | } | |
566 | 260 | foreach (string s in guesses) | ||
567 | 261 | yield return "gnome-" + s; | ||
568 | 262 | |||
569 | 263 | if (Name.Length > 4 && Name.Contains (" ")) | ||
570 | 264 | yield return Name.Split (' ') [0].ToLower (); | ||
572 | 265 | } | 244 | } |
573 | 266 | 245 | ||
574 | 267 | string PrepName (string s) | 246 | string PrepName (string s) |
575 | @@ -283,27 +262,14 @@ | |||
576 | 283 | return exec; | 262 | return exec; |
577 | 284 | } | 263 | } |
578 | 285 | 264 | ||
579 | 286 | string GetDesktopFile (string base_name) | ||
580 | 287 | { | ||
581 | 288 | foreach (string dir in DesktopFilesDirectories) { | ||
582 | 289 | try { | ||
583 | 290 | if (File.Exists (System.IO.Path.Combine (dir, base_name+".desktop"))) | ||
584 | 291 | return System.IO.Path.Combine (dir, base_name+".desktop"); | ||
585 | 292 | if (File.Exists (System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop"))) | ||
586 | 293 | return System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop"); | ||
587 | 294 | } catch { return null; } | ||
588 | 295 | } | ||
589 | 296 | return null; | ||
590 | 297 | } | ||
591 | 298 | |||
592 | 299 | bool StringIsValidName (string s) | 265 | bool StringIsValidName (string s) |
593 | 300 | { | 266 | { |
594 | 301 | s = s.Trim (); | 267 | s = s.Trim (); |
595 | 302 | if (string.IsNullOrEmpty (s) || s == "<unknown>") | 268 | if (string.IsNullOrEmpty (s) || s == "<unknown>") |
596 | 303 | return false; | 269 | return false; |
597 | 304 | 270 | ||
600 | 305 | foreach (string prefix in WindowUtils.BadPrefixes) { | 271 | foreach (System.Text.RegularExpressions.Regex prefix in WindowUtils.BadPrefixes) { |
601 | 306 | if (string.Compare (s, prefix, true) == 0) | 272 | if (prefix.IsMatch (s)) |
602 | 307 | return false; | 273 | return false; |
603 | 308 | } | 274 | } |
604 | 309 | 275 | ||
605 | @@ -324,14 +290,15 @@ | |||
606 | 324 | if (!(other is ApplicationDockItem)) | 290 | if (!(other is ApplicationDockItem)) |
607 | 325 | return false; | 291 | return false; |
608 | 326 | 292 | ||
610 | 327 | return Applications.Any (app => (other as ApplicationDockItem).Applications.Contains (app)); | 293 | return Windows.Any (w => (other as ApplicationDockItem).Windows.Contains (w)); |
611 | 328 | } | 294 | } |
612 | 329 | 295 | ||
613 | 330 | public IEnumerable<AbstractMenuArgs> GetMenuItems () | 296 | public IEnumerable<AbstractMenuArgs> GetMenuItems () |
614 | 331 | { | 297 | { |
615 | 332 | yield return new SeparatorMenuButtonArgs (); | 298 | yield return new SeparatorMenuButtonArgs (); |
616 | 333 | 299 | ||
618 | 334 | if (DesktopFile == null) { | 300 | Item item = Launcher as Item; |
619 | 301 | if (item == null) { | ||
620 | 335 | yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows), | 302 | yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows), |
621 | 336 | MinimizeRestoreText, MinimizeIcon).AsDark (); | 303 | MinimizeRestoreText, MinimizeIcon).AsDark (); |
622 | 337 | 304 | ||
623 | @@ -341,8 +308,6 @@ | |||
624 | 341 | yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows), | 308 | yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows), |
625 | 342 | CloseText, CloseIcon).AsDark (); | 309 | CloseText, CloseIcon).AsDark (); |
626 | 343 | } else { | 310 | } else { |
627 | 344 | Item item = Services.UniverseFactory.NewApplicationItem (DesktopFile) as Item; | ||
628 | 345 | |||
629 | 346 | foreach (Act act in ActionsForItem (item)) | 311 | foreach (Act act in ActionsForItem (item)) |
630 | 347 | yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark (); | 312 | yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark (); |
631 | 348 | } | 313 | } |
632 | @@ -352,6 +317,12 @@ | |||
633 | 352 | yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon); | 317 | yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon); |
634 | 353 | } | 318 | } |
635 | 354 | } | 319 | } |
636 | 320 | |||
637 | 321 | protected override void Launch () | ||
638 | 322 | { | ||
639 | 323 | if (Launcher != null) | ||
640 | 324 | Launcher.Run (); | ||
641 | 325 | } | ||
642 | 355 | 326 | ||
643 | 356 | public override void Dispose () | 327 | public override void Dispose () |
644 | 357 | { | 328 | { |
645 | 358 | 329 | ||
646 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs' | |||
647 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs 2009-03-20 20:43:06 +0000 | |||
648 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs 2009-03-25 03:40:59 +0000 | |||
649 | @@ -52,7 +52,7 @@ | |||
650 | 52 | bool accepting_drops; | 52 | bool accepting_drops; |
651 | 53 | Gdk.Pixbuf drag_pixbuf; | 53 | Gdk.Pixbuf drag_pixbuf; |
652 | 54 | Gdk.Rectangle icon_region; | 54 | Gdk.Rectangle icon_region; |
654 | 55 | List<Wnck.Application> apps; | 55 | List<Wnck.Window> windows; |
655 | 56 | 56 | ||
656 | 57 | public event EventHandler RemoveClicked; | 57 | public event EventHandler RemoveClicked; |
657 | 58 | 58 | ||
658 | @@ -64,16 +64,32 @@ | |||
659 | 64 | get { return element.Icon; } | 64 | get { return element.Icon; } |
660 | 65 | } | 65 | } |
661 | 66 | 66 | ||
662 | 67 | string Name { | ||
663 | 68 | get { | ||
664 | 69 | if (NeedsAttention && AttentionWindows.Any ()) | ||
665 | 70 | return AttentionWindows.First ().Name; | ||
666 | 71 | |||
667 | 72 | if (VisibleWindows.Any () && WindowCount == 1) | ||
668 | 73 | return VisibleWindows.First ().Name; | ||
669 | 74 | |||
670 | 75 | return Element.Name; | ||
671 | 76 | } | ||
672 | 77 | } | ||
673 | 78 | |||
674 | 67 | public Item Element { | 79 | public Item Element { |
675 | 68 | get { return element; } | 80 | get { return element; } |
676 | 69 | } | 81 | } |
677 | 70 | 82 | ||
680 | 71 | protected override IEnumerable<Wnck.Application> Applications { | 83 | public override IEnumerable<Wnck.Window> Windows { |
681 | 72 | get { return apps; } | 84 | get { return windows; } |
682 | 85 | } | ||
683 | 86 | |||
684 | 87 | IEnumerable<Wnck.Window> AttentionWindows { | ||
685 | 88 | get { return VisibleWindows.Where (w => w.NeedsAttention ()); } | ||
686 | 73 | } | 89 | } |
687 | 74 | 90 | ||
688 | 75 | public IEnumerable<int> Pids { | 91 | public IEnumerable<int> Pids { |
690 | 76 | get { return apps.Select (win => win.Pid).ToArray (); } | 92 | get { return windows.Select (win => win.Pid).ToArray (); } |
691 | 77 | } | 93 | } |
692 | 78 | 94 | ||
693 | 79 | public override int WindowCount { | 95 | public override int WindowCount { |
694 | @@ -84,9 +100,7 @@ | |||
695 | 84 | { | 100 | { |
696 | 85 | Position = -1; | 101 | Position = -1; |
697 | 86 | this.element = element; | 102 | this.element = element; |
701 | 87 | apps = new List<Wnck.Application> (); | 103 | windows = new List<Wnck.Window> (); |
699 | 88 | |||
700 | 89 | SetText (element.Name); | ||
702 | 90 | 104 | ||
703 | 91 | UpdateApplication (); | 105 | UpdateApplication (); |
704 | 92 | NeedsAttention = DetermineUrgencyStatus (); | 106 | NeedsAttention = DetermineUrgencyStatus (); |
705 | @@ -95,6 +109,8 @@ | |||
706 | 95 | accepting_drops = true; | 109 | accepting_drops = true; |
707 | 96 | else | 110 | else |
708 | 97 | accepting_drops = false; | 111 | accepting_drops = false; |
709 | 112 | |||
710 | 113 | SetText (Name); | ||
711 | 98 | } | 114 | } |
712 | 99 | 115 | ||
713 | 100 | public override bool ReceiveItem (string item) | 116 | public override bool ReceiveItem (string item) |
714 | @@ -126,46 +142,49 @@ | |||
715 | 126 | 142 | ||
716 | 127 | public void UpdateApplication () | 143 | public void UpdateApplication () |
717 | 128 | { | 144 | { |
719 | 129 | UnregisterStateChangeEvents (); | 145 | UnregisterWindowEvents (); |
720 | 130 | 146 | ||
721 | 131 | if (element is IApplicationItem) { | 147 | if (element is IApplicationItem) { |
724 | 132 | apps = WindowUtils.GetApplicationList ((element as IApplicationItem).Exec); | 148 | windows = WindowUtils.WindowListForCmd ((element as IApplicationItem).Exec); |
725 | 133 | window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count (); | 149 | window_count = windows.Where (w => !w.IsSkipTasklist).Count (); |
726 | 134 | } | 150 | } |
727 | 135 | 151 | ||
753 | 136 | RegisterStateChangeEvents (); | 152 | RegisterWindowEvents (); |
754 | 137 | } | 153 | SetText (Name); |
755 | 138 | 154 | } | |
756 | 139 | void RegisterStateChangeEvents () | 155 | |
757 | 140 | { | 156 | void RegisterWindowEvents () |
758 | 141 | foreach (Application app in Applications) { | 157 | { |
759 | 142 | foreach (Wnck.Window w in app.Windows) { | 158 | foreach (Wnck.Window w in VisibleWindows) { |
760 | 143 | if (!w.IsSkipTasklist) | 159 | w.StateChanged += HandleStateChanged; |
761 | 144 | w.StateChanged += OnWindowStateChanged; | 160 | w.NameChanged += HandleNameChanged; |
762 | 145 | } | 161 | } |
763 | 146 | } | 162 | } |
764 | 147 | } | 163 | |
765 | 148 | 164 | void UnregisterWindowEvents () | |
766 | 149 | void UnregisterStateChangeEvents () | 165 | { |
767 | 150 | { | 166 | foreach (Wnck.Window w in Windows) { |
768 | 151 | foreach (Application app in Applications) { | 167 | try { |
769 | 152 | foreach (Wnck.Window w in app.Windows) { | 168 | w.StateChanged -= HandleStateChanged; |
770 | 153 | try { | 169 | w.NameChanged += HandleNameChanged; |
771 | 154 | w.StateChanged -= OnWindowStateChanged; | 170 | } catch {} |
772 | 155 | } catch {} | 171 | } |
773 | 156 | } | 172 | } |
774 | 157 | } | 173 | |
775 | 158 | } | 174 | void HandleStateChanged (object o, StateChangedArgs args) |
751 | 159 | |||
752 | 160 | void OnWindowStateChanged (object o, StateChangedArgs args) | ||
776 | 161 | { | 175 | { |
777 | 162 | if (handle_timer > 0) return; | 176 | if (handle_timer > 0) return; |
778 | 163 | // we do this delayed so that we dont get a flood of these events. Certain windows behave badly. | 177 | // we do this delayed so that we dont get a flood of these events. Certain windows behave badly. |
779 | 164 | handle_timer = GLib.Timeout.Add (100, HandleUpdate); | 178 | handle_timer = GLib.Timeout.Add (100, HandleUpdate); |
781 | 165 | window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count (); | 179 | window_count = VisibleWindows.Count (); |
782 | 166 | SetIconRegionFromCache (); | 180 | SetIconRegionFromCache (); |
783 | 167 | } | 181 | } |
784 | 168 | 182 | ||
785 | 183 | void HandleNameChanged(object sender, EventArgs e) | ||
786 | 184 | { | ||
787 | 185 | SetText (Name); | ||
788 | 186 | } | ||
789 | 187 | |||
790 | 169 | bool HandleUpdate () | 188 | bool HandleUpdate () |
791 | 170 | { | 189 | { |
792 | 171 | bool needed_attention = NeedsAttention; | 190 | bool needed_attention = NeedsAttention; |
793 | @@ -180,6 +199,7 @@ | |||
794 | 180 | OnUpdateNeeded (new UpdateRequestArgs (this, req)); | 199 | OnUpdateNeeded (new UpdateRequestArgs (this, req)); |
795 | 181 | } | 200 | } |
796 | 182 | 201 | ||
797 | 202 | SetText (Name); | ||
798 | 183 | handle_timer = 0; | 203 | handle_timer = 0; |
799 | 184 | return false; | 204 | return false; |
800 | 185 | } | 205 | } |
801 | @@ -250,9 +270,9 @@ | |||
802 | 250 | 270 | ||
803 | 251 | public override void Dispose () | 271 | public override void Dispose () |
804 | 252 | { | 272 | { |
806 | 253 | UnregisterStateChangeEvents (); | 273 | UnregisterWindowEvents (); |
807 | 254 | element = null; | 274 | element = null; |
809 | 255 | apps.Clear (); | 275 | windows.Clear (); |
810 | 256 | 276 | ||
811 | 257 | if (drag_pixbuf != null) | 277 | if (drag_pixbuf != null) |
812 | 258 | drag_pixbuf.Dispose (); | 278 | drag_pixbuf.Dispose (); |
813 | 259 | 279 | ||
814 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs' | |||
815 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs 2009-03-20 20:43:06 +0000 | |||
816 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs 2009-04-01 01:08:07 +0000 | |||
817 | @@ -42,20 +42,26 @@ | |||
818 | 42 | 42 | ||
819 | 43 | public abstract class WnckDockItem : AbstractDockItem | 43 | public abstract class WnckDockItem : AbstractDockItem |
820 | 44 | { | 44 | { |
821 | 45 | // a bad hack, but it works | ||
822 | 46 | static string [] blacklist = new [] { | ||
823 | 47 | "CopyToClipboardAction", | ||
824 | 48 | "WindowFocusAction", | ||
825 | 49 | }; | ||
826 | 50 | |||
827 | 45 | int last_raised; | 51 | int last_raised; |
828 | 46 | 52 | ||
829 | 47 | DateTime last_scroll = new DateTime (0); | 53 | DateTime last_scroll = new DateTime (0); |
830 | 48 | TimeSpan scroll_rate = new TimeSpan (0, 0, 0, 0, 300); | 54 | TimeSpan scroll_rate = new TimeSpan (0, 0, 0, 0, 300); |
831 | 49 | 55 | ||
833 | 50 | protected abstract IEnumerable<Wnck.Application> Applications { get; } | 56 | public abstract IEnumerable<Wnck.Window> Windows { get; } |
834 | 51 | 57 | ||
835 | 52 | protected IEnumerable<Wnck.Window> VisibleWindows { | 58 | protected IEnumerable<Wnck.Window> VisibleWindows { |
837 | 53 | get { return Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist); } | 59 | get { return Windows.Where (w => !w.IsSkipTasklist); } |
838 | 54 | } | 60 | } |
839 | 55 | 61 | ||
840 | 56 | protected bool HasVisibleApps { | 62 | protected bool HasVisibleApps { |
841 | 57 | get { | 63 | get { |
843 | 58 | if (Applications == null) | 64 | if (Windows == null) |
844 | 59 | return false; | 65 | return false; |
845 | 60 | return VisibleWindows.Any (); | 66 | return VisibleWindows.Any (); |
846 | 61 | } | 67 | } |
847 | @@ -69,7 +75,7 @@ | |||
848 | 69 | protected IEnumerable<Act> ActionsForItem (Item item) | 75 | protected IEnumerable<Act> ActionsForItem (Item item) |
849 | 70 | { | 76 | { |
850 | 71 | return Services.Core.GetActionsForItemOrderedByRelevance (item, false) | 77 | return Services.Core.GetActionsForItemOrderedByRelevance (item, false) |
852 | 72 | .Where (act => act.GetType ().Name != "CopyToClipboardAction") | 78 | .Where (act => !blacklist.Contains (act.GetType ().Name)) |
853 | 73 | .OrderByDescending (act => act.GetType ().Name != "WindowCloseAction") | 79 | .OrderByDescending (act => act.GetType ().Name != "WindowCloseAction") |
854 | 74 | .ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction") | 80 | .ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction") |
855 | 75 | .ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction") | 81 | .ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction") |
856 | @@ -77,10 +83,7 @@ | |||
857 | 77 | .ThenBy (act => act.Name); | 83 | .ThenBy (act => act.Name); |
858 | 78 | } | 84 | } |
859 | 79 | 85 | ||
864 | 80 | protected virtual void Launch () | 86 | protected abstract void Launch (); |
861 | 81 | { | ||
862 | 82 | return; | ||
863 | 83 | } | ||
865 | 84 | 87 | ||
866 | 85 | public override void Scrolled (Gdk.ScrollDirection direction) | 88 | public override void Scrolled (Gdk.ScrollDirection direction) |
867 | 86 | { | 89 | { |
868 | @@ -115,12 +118,12 @@ | |||
869 | 115 | 118 | ||
870 | 116 | public override void Clicked (uint button, Gdk.ModifierType state, Gdk.Point position) | 119 | public override void Clicked (uint button, Gdk.ModifierType state, Gdk.Point position) |
871 | 117 | { | 120 | { |
873 | 118 | if (!Applications.Any () || !HasVisibleApps || button == 2) { | 121 | if (!Windows.Any () || !HasVisibleApps || button == 2) { |
874 | 119 | AnimationType = ClickAnimationType.Bounce; | 122 | AnimationType = ClickAnimationType.Bounce; |
875 | 120 | Launch (); | 123 | Launch (); |
876 | 121 | } else if (button == 1) { | 124 | } else if (button == 1) { |
877 | 122 | AnimationType = ClickAnimationType.Darken; | 125 | AnimationType = ClickAnimationType.Darken; |
879 | 123 | WindowUtils.PerformLogicalClick (Applications); | 126 | WindowUtils.PerformLogicalClick (Windows); |
880 | 124 | } else { | 127 | } else { |
881 | 125 | AnimationType = ClickAnimationType.None; | 128 | AnimationType = ClickAnimationType.None; |
882 | 126 | } | 129 | } |
883 | 127 | 130 | ||
884 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs' | |||
885 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs 2009-03-07 22:50:28 +0000 | |||
886 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs 2009-03-26 14:42:21 +0000 | |||
887 | @@ -39,7 +39,8 @@ | |||
888 | 39 | const int Height = 22; | 39 | const int Height = 22; |
889 | 40 | 40 | ||
890 | 41 | Gtk.Widget widget; | 41 | Gtk.Widget widget; |
892 | 42 | bool hovered; | 42 | bool hovered, tooltip; |
893 | 43 | string description, icon; | ||
894 | 43 | 44 | ||
895 | 44 | public bool Dark { get; set; } | 45 | public bool Dark { get; set; } |
896 | 45 | 46 | ||
897 | @@ -47,33 +48,60 @@ | |||
898 | 47 | get { return 1; } | 48 | get { return 1; } |
899 | 48 | } | 49 | } |
900 | 49 | 50 | ||
914 | 50 | public override Gtk.Widget Widget { | 51 | public override Gtk.Widget Widget { |
915 | 51 | get { | 52 | get { return widget; } |
916 | 52 | if (widget == null) | 53 | } |
917 | 53 | widget = BuildWidget (); | 54 | |
918 | 54 | return widget; | 55 | private Gdk.Pixbuf Pixbuf { get; set; } |
919 | 55 | } | 56 | |
920 | 56 | } | 57 | protected string Description { |
921 | 57 | 58 | get { | |
922 | 58 | protected virtual string Description { get; set; } | 59 | return description; |
923 | 59 | 60 | } | |
924 | 60 | protected virtual string Icon { get; set; } | 61 | set { |
925 | 61 | 62 | description = value; | |
926 | 62 | protected virtual bool UseTooltip { get; set; } | 63 | BuildWidget (); |
927 | 64 | } | ||
928 | 65 | } | ||
929 | 66 | |||
930 | 67 | protected string Icon { | ||
931 | 68 | get { | ||
932 | 69 | return icon; | ||
933 | 70 | } | ||
934 | 71 | set { | ||
935 | 72 | icon = value; | ||
936 | 73 | BuildWidget (); | ||
937 | 74 | } | ||
938 | 75 | } | ||
939 | 76 | |||
940 | 77 | protected bool UseTooltip { | ||
941 | 78 | get { | ||
942 | 79 | return tooltip; | ||
943 | 80 | } | ||
944 | 81 | set { | ||
945 | 82 | |||
946 | 83 | tooltip = value; | ||
947 | 84 | BuildWidget (); | ||
948 | 85 | } | ||
949 | 86 | } | ||
950 | 63 | 87 | ||
951 | 64 | public AbstractMenuButtonArgs () | 88 | public AbstractMenuButtonArgs () |
952 | 65 | { | 89 | { |
953 | 66 | |||
954 | 67 | } | 90 | } |
955 | 68 | 91 | ||
956 | 69 | public AbstractMenuButtonArgs (string description, string icon) | 92 | public AbstractMenuButtonArgs (string description, string icon) |
957 | 70 | { | 93 | { |
960 | 71 | Description = GLib.Markup.EscapeText (Catalog.GetString (description)); | 94 | this.description = GLib.Markup.EscapeText (Catalog.GetString (description)); |
961 | 72 | Icon = icon; | 95 | this.icon = icon; |
962 | 96 | |||
963 | 97 | BuildWidget (); | ||
964 | 73 | } | 98 | } |
965 | 74 | 99 | ||
967 | 75 | Widget BuildWidget () | 100 | void BuildWidget () |
968 | 76 | { | 101 | { |
969 | 102 | if (widget != null) | ||
970 | 103 | widget.Destroy (); | ||
971 | 104 | |||
972 | 77 | DrawingArea button = new DrawingArea (); | 105 | DrawingArea button = new DrawingArea (); |
973 | 78 | 106 | ||
974 | 79 | button.ExposeEvent += HandleExposeEvent; | 107 | button.ExposeEvent += HandleExposeEvent; |
975 | @@ -88,7 +116,12 @@ | |||
976 | 88 | if (UseTooltip) | 116 | if (UseTooltip) |
977 | 89 | button.TooltipText = Description; | 117 | button.TooltipText = Description; |
978 | 90 | 118 | ||
980 | 91 | return button; | 119 | widget = button; |
981 | 120 | |||
982 | 121 | if (Pixbuf != null) | ||
983 | 122 | Pixbuf.Dispose (); | ||
984 | 123 | |||
985 | 124 | Pixbuf = GetPixbuf (Height - 8); | ||
986 | 92 | } | 125 | } |
987 | 93 | 126 | ||
988 | 94 | void HandleButtonReleaseEvent(object o, ButtonReleaseEventArgs args) | 127 | void HandleButtonReleaseEvent(object o, ButtonReleaseEventArgs args) |
989 | @@ -135,27 +168,31 @@ | |||
990 | 135 | 168 | ||
991 | 136 | int width = area.Width - WidthBuffer * 2 - 25; | 169 | int width = area.Width - WidthBuffer * 2 - 25; |
992 | 137 | 170 | ||
1008 | 138 | TextRenderContext renderContext = new TextRenderContext (cr, string.Format (FormatString, Description), width); | 171 | if (!string.IsNullOrEmpty (Description)) { |
1009 | 139 | 172 | TextRenderContext renderContext = new TextRenderContext (cr, string.Format (FormatString, Description), width); | |
1010 | 140 | renderContext.LeftCenteredPoint = new Gdk.Point (area.X + WidthBuffer + 25, area.Y + area.Height / 2); | 173 | |
1011 | 141 | renderContext.Alignment = Pango.Alignment.Left; | 174 | renderContext.LeftCenteredPoint = new Gdk.Point (area.X + WidthBuffer + 25, area.Y + area.Height / 2); |
1012 | 142 | renderContext.EllipsizeMode = Pango.EllipsizeMode.End; | 175 | renderContext.Alignment = Pango.Alignment.Left; |
1013 | 143 | 176 | renderContext.EllipsizeMode = Pango.EllipsizeMode.End; | |
1014 | 144 | DockServices.DrawingService.TextPathAtPoint (renderContext); | 177 | |
1015 | 145 | 178 | DockServices.DrawingService.TextPathAtPoint (renderContext); | |
1016 | 146 | cr.Color = new Cairo.Color (1, 1, 1); | 179 | |
1017 | 147 | cr.Fill (); | 180 | cr.Color = new Cairo.Color (1, 1, 1); |
1018 | 148 | 181 | cr.Fill (); | |
1019 | 149 | Gdk.Pixbuf pbuf = GetPixbuf (Height - 8); | 182 | } |
1020 | 150 | CairoHelper.SetSourcePixbuf (cr, pbuf, WidthBuffer, (Height - pbuf.Height) / 2); | 183 | |
1021 | 151 | cr.PaintWithAlpha (IconOpacity); | 184 | if (Pixbuf != null) { |
1022 | 152 | pbuf.Dispose (); | 185 | CairoHelper.SetSourcePixbuf (cr, Pixbuf, WidthBuffer, (Height - Pixbuf.Height) / 2); |
1023 | 186 | cr.PaintWithAlpha (IconOpacity); | ||
1024 | 187 | } | ||
1025 | 153 | } | 188 | } |
1026 | 154 | } | 189 | } |
1027 | 155 | 190 | ||
1028 | 156 | protected virtual Gdk.Pixbuf GetPixbuf (int size) | 191 | protected virtual Gdk.Pixbuf GetPixbuf (int size) |
1029 | 157 | { | 192 | { |
1031 | 158 | return IconProvider.PixbufFromIconName (Icon, size); | 193 | if (!string.IsNullOrEmpty (Icon)) |
1032 | 194 | return IconProvider.PixbufFromIconName (Icon, size); | ||
1033 | 195 | return null; | ||
1034 | 159 | } | 196 | } |
1035 | 160 | 197 | ||
1036 | 161 | public abstract void Action (); | 198 | public abstract void Action (); |
1037 | @@ -169,6 +206,7 @@ | |||
1038 | 169 | public override void Dispose () | 206 | public override void Dispose () |
1039 | 170 | { | 207 | { |
1040 | 171 | Widget.Destroy (); | 208 | Widget.Destroy (); |
1041 | 209 | Pixbuf.Dispose (); | ||
1042 | 172 | base.Dispose (); | 210 | base.Dispose (); |
1043 | 173 | } | 211 | } |
1044 | 174 | 212 | ||
1045 | 175 | 213 | ||
1046 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs' | |||
1047 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs 2009-03-20 20:43:06 +0000 | |||
1048 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs 2009-03-26 04:33:12 +0000 | |||
1049 | @@ -38,7 +38,6 @@ | |||
1050 | 38 | return (window.IsMinimized) ? .5 : base.IconOpacity; | 38 | return (window.IsMinimized) ? .5 : base.IconOpacity; |
1051 | 39 | } | 39 | } |
1052 | 40 | } | 40 | } |
1053 | 41 | |||
1054 | 42 | 41 | ||
1055 | 43 | public WindowMenuButtonArgs (Wnck.Window window, string description, string icon) : base (description, icon) | 42 | public WindowMenuButtonArgs (Wnck.Window window, string description, string icon) : base (description, icon) |
1056 | 44 | { | 43 | { |
1057 | 45 | 44 | ||
1058 | === modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs' | |||
1059 | --- Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs 2009-03-20 20:43:06 +0000 | |||
1060 | +++ Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs 2009-03-24 16:08:07 +0000 | |||
1061 | @@ -78,7 +78,8 @@ | |||
1062 | 78 | DockOrientation orientation) | 78 | DockOrientation orientation) |
1063 | 79 | { | 79 | { |
1064 | 80 | Surface sr; | 80 | Surface sr; |
1066 | 81 | sr = similar.CreateSimilar (similar.Content, maxWidth, Height); | 81 | // we are going to give ourselves a bit of a buffer due to pango weirdness |
1067 | 82 | sr = similar.CreateSimilar (similar.Content, maxWidth + 5, Height); | ||
1068 | 82 | 83 | ||
1069 | 83 | Context cr = new Context (sr); | 84 | Context cr = new Context (sr); |
1070 | 84 | 85 | ||
1071 | @@ -89,7 +90,7 @@ | |||
1072 | 89 | cr.NewPath (); | 90 | cr.NewPath (); |
1073 | 90 | 91 | ||
1074 | 91 | int localHeight = textArea.Height; | 92 | int localHeight = textArea.Height; |
1076 | 92 | cr.SetRoundedRectanglePath (textArea.X + .5, .5, textArea.Width + 20 - 1, localHeight + 10 - 1, 5); | 93 | cr.SetRoundedRectanglePath (textArea.X + .5, .5, textArea.Width + 20 - 1, localHeight + 10 - 1, 5); |
1077 | 93 | 94 | ||
1078 | 94 | cr.Color = new Cairo.Color (0.1, 0.1, 0.1, .75); | 95 | cr.Color = new Cairo.Color (0.1, 0.1, 0.1, .75); |
1079 | 95 | cr.FillPreserve (); | 96 | cr.FillPreserve (); |
1080 | 96 | 97 | ||
1081 | === modified file 'Do.Interface.Wink/Do.Interface.Wink.mdp' | |||
1082 | --- Do.Interface.Wink/Do.Interface.Wink.mdp 2009-03-20 20:43:06 +0000 | |||
1083 | +++ Do.Interface.Wink/Do.Interface.Wink.mdp 2009-03-31 03:39:44 +0000 | |||
1084 | @@ -20,11 +20,20 @@ | |||
1085 | 20 | <File name="src/AssemblyInfo.cs" subtype="Code" buildaction="Compile" /> | 20 | <File name="src/AssemblyInfo.cs" subtype="Code" buildaction="Compile" /> |
1086 | 21 | <File name="src/Do.Interface.Wink/WindowControl.cs" subtype="Code" buildaction="Compile" /> | 21 | <File name="src/Do.Interface.Wink/WindowControl.cs" subtype="Code" buildaction="Compile" /> |
1087 | 22 | <File name="src/Do.Interface.Wink/WindowUtils.cs" subtype="Code" buildaction="Compile" /> | 22 | <File name="src/Do.Interface.Wink/WindowUtils.cs" subtype="Code" buildaction="Compile" /> |
1088 | 23 | <File name="src/Do.Interface.Wink/ClickAction.cs" subtype="Code" buildaction="Compile" /> | ||
1089 | 24 | <File name="src/Do.Interface.Wink/ScreenUtils.cs" subtype="Code" buildaction="Compile" /> | ||
1090 | 25 | <File name="src/Do.Interface.Wink/Viewport.cs" subtype="Code" buildaction="Compile" /> | ||
1091 | 26 | <File name="src/Do.Interface.Xlib" subtype="Directory" buildaction="Compile" /> | ||
1092 | 27 | <File name="src/Do.Interface.Xlib/X11Atoms.cs" subtype="Code" buildaction="Compile" /> | ||
1093 | 28 | <File name="src/Do.Interface.Xlib/Xlib.cs" subtype="Code" buildaction="Compile" /> | ||
1094 | 23 | </Contents> | 29 | </Contents> |
1095 | 24 | <References> | 30 | <References> |
1096 | 25 | <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | 31 | <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
1097 | 26 | <ProjectReference type="Gac" localcopy="True" refto="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | 32 | <ProjectReference type="Gac" localcopy="True" refto="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> |
1098 | 27 | <ProjectReference type="Gac" localcopy="True" refto="wnck-sharp, Version=2.20.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> | 33 | <ProjectReference type="Gac" localcopy="True" refto="wnck-sharp, Version=2.20.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> |
1099 | 28 | <ProjectReference type="Project" localcopy="True" refto="Do.Platform" /> | 34 | <ProjectReference type="Project" localcopy="True" refto="Do.Platform" /> |
1100 | 35 | <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> | ||
1101 | 36 | <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" /> | ||
1102 | 37 | <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> | ||
1103 | 29 | </References> | 38 | </References> |
1104 | 30 | </Project> | 39 | </Project> |
1105 | 31 | \ No newline at end of file | 40 | \ No newline at end of file |
1106 | 32 | 41 | ||
1107 | === modified file 'Do.Interface.Wink/Makefile.am' | |||
1108 | --- Do.Interface.Wink/Makefile.am 2009-03-20 23:06:10 +0000 | |||
1109 | +++ Do.Interface.Wink/Makefile.am 2009-03-31 16:23:23 +0000 | |||
1110 | @@ -8,8 +8,13 @@ | |||
1111 | 8 | 8 | ||
1112 | 9 | FILES = \ | 9 | FILES = \ |
1113 | 10 | src/AssemblyInfo.cs \ | 10 | src/AssemblyInfo.cs \ |
1114 | 11 | src/Do.Interface.Xlib/Xlib.cs \ | ||
1115 | 12 | src/Do.Interface.Xlib/X11Atoms.cs \ | ||
1116 | 13 | src/Do.Interface.Wink/ClickAction.cs \ | ||
1117 | 11 | src/Do.Interface.Wink/WindowControl.cs \ | 14 | src/Do.Interface.Wink/WindowControl.cs \ |
1119 | 12 | src/Do.Interface.Wink/WindowUtils.cs | 15 | src/Do.Interface.Wink/WindowUtils.cs \ |
1120 | 16 | src/Do.Interface.Wink/ScreenUtils.cs \ | ||
1121 | 17 | src/Do.Interface.Wink/Viewport.cs | ||
1122 | 13 | 18 | ||
1123 | 14 | #RESOURCES = \ | 19 | #RESOURCES = \ |
1124 | 15 | # Resources/Do.Interface.Wnck.addin.xml | 20 | # Resources/Do.Interface.Wnck.addin.xml |
1125 | @@ -17,11 +22,12 @@ | |||
1126 | 17 | REFERENCES = \ | 22 | REFERENCES = \ |
1127 | 18 | System \ | 23 | System \ |
1128 | 19 | System.Core \ | 24 | System.Core \ |
1129 | 25 | Mono.Posix \ | ||
1130 | 20 | $(GTK_SHARP_20_LIBS) \ | 26 | $(GTK_SHARP_20_LIBS) \ |
1131 | 21 | $(WNCK_SHARP_10_LIBS) | 27 | $(WNCK_SHARP_10_LIBS) |
1132 | 22 | 28 | ||
1133 | 23 | PROJECT_REFERENCES = \ | 29 | PROJECT_REFERENCES = \ |
1134 | 24 | Do.Platform | 30 | Do.Platform |
1135 | 25 | 31 | ||
1138 | 26 | #module_DATA += $(ASSEMBLY).dll.config | 32 | module_DATA += $(ASSEMBLY).dll.config |
1139 | 27 | #EXTRA_DIST += $(ASSEMBLY).dll.config | 33 | EXTRA_DIST += $(ASSEMBLY).dll.config |
1140 | 28 | 34 | ||
1141 | === added file 'Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs' | |||
1142 | --- Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs 1970-01-01 00:00:00 +0000 | |||
1143 | +++ Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs 2009-03-25 19:49:42 +0000 | |||
1144 | @@ -0,0 +1,31 @@ | |||
1145 | 1 | // | ||
1146 | 2 | // Copyright (C) 2009 GNOME Do | ||
1147 | 3 | // | ||
1148 | 4 | // This program is free software: you can redistribute it and/or modify | ||
1149 | 5 | // it under the terms of the GNU General Public License as published by | ||
1150 | 6 | // the Free Software Foundation, either version 3 of the License, or | ||
1151 | 7 | // (at your option) any later version. | ||
1152 | 8 | // | ||
1153 | 9 | // This program is distributed in the hope that it will be useful, | ||
1154 | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1155 | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1156 | 12 | // GNU General Public License for more details. | ||
1157 | 13 | // | ||
1158 | 14 | // You should have received a copy of the GNU General Public License | ||
1159 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1160 | 16 | // | ||
1161 | 17 | |||
1162 | 18 | using System; | ||
1163 | 19 | |||
1164 | 20 | namespace Do.Interface.Wink | ||
1165 | 21 | { | ||
1166 | 22 | |||
1167 | 23 | |||
1168 | 24 | public enum ClickAction | ||
1169 | 25 | { | ||
1170 | 26 | Focus, | ||
1171 | 27 | Minimize, | ||
1172 | 28 | Restore, | ||
1173 | 29 | None, | ||
1174 | 30 | } | ||
1175 | 31 | } | ||
1176 | 0 | 32 | ||
1177 | === added file 'Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs' | |||
1178 | --- Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs 1970-01-01 00:00:00 +0000 | |||
1179 | +++ Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs 2009-04-01 01:08:07 +0000 | |||
1180 | @@ -0,0 +1,138 @@ | |||
1181 | 1 | // | ||
1182 | 2 | // Copyright (C) 2009 GNOME Do | ||
1183 | 3 | // | ||
1184 | 4 | // This program is free software: you can redistribute it and/or modify | ||
1185 | 5 | // it under the terms of the GNU General Public License as published by | ||
1186 | 6 | // the Free Software Foundation, either version 3 of the License, or | ||
1187 | 7 | // (at your option) any later version. | ||
1188 | 8 | // | ||
1189 | 9 | // This program is distributed in the hope that it will be useful, | ||
1190 | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1191 | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1192 | 12 | // GNU General Public License for more details. | ||
1193 | 13 | // | ||
1194 | 14 | // You should have received a copy of the GNU General Public License | ||
1195 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1196 | 16 | // | ||
1197 | 17 | |||
1198 | 18 | using System; | ||
1199 | 19 | using System.Collections.Generic; | ||
1200 | 20 | using System.Linq; | ||
1201 | 21 | |||
1202 | 22 | using Mono.Unix; | ||
1203 | 23 | |||
1204 | 24 | using Wnck; | ||
1205 | 25 | |||
1206 | 26 | namespace Do.Interface.Wink | ||
1207 | 27 | { | ||
1208 | 28 | |||
1209 | 29 | |||
1210 | 30 | public static class ScreenUtils | ||
1211 | 31 | { | ||
1212 | 32 | static string ViewportFormatString = Catalog.GetString ("Desktop") + " {0}"; | ||
1213 | 33 | static List<Viewport> viewports; | ||
1214 | 34 | |||
1215 | 35 | public static Viewport ActiveViewport { | ||
1216 | 36 | get { | ||
1217 | 37 | Workspace wsp = Wnck.Screen.Default.ActiveWorkspace; | ||
1218 | 38 | Gdk.Rectangle geo = new Gdk.Rectangle (wsp.ViewportX, wsp.ViewportY, wsp.Screen.Width, wsp.Screen.Height); | ||
1219 | 39 | if (viewports.Any (vp => vp.Area == geo)) | ||
1220 | 40 | return viewports.First (vp => vp.Area == geo); | ||
1221 | 41 | return null; | ||
1222 | 42 | } | ||
1223 | 43 | } | ||
1224 | 44 | |||
1225 | 45 | public static IEnumerable<Viewport> Viewports { | ||
1226 | 46 | get { return viewports.AsEnumerable (); } | ||
1227 | 47 | } | ||
1228 | 48 | |||
1229 | 49 | static ScreenUtils () | ||
1230 | 50 | { | ||
1231 | 51 | Wnck.Screen.Default.ViewportsChanged += HandleViewportsChanged; | ||
1232 | 52 | Wnck.Screen.Default.WorkspaceCreated += HandleWorkspaceCreated; | ||
1233 | 53 | Wnck.Screen.Default.WorkspaceDestroyed += HandleWorkspaceDestroyed; | ||
1234 | 54 | |||
1235 | 55 | // Wnck.Screen.Default.ForceUpdate (); | ||
1236 | 56 | UpdateViewports (); | ||
1237 | 57 | } | ||
1238 | 58 | |||
1239 | 59 | static void HandleWorkspaceDestroyed(object o, WorkspaceDestroyedArgs args) | ||
1240 | 60 | { | ||
1241 | 61 | UpdateViewports (); | ||
1242 | 62 | } | ||
1243 | 63 | |||
1244 | 64 | static void HandleWorkspaceCreated(object o, WorkspaceCreatedArgs args) | ||
1245 | 65 | { | ||
1246 | 66 | UpdateViewports (); | ||
1247 | 67 | } | ||
1248 | 68 | |||
1249 | 69 | static void HandleViewportsChanged(object sender, EventArgs e) | ||
1250 | 70 | { | ||
1251 | 71 | UpdateViewports (); | ||
1252 | 72 | } | ||
1253 | 73 | |||
1254 | 74 | public static bool DesktopShow (Screen screen) | ||
1255 | 75 | { | ||
1256 | 76 | return screen.ShowingDesktop; | ||
1257 | 77 | } | ||
1258 | 78 | |||
1259 | 79 | public static void ShowDesktop (Screen screen) | ||
1260 | 80 | { | ||
1261 | 81 | if (!screen.ShowingDesktop) | ||
1262 | 82 | screen.ToggleShowingDesktop (true); | ||
1263 | 83 | } | ||
1264 | 84 | |||
1265 | 85 | public static void UnshowDesktop (Screen screen) | ||
1266 | 86 | { | ||
1267 | 87 | if (screen.ShowingDesktop) | ||
1268 | 88 | screen.ToggleShowingDesktop (false); | ||
1269 | 89 | } | ||
1270 | 90 | |||
1271 | 91 | public static IEnumerable<Window> ViewportWindows (Viewport viewport) | ||
1272 | 92 | { | ||
1273 | 93 | var windows = WindowUtils.GetWindows () | ||
1274 | 94 | .Where (w => w.WindowType != WindowType.Dock && !w.IsSkipTasklist); | ||
1275 | 95 | |||
1276 | 96 | foreach (Window window in windows) { | ||
1277 | 97 | if (viewport.WindowCenterInViewport (window)) | ||
1278 | 98 | yield return window; | ||
1279 | 99 | } | ||
1280 | 100 | } | ||
1281 | 101 | |||
1282 | 102 | static void UpdateViewports () | ||
1283 | 103 | { | ||
1284 | 104 | viewports = new List<Viewport> (); | ||
1285 | 105 | int currentViewport = 1; | ||
1286 | 106 | foreach (Wnck.Workspace workspace in Wnck.Screen.Default.Workspaces) { | ||
1287 | 107 | if (workspace.IsVirtual) { | ||
1288 | 108 | int viewportWidth; | ||
1289 | 109 | int viewportHeight; | ||
1290 | 110 | viewportWidth = workspace.Screen.Width; | ||
1291 | 111 | viewportHeight = workspace.Screen.Height; | ||
1292 | 112 | |||
1293 | 113 | int rows = workspace.Height / viewportHeight; | ||
1294 | 114 | int columns = workspace.Width / viewportWidth; | ||
1295 | 115 | |||
1296 | 116 | for (int i = 0; i < rows; i++) { | ||
1297 | 117 | for (int j = 0; j < columns; j++) { | ||
1298 | 118 | Gdk.Rectangle area = new Gdk.Rectangle (j * viewportWidth, | ||
1299 | 119 | i * viewportHeight, | ||
1300 | 120 | viewportWidth, | ||
1301 | 121 | viewportHeight); | ||
1302 | 122 | viewports.Add (new Viewport (string.Format (ViewportFormatString, currentViewport), | ||
1303 | 123 | area, | ||
1304 | 124 | workspace)); | ||
1305 | 125 | currentViewport++; | ||
1306 | 126 | } | ||
1307 | 127 | } | ||
1308 | 128 | } else { | ||
1309 | 129 | Viewport viewport = new Viewport (string.Format (ViewportFormatString, currentViewport), | ||
1310 | 130 | new Gdk.Rectangle (0, 0, workspace.Width, workspace.Height), | ||
1311 | 131 | workspace); | ||
1312 | 132 | viewports.Add (viewport); | ||
1313 | 133 | currentViewport++; | ||
1314 | 134 | } | ||
1315 | 135 | } | ||
1316 | 136 | } | ||
1317 | 137 | } | ||
1318 | 138 | } | ||
1319 | 0 | 139 | ||
1320 | === added file 'Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs' | |||
1321 | --- Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs 1970-01-01 00:00:00 +0000 | |||
1322 | +++ Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs 2009-03-31 16:23:23 +0000 | |||
1323 | @@ -0,0 +1,142 @@ | |||
1324 | 1 | // | ||
1325 | 2 | // Copyright (C) 2009 GNOME Do | ||
1326 | 3 | // | ||
1327 | 4 | // This program is free software: you can redistribute it and/or modify | ||
1328 | 5 | // it under the terms of the GNU General Public License as published by | ||
1329 | 6 | // the Free Software Foundation, either version 3 of the License, or | ||
1330 | 7 | // (at your option) any later version. | ||
1331 | 8 | // | ||
1332 | 9 | // This program is distributed in the hope that it will be useful, | ||
1333 | 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1334 | 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1335 | 12 | // GNU General Public License for more details. | ||
1336 | 13 | // | ||
1337 | 14 | // You should have received a copy of the GNU General Public License | ||
1338 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1339 | 16 | // | ||
1340 | 17 | |||
1341 | 18 | using System; | ||
1342 | 19 | using System.Collections.Generic; | ||
1343 | 20 | using System.Runtime.InteropServices; | ||
1344 | 21 | |||
1345 | 22 | |||
1346 | 23 | using Gdk; | ||
1347 | 24 | using Wnck; | ||
1348 | 25 | |||
1349 | 26 | using Do.Platform; | ||
1350 | 27 | using Do.Interface.Xlib; | ||
1351 | 28 | |||
1352 | 29 | namespace Do.Interface.Wink | ||
1353 | 30 | { | ||
1354 | 31 | |||
1355 | 32 | |||
1356 | 33 | public class Viewport | ||
1357 | 34 | { | ||
1358 | 35 | Workspace parent; | ||
1359 | 36 | Rectangle area; | ||
1360 | 37 | |||
1361 | 38 | public string Name { get; private set; } | ||
1362 | 39 | |||
1363 | 40 | internal Rectangle Area { | ||
1364 | 41 | get { return area; } | ||
1365 | 42 | } | ||
1366 | 43 | |||
1367 | 44 | internal Viewport(string name, Rectangle area, Workspace parent) | ||
1368 | 45 | { | ||
1369 | 46 | this.area = area; | ||
1370 | 47 | this.parent = parent; | ||
1371 | 48 | Name = name; | ||
1372 | 49 | } | ||
1373 | 50 | |||
1374 | 51 | public void MoveWindowInto (Wnck.Window window) | ||
1375 | 52 | { | ||
1376 | 53 | if (parent.IsVirtual) { | ||
1377 | 54 | Rectangle geo; | ||
1378 | 55 | window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height); | ||
1379 | 56 | |||
1380 | 57 | geo.X += window.Workspace.ViewportX; | ||
1381 | 58 | geo.Y += window.Workspace.ViewportY; | ||
1382 | 59 | |||
1383 | 60 | int x = area.X + (geo.X % area.Width); | ||
1384 | 61 | int y = area.Y + (geo.Y % area.Height); | ||
1385 | 62 | |||
1386 | 63 | x -= window.Workspace.ViewportX; | ||
1387 | 64 | y -= window.Workspace.ViewportY; | ||
1388 | 65 | |||
1389 | 66 | if (string.Compare (window.Screen.WindowManagerName, "compiz", true) == 0) { | ||
1390 | 67 | // This is a compiz-ism. Don't know when they will fix it. You must subtract the top and left | ||
1391 | 68 | // frame extents from a move operation to get the window to actually show in the right spot. | ||
1392 | 69 | // Save for maybe kwin, I think only compiz uses Viewports anyhow, so this is ok. | ||
1393 | 70 | int [] extents = GetWindowFrameExtents (window); | ||
1394 | 71 | int left_extent = extents [0]; | ||
1395 | 72 | int top_extent = extents [2]; | ||
1396 | 73 | |||
1397 | 74 | x -= left_extent; | ||
1398 | 75 | y -= top_extent; | ||
1399 | 76 | } | ||
1400 | 77 | |||
1401 | 78 | WindowMoveResizeMask mask = WindowMoveResizeMask.X | WindowMoveResizeMask.Y; | ||
1402 | 79 | window.SetGeometry (WindowGravity.Current, mask, x, y, 0, 0); | ||
1403 | 80 | } else { | ||
1404 | 81 | window.MoveToWorkspace (parent); | ||
1405 | 82 | } | ||
1406 | 83 | } | ||
1407 | 84 | |||
1408 | 85 | int[] GetWindowFrameExtents (Wnck.Window window) | ||
1409 | 86 | { | ||
1410 | 87 | X11Atoms atoms = X11Atoms.Instance; | ||
1411 | 88 | |||
1412 | 89 | IntPtr display; | ||
1413 | 90 | IntPtr type; | ||
1414 | 91 | int format; | ||
1415 | 92 | IntPtr prop_return; | ||
1416 | 93 | IntPtr nitems, bytes_after; | ||
1417 | 94 | int result; | ||
1418 | 95 | int [] extents = new int[4]; | ||
1419 | 96 | |||
1420 | 97 | IntPtr window_handle = (IntPtr) window.Xid; | ||
1421 | 98 | |||
1422 | 99 | display = Xlib.Xlib.GdkDisplayXDisplay (Gdk.Screen.Default.Display); | ||
1423 | 100 | type = IntPtr.Zero; | ||
1424 | 101 | |||
1425 | 102 | result = Xlib.Xlib.XGetWindowProperty (display, window_handle, atoms._NET_FRAME_EXTENTS, (IntPtr) 0, | ||
1426 | 103 | (IntPtr) System.Int32.MaxValue, false, atoms.XA_CARDINAL, out type, out format, | ||
1427 | 104 | out nitems, out bytes_after, out prop_return); | ||
1428 | 105 | |||
1429 | 106 | if (type == atoms.XA_CARDINAL && format == 32) { | ||
1430 | 107 | extents = new int [(int) nitems]; | ||
1431 | 108 | for (int i = 0; i < (int) nitems; i++) { | ||
1432 | 109 | extents [i] = Marshal.ReadInt32 (prop_return, i * 4); | ||
1433 | 110 | } | ||
1434 | 111 | } | ||
1435 | 112 | |||
1436 | 113 | return extents; | ||
1437 | 114 | } | ||
1438 | 115 | |||
1439 | 116 | public bool WindowVisibleInVeiwport (Wnck.Window window) | ||
1440 | 117 | { | ||
1441 | 118 | Rectangle geo; | ||
1442 | 119 | window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height); | ||
1443 | 120 | geo.X += parent.ViewportX; | ||
1444 | 121 | geo.Y += parent.ViewportY; | ||
1445 | 122 | |||
1446 | 123 | return area.IntersectsWith (geo); | ||
1447 | 124 | } | ||
1448 | 125 | |||
1449 | 126 | public bool WindowCenterInViewport (Wnck.Window window) | ||
1450 | 127 | { | ||
1451 | 128 | Rectangle geo; | ||
1452 | 129 | window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height); | ||
1453 | 130 | geo.X += parent.ViewportX; | ||
1454 | 131 | geo.Y += parent.ViewportY; | ||
1455 | 132 | |||
1456 | 133 | Point center = new Point (geo.X + geo.Width / 2, geo.Y + geo.Height / 2); | ||
1457 | 134 | return Contains (center); | ||
1458 | 135 | } | ||
1459 | 136 | |||
1460 | 137 | public bool Contains (Gdk.Point point) | ||
1461 | 138 | { | ||
1462 | 139 | return area.Contains (point); | ||
1463 | 140 | } | ||
1464 | 141 | } | ||
1465 | 142 | } | ||
1466 | 0 | 143 | ||
1467 | === modified file 'Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs' | |||
1468 | --- Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs 2009-03-20 20:43:06 +0000 | |||
1469 | +++ Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs 2009-03-31 03:39:44 +0000 | |||
1470 | @@ -88,11 +88,18 @@ | |||
1471 | 88 | 88 | ||
1472 | 89 | public static void FocusWindows (IEnumerable<Window> windows) | 89 | public static void FocusWindows (IEnumerable<Window> windows) |
1473 | 90 | { | 90 | { |
1478 | 91 | foreach (Window window in windows.Reverse ()) { | 91 | if (!windows.Any ()) |
1479 | 92 | if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) { | 92 | return; |
1480 | 93 | window.CenterAndFocusWindow (); | 93 | |
1481 | 94 | System.Threading.Thread.Sleep (SleepTime); | 94 | if (windows.Any (w => w.IsInViewport (w.Screen.ActiveWorkspace))) { |
1482 | 95 | foreach (Window window in windows.Reverse ()) { | ||
1483 | 96 | if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) { | ||
1484 | 97 | window.CenterAndFocusWindow (); | ||
1485 | 98 | System.Threading.Thread.Sleep (SleepTime); | ||
1486 | 99 | } | ||
1487 | 95 | } | 100 | } |
1488 | 101 | } else { | ||
1489 | 102 | windows.First ().CenterAndFocusWindow (); | ||
1490 | 96 | } | 103 | } |
1491 | 97 | 104 | ||
1492 | 98 | if (windows.Count () <= 1) | 105 | if (windows.Count () <= 1) |
1493 | @@ -102,7 +109,9 @@ | |||
1494 | 102 | // sometimes compiz plays badly. This hacks around it | 109 | // sometimes compiz plays badly. This hacks around it |
1495 | 103 | uint time = Gtk.Global.CurrentEventTime + 200; | 110 | uint time = Gtk.Global.CurrentEventTime + 200; |
1496 | 104 | GLib.Timeout.Add (200, delegate { | 111 | GLib.Timeout.Add (200, delegate { |
1498 | 105 | windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time); | 112 | try { //unimportant if this fails, its just "nice" |
1499 | 113 | windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time); | ||
1500 | 114 | } catch { } | ||
1501 | 106 | return false; | 115 | return false; |
1502 | 107 | }); | 116 | }); |
1503 | 108 | } | 117 | } |
1504 | @@ -187,6 +196,17 @@ | |||
1505 | 187 | window.Maximize (); | 196 | window.Maximize (); |
1506 | 188 | } | 197 | } |
1507 | 189 | 198 | ||
1508 | 199 | public static void MoveToWorkspace (Window window, Workspace workspace) | ||
1509 | 200 | { | ||
1510 | 201 | MoveToWorkspace (new [] {window}, workspace); | ||
1511 | 202 | } | ||
1512 | 203 | |||
1513 | 204 | public static void MoveToWorkspace (IEnumerable<Window> windows, Workspace workspace) | ||
1514 | 205 | { | ||
1515 | 206 | foreach (Window window in windows.Where (w => w.Workspace != workspace)) | ||
1516 | 207 | window.MoveToWorkspace (workspace); | ||
1517 | 208 | } | ||
1518 | 209 | |||
1519 | 190 | /// <summary> | 210 | /// <summary> |
1520 | 191 | /// Moves the current viewport to the selected window and then raises it | 211 | /// Moves the current viewport to the selected window and then raises it |
1521 | 192 | /// </summary> | 212 | /// </summary> |
1522 | 193 | 213 | ||
1523 | === modified file 'Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs' | |||
1524 | --- Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs 2009-03-21 02:35:05 +0000 | |||
1525 | +++ Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs 2009-04-01 01:08:07 +0000 | |||
1526 | @@ -29,12 +29,6 @@ | |||
1527 | 29 | 29 | ||
1528 | 30 | namespace Do.Interface.Wink | 30 | namespace Do.Interface.Wink |
1529 | 31 | { | 31 | { |
1530 | 32 | public enum ClickAction { | ||
1531 | 33 | Focus, | ||
1532 | 34 | Minimize, | ||
1533 | 35 | Restore, | ||
1534 | 36 | None, | ||
1535 | 37 | } | ||
1536 | 38 | 32 | ||
1537 | 39 | public static class WindowUtils | 33 | public static class WindowUtils |
1538 | 40 | { | 34 | { |
1539 | @@ -42,7 +36,7 @@ | |||
1540 | 42 | get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); } | 36 | get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); } |
1541 | 43 | } | 37 | } |
1542 | 44 | 38 | ||
1544 | 45 | public static IEnumerable<string> BadPrefixes { | 39 | static IEnumerable<string> PrefixStrings { |
1545 | 46 | get { | 40 | get { |
1546 | 47 | yield return "gksu"; | 41 | yield return "gksu"; |
1547 | 48 | yield return "sudo"; | 42 | yield return "sudo"; |
1548 | @@ -55,35 +49,46 @@ | |||
1549 | 55 | } | 49 | } |
1550 | 56 | } | 50 | } |
1551 | 57 | 51 | ||
1552 | 52 | public static IEnumerable<Regex> BadPrefixes { get; private set; } | ||
1553 | 53 | |||
1554 | 58 | static Dictionary<string, string> RemapDictionary { get; set; } | 54 | static Dictionary<string, string> RemapDictionary { get; set; } |
1555 | 59 | 55 | ||
1558 | 60 | static List<Application> application_list; | 56 | static List<Window> window_list; |
1559 | 61 | static bool application_list_update_needed; | 57 | static bool window_list_update_needed; |
1560 | 62 | 58 | ||
1561 | 63 | static Dictionary<int, string> exec_lines = new Dictionary<int, string> (); | 59 | static Dictionary<int, string> exec_lines = new Dictionary<int, string> (); |
1562 | 64 | static DateTime last_update = new DateTime (0); | 60 | static DateTime last_update = new DateTime (0); |
1563 | 65 | 61 | ||
1564 | 62 | #region ctor | ||
1565 | 66 | static WindowUtils () | 63 | static WindowUtils () |
1566 | 67 | { | 64 | { |
1567 | 65 | List<Regex> regex = new List<Regex> (); | ||
1568 | 66 | foreach (string s in PrefixStrings) { | ||
1569 | 67 | regex.Add (new Regex (string.Format ("^{0}$", s), RegexOptions.IgnoreCase)); | ||
1570 | 68 | } | ||
1571 | 69 | BadPrefixes = regex.AsEnumerable (); | ||
1572 | 70 | |||
1573 | 68 | Wnck.Screen.Default.WindowClosed += delegate { | 71 | Wnck.Screen.Default.WindowClosed += delegate { |
1575 | 69 | application_list_update_needed = true; | 72 | window_list_update_needed = true; |
1576 | 70 | }; | 73 | }; |
1577 | 71 | 74 | ||
1578 | 72 | Wnck.Screen.Default.WindowOpened += delegate { | 75 | Wnck.Screen.Default.WindowOpened += delegate { |
1580 | 73 | application_list_update_needed = true; | 76 | window_list_update_needed = true; |
1581 | 74 | }; | 77 | }; |
1582 | 75 | 78 | ||
1583 | 76 | Wnck.Screen.Default.ApplicationOpened += delegate { | 79 | Wnck.Screen.Default.ApplicationOpened += delegate { |
1585 | 77 | application_list_update_needed = true; | 80 | window_list_update_needed = true; |
1586 | 78 | }; | 81 | }; |
1587 | 79 | 82 | ||
1588 | 80 | Wnck.Screen.Default.ApplicationClosed += delegate { | 83 | Wnck.Screen.Default.ApplicationClosed += delegate { |
1590 | 81 | application_list_update_needed = true; | 84 | window_list_update_needed = true; |
1591 | 82 | }; | 85 | }; |
1592 | 83 | 86 | ||
1593 | 84 | BuildRemapDictionary (); | 87 | BuildRemapDictionary (); |
1594 | 85 | } | 88 | } |
1595 | 89 | #endregion | ||
1596 | 86 | 90 | ||
1597 | 91 | #region Private Methods | ||
1598 | 87 | static void BuildRemapDictionary () | 92 | static void BuildRemapDictionary () |
1599 | 88 | { | 93 | { |
1600 | 89 | if (!File.Exists (RemapFile)) { | 94 | if (!File.Exists (RemapFile)) { |
1601 | @@ -151,117 +156,39 @@ | |||
1602 | 151 | return remapDict; | 156 | return remapDict; |
1603 | 152 | } | 157 | } |
1604 | 153 | 158 | ||
1605 | 154 | /// <summary> | ||
1606 | 155 | /// Returns a list of all applications on the default screen | ||
1607 | 156 | /// </summary> | ||
1608 | 157 | /// <returns> | ||
1609 | 158 | /// A <see cref="Application"/> array | ||
1610 | 159 | /// </returns> | ||
1611 | 160 | public static List<Application> GetApplications () | ||
1612 | 161 | { | ||
1613 | 162 | if (application_list == null || application_list_update_needed) { | ||
1614 | 163 | application_list = new List<Application> (); | ||
1615 | 164 | foreach (Window w in Wnck.Screen.Default.Windows) { | ||
1616 | 165 | if (!application_list.Contains (w.Application)) | ||
1617 | 166 | application_list.Add (w.Application); | ||
1618 | 167 | } | ||
1619 | 168 | } | ||
1620 | 169 | return application_list; | ||
1621 | 170 | } | ||
1622 | 171 | |||
1623 | 172 | /// <summary> | ||
1624 | 173 | /// Gets the command line excec string for a PID | ||
1625 | 174 | /// </summary> | ||
1626 | 175 | /// <param name="pid"> | ||
1627 | 176 | /// A <see cref="System.Int32"/> | ||
1628 | 177 | /// </param> | ||
1629 | 178 | /// <returns> | ||
1630 | 179 | /// A <see cref="System.String"/> | ||
1631 | 180 | /// </returns> | ||
1632 | 181 | public static string CmdLineForPid (int pid) | ||
1633 | 182 | { | ||
1634 | 183 | StreamReader reader; | ||
1635 | 184 | string cmdline = null; | ||
1636 | 185 | |||
1637 | 186 | try { | ||
1638 | 187 | string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine); | ||
1639 | 188 | reader = new StreamReader (procPath); | ||
1640 | 189 | cmdline = reader.ReadLine ().Replace (Convert.ToChar (0x0), ' '); | ||
1641 | 190 | reader.Close (); | ||
1642 | 191 | reader.Dispose (); | ||
1643 | 192 | } catch { } | ||
1644 | 193 | |||
1645 | 194 | return cmdline; | ||
1646 | 195 | } | ||
1647 | 196 | |||
1648 | 197 | /// <summary> | ||
1649 | 198 | /// Returns a list of applications that match an exec string | ||
1650 | 199 | /// </summary> | ||
1651 | 200 | /// <param name="exec"> | ||
1652 | 201 | /// A <see cref="System.String"/> | ||
1653 | 202 | /// </param> | ||
1654 | 203 | /// <returns> | ||
1655 | 204 | /// A <see cref="List"/> | ||
1656 | 205 | /// </returns> | ||
1657 | 206 | public static List<Application> GetApplicationList (string exec) | ||
1658 | 207 | { | ||
1659 | 208 | List<Application> apps = new List<Application> (); | ||
1660 | 209 | if (string.IsNullOrEmpty (exec)) | ||
1661 | 210 | return apps; | ||
1662 | 211 | |||
1663 | 212 | exec = ProcessExecString (exec); | ||
1664 | 213 | if (string.IsNullOrEmpty (exec)) | ||
1665 | 214 | return apps; | ||
1666 | 215 | |||
1667 | 216 | UpdateExecList (); | ||
1668 | 217 | |||
1669 | 218 | foreach (KeyValuePair<int, string> kvp in exec_lines) { | ||
1670 | 219 | if (kvp.Value != null && kvp.Value.Contains (exec)) { | ||
1671 | 220 | foreach (Application app in GetApplications ()) { | ||
1672 | 221 | if (app == null) | ||
1673 | 222 | continue; | ||
1674 | 223 | |||
1675 | 224 | if (app.Pid == kvp.Key || app.Windows.Any (w => w.Pid == kvp.Key)) { | ||
1676 | 225 | if (app.Windows.Any (win => !win.IsSkipTasklist)) | ||
1677 | 226 | apps.Add (app); | ||
1678 | 227 | break; | ||
1679 | 228 | } | ||
1680 | 229 | } | ||
1681 | 230 | } | ||
1682 | 231 | } | ||
1683 | 232 | return apps; | ||
1684 | 233 | } | ||
1685 | 234 | |||
1686 | 235 | static void UpdateExecList () | 159 | static void UpdateExecList () |
1687 | 236 | { | 160 | { |
1688 | 237 | if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return; | 161 | if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return; |
1689 | 238 | 162 | ||
1691 | 239 | exec_lines.Clear (); | 163 | Dictionary<int, string> old = exec_lines; |
1692 | 164 | |||
1693 | 165 | exec_lines = new Dictionary<int, string> (); | ||
1694 | 240 | 166 | ||
1695 | 241 | foreach (string dir in Directory.GetDirectories ("/proc")) { | 167 | foreach (string dir in Directory.GetDirectories ("/proc")) { |
1696 | 242 | int pid; | 168 | int pid; |
1697 | 243 | try { pid = Convert.ToInt32 (Path.GetFileName (dir)); } | 169 | try { pid = Convert.ToInt32 (Path.GetFileName (dir)); } |
1698 | 244 | catch { continue; } | 170 | catch { continue; } |
1699 | 245 | 171 | ||
1700 | 172 | if (old.ContainsKey (pid)) { | ||
1701 | 173 | exec_lines [pid] = old [pid]; | ||
1702 | 174 | continue; | ||
1703 | 175 | } | ||
1704 | 176 | |||
1705 | 246 | string exec_line = CmdLineForPid (pid); | 177 | string exec_line = CmdLineForPid (pid); |
1706 | 247 | if (string.IsNullOrEmpty (exec_line)) | 178 | if (string.IsNullOrEmpty (exec_line)) |
1707 | 248 | continue; | 179 | continue; |
1708 | 249 | 180 | ||
1709 | 250 | if (exec_line.Contains ("java") && exec_line.Contains ("jar")) { | 181 | if (exec_line.Contains ("java") && exec_line.Contains ("jar")) { |
1712 | 251 | foreach (Application app in GetApplications ()) { | 182 | foreach (Window window in GetWindows ()) { |
1713 | 252 | if (app == null) | 183 | if (window == null) |
1714 | 253 | continue; | 184 | continue; |
1715 | 254 | 185 | ||
1719 | 255 | if (app.Pid == pid || app.Windows.Any (w => w.Pid == pid)) { | 186 | if (window.Pid == pid || window.Application.Pid == pid) { |
1720 | 256 | foreach (Wnck.Window window in app.Windows.Where (win => !win.IsSkipTasklist)) { | 187 | exec_line = window.ClassGroup.ResClass; |
1718 | 257 | exec_line = window.ClassGroup.ResClass; | ||
1721 | 258 | 188 | ||
1728 | 259 | // Vuze is retarded | 189 | // Vuze is retarded |
1729 | 260 | if (exec_line == "SWT") | 190 | if (exec_line == "SWT") |
1730 | 261 | exec_line = window.Name; | 191 | exec_line = window.Name; |
1725 | 262 | Console.WriteLine (exec_line); | ||
1726 | 263 | break; | ||
1727 | 264 | } | ||
1731 | 265 | } | 192 | } |
1732 | 266 | } | 193 | } |
1733 | 267 | } | 194 | } |
1734 | @@ -273,16 +200,126 @@ | |||
1735 | 273 | 200 | ||
1736 | 274 | last_update = DateTime.UtcNow; | 201 | last_update = DateTime.UtcNow; |
1737 | 275 | } | 202 | } |
1739 | 276 | 203 | ||
1740 | 204 | static ClickAction GetClickAction (IEnumerable<Window> windows) | ||
1741 | 205 | { | ||
1742 | 206 | if (!windows.Any ()) | ||
1743 | 207 | return ClickAction.None; | ||
1744 | 208 | |||
1745 | 209 | if (windows.Any (w => w.IsMinimized && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace))) | ||
1746 | 210 | return ClickAction.Restore; | ||
1747 | 211 | |||
1748 | 212 | if (windows.Any (w => w.IsActive && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace))) | ||
1749 | 213 | return ClickAction.Minimize; | ||
1750 | 214 | |||
1751 | 215 | return ClickAction.Focus; | ||
1752 | 216 | } | ||
1753 | 217 | #endregion | ||
1754 | 218 | |||
1755 | 219 | #region Public Methods | ||
1756 | 220 | /// <summary> | ||
1757 | 221 | /// Returns a list of all windows on the default screen | ||
1758 | 222 | /// </summary> | ||
1759 | 223 | /// <returns> | ||
1760 | 224 | /// A <see cref="List"/> | ||
1761 | 225 | /// </returns> | ||
1762 | 226 | public static List<Window> GetWindows () | ||
1763 | 227 | { | ||
1764 | 228 | if (window_list == null || window_list_update_needed) | ||
1765 | 229 | window_list = new List<Window> (Wnck.Screen.Default.WindowsStacked); | ||
1766 | 230 | |||
1767 | 231 | return window_list; | ||
1768 | 232 | } | ||
1769 | 233 | |||
1770 | 234 | /// <summary> | ||
1771 | 235 | /// Gets the command line excec string for a PID | ||
1772 | 236 | /// </summary> | ||
1773 | 237 | /// <param name="pid"> | ||
1774 | 238 | /// A <see cref="System.Int32"/> | ||
1775 | 239 | /// </param> | ||
1776 | 240 | /// <returns> | ||
1777 | 241 | /// A <see cref="System.String"/> | ||
1778 | 242 | /// </returns> | ||
1779 | 243 | public static string CmdLineForPid (int pid) | ||
1780 | 244 | { | ||
1781 | 245 | string cmdline = null; | ||
1782 | 246 | |||
1783 | 247 | try { | ||
1784 | 248 | string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine); | ||
1785 | 249 | using (StreamReader reader = new StreamReader (procPath)) { | ||
1786 | 250 | cmdline = reader.ReadLine (); | ||
1787 | 251 | reader.Close (); | ||
1788 | 252 | } | ||
1789 | 253 | } catch { } | ||
1790 | 254 | |||
1791 | 255 | return cmdline; | ||
1792 | 256 | } | ||
1793 | 257 | |||
1794 | 258 | public static List<Window> WindowListForCmd (string exec) | ||
1795 | 259 | { | ||
1796 | 260 | List<Window> windows = new List<Window> (); | ||
1797 | 261 | if (string.IsNullOrEmpty (exec)) | ||
1798 | 262 | return windows; | ||
1799 | 263 | |||
1800 | 264 | exec = ProcessExecString (exec); | ||
1801 | 265 | if (string.IsNullOrEmpty (exec)) | ||
1802 | 266 | return windows; | ||
1803 | 267 | |||
1804 | 268 | UpdateExecList (); | ||
1805 | 269 | |||
1806 | 270 | foreach (KeyValuePair<int, string> kvp in exec_lines) { | ||
1807 | 271 | if (!string.IsNullOrEmpty (kvp.Value) && kvp.Value.Contains (exec)) { | ||
1808 | 272 | // we have a matching exec, now we just find every window whose PID matches this exec | ||
1809 | 273 | foreach (Window window in GetWindows ()) { | ||
1810 | 274 | if (window == null) | ||
1811 | 275 | continue; | ||
1812 | 276 | |||
1813 | 277 | // this window matches the right PID and exec string, we can match it. | ||
1814 | 278 | bool pidMatch = window.Pid == kvp.Key || | ||
1815 | 279 | (window.Application != null && window.Application.Pid == kvp.Key); | ||
1816 | 280 | |||
1817 | 281 | if (pidMatch && !windows.Contains (window)) | ||
1818 | 282 | windows.Add (window); | ||
1819 | 283 | } | ||
1820 | 284 | } | ||
1821 | 285 | } | ||
1822 | 286 | |||
1823 | 287 | return windows; | ||
1824 | 288 | } | ||
1825 | 289 | |||
1826 | 290 | /// <summary> | ||
1827 | 291 | /// This method takes in an "execution string" from proc and applies a heureustic to try | ||
1828 | 292 | /// to magic out the name of the actual executing application. The executing binary is not | ||
1829 | 293 | /// the desired target all the time. | ||
1830 | 294 | /// </summary> | ||
1831 | 295 | /// <param name="exec"> | ||
1832 | 296 | /// A <see cref="System.String"/> | ||
1833 | 297 | /// </param> | ||
1834 | 298 | /// <returns> | ||
1835 | 299 | /// A <see cref="System.String"/> | ||
1836 | 300 | /// </returns> | ||
1837 | 277 | public static string ProcessExecString (string exec) | 301 | public static string ProcessExecString (string exec) |
1838 | 278 | { | 302 | { |
1839 | 303 | if (string.IsNullOrEmpty (exec)) | ||
1840 | 304 | return exec; | ||
1841 | 305 | |||
1842 | 306 | // lower it and trim off white space so we can abuse whitespace a bit | ||
1843 | 279 | exec = exec.ToLower ().Trim (); | 307 | exec = exec.ToLower ().Trim (); |
1844 | 280 | 308 | ||
1845 | 309 | // if the user has specified a specific mapping, we can use that here | ||
1846 | 281 | if (RemapDictionary.ContainsKey (exec)) | 310 | if (RemapDictionary.ContainsKey (exec)) |
1847 | 282 | return RemapDictionary [exec]; | 311 | return RemapDictionary [exec]; |
1848 | 283 | 312 | ||
1849 | 313 | // this is the "split" character or the argument separator. If the string contains a null | ||
1850 | 314 | // it was fetched from /proc/PID/cmdline and will be nicely split up. Otherwise things get a bit | ||
1851 | 315 | // nasty, and it likely came from a .desktop file. | ||
1852 | 316 | char splitChar = Convert.ToChar (0x0); | ||
1853 | 317 | splitChar = exec.Contains (splitChar) ? splitChar : ' '; | ||
1854 | 318 | |||
1855 | 319 | // this part is here soley for the remap file so that users may specify to remap based on just the name | ||
1856 | 320 | // without the full path. If no remap file match is found, the net effect of this is nothing. | ||
1857 | 284 | if (exec.StartsWith ("/")) { | 321 | if (exec.StartsWith ("/")) { |
1859 | 285 | string first_part = exec.Split (' ') [0]; | 322 | string first_part = exec.Split (splitChar) [0]; |
1860 | 286 | int length = first_part.Length; | 323 | int length = first_part.Length; |
1861 | 287 | first_part = first_part.Split ('/').Last (); | 324 | first_part = first_part.Split ('/').Last (); |
1862 | 288 | 325 | ||
1863 | @@ -294,25 +331,38 @@ | |||
1864 | 294 | } | 331 | } |
1865 | 295 | } | 332 | } |
1866 | 296 | 333 | ||
1868 | 297 | string [] parts = exec.Split (' '); | 334 | string [] parts = exec.Split (splitChar); |
1869 | 298 | for (int i = 0; i < parts.Length; i++) { | 335 | for (int i = 0; i < parts.Length; i++) { |
1871 | 299 | if (parts [i].StartsWith ("-")) | 336 | // we're going to use this a lot |
1872 | 337 | string out_val = parts [i]; | ||
1873 | 338 | |||
1874 | 339 | // arguments are useless | ||
1875 | 340 | if (out_val.StartsWith ("-")) | ||
1876 | 300 | continue; | 341 | continue; |
1877 | 301 | 342 | ||
1886 | 302 | if (parts [i].Contains ("/")) | 343 | // we want the end of paths |
1887 | 303 | parts [i] = parts [i].Split ('/').Last (); | 344 | if (out_val.Contains ("/")) |
1888 | 304 | 345 | out_val = out_val.Split ('/').Last (); | |
1889 | 305 | Regex regex; | 346 | |
1890 | 306 | foreach (string prefix in BadPrefixes) { | 347 | // wine apps can do it backwards... who knew? |
1891 | 307 | regex = new Regex (string.Format ("^{0}$", prefix), RegexOptions.IgnoreCase); | 348 | if (out_val.Contains ("\\")) |
1892 | 308 | if (regex.IsMatch (parts [i])) { | 349 | out_val = out_val.Split ('\\').Last (); |
1893 | 309 | parts [i] = null; | 350 | |
1894 | 351 | // null out our part if is a bad prefix | ||
1895 | 352 | foreach (Regex regex in BadPrefixes) { | ||
1896 | 353 | if (regex.IsMatch (out_val)) { | ||
1897 | 354 | out_val = null; | ||
1898 | 310 | break; | 355 | break; |
1899 | 311 | } | 356 | } |
1900 | 312 | } | 357 | } |
1901 | 313 | 358 | ||
1904 | 314 | if (!string.IsNullOrEmpty (parts [i])) { | 359 | // check if it was a bad prefix... |
1905 | 315 | string out_val = parts [i]; | 360 | if (!string.IsNullOrEmpty (out_val)) { |
1906 | 361 | // sometimes we hide things with shell scripts. This is the most common method of doing it. | ||
1907 | 362 | if (out_val.EndsWith (".real")) | ||
1908 | 363 | out_val = out_val.Substring (0, out_val.Length - ".real".Length); | ||
1909 | 364 | |||
1910 | 365 | // give the remap dictionary one last shot at this | ||
1911 | 316 | if (RemapDictionary.ContainsKey (out_val)) | 366 | if (RemapDictionary.ContainsKey (out_val)) |
1912 | 317 | out_val = RemapDictionary [out_val]; | 367 | out_val = RemapDictionary [out_val]; |
1913 | 318 | return out_val; | 368 | return out_val; |
1914 | @@ -327,12 +377,10 @@ | |||
1915 | 327 | /// <param name="apps"> | 377 | /// <param name="apps"> |
1916 | 328 | /// A <see cref="IEnumerable"/> | 378 | /// A <see cref="IEnumerable"/> |
1917 | 329 | /// </param> | 379 | /// </param> |
1919 | 330 | public static void PerformLogicalClick (IEnumerable<Application> apps) | 380 | public static void PerformLogicalClick (IEnumerable<Window> windows) |
1920 | 331 | { | 381 | { |
1921 | 332 | List<Window> stack = new List<Window> (Wnck.Screen.Default.WindowsStacked); | 382 | List<Window> stack = new List<Window> (Wnck.Screen.Default.WindowsStacked); |
1925 | 333 | IEnumerable<Window> windows = apps | 383 | windows = windows.OrderByDescending (w => stack.IndexOf (w)); |
1923 | 334 | .SelectMany (app => app.Windows) | ||
1924 | 335 | .OrderByDescending (w => stack.IndexOf (w)); | ||
1926 | 336 | 384 | ||
1927 | 337 | bool not_in_viewport = !windows.Any (w => !w.IsSkipTasklist && w.IsInViewport (w.Screen.ActiveWorkspace)); | 385 | bool not_in_viewport = !windows.Any (w => !w.IsSkipTasklist && w.IsInViewport (w.Screen.ActiveWorkspace)); |
1928 | 338 | bool urgent = windows.Any (w => w.NeedsAttention ()); | 386 | bool urgent = windows.Any (w => w.NeedsAttention ()); |
1929 | @@ -348,7 +396,7 @@ | |||
1930 | 348 | } | 396 | } |
1931 | 349 | } | 397 | } |
1932 | 350 | 398 | ||
1934 | 351 | switch (GetClickAction (apps)) { | 399 | switch (GetClickAction (windows)) { |
1935 | 352 | case ClickAction.Focus: | 400 | case ClickAction.Focus: |
1936 | 353 | WindowControl.FocusWindows (windows); | 401 | WindowControl.FocusWindows (windows); |
1937 | 354 | break; | 402 | break; |
1938 | @@ -361,26 +409,6 @@ | |||
1939 | 361 | } | 409 | } |
1940 | 362 | } | 410 | } |
1941 | 363 | 411 | ||
1963 | 364 | static ClickAction GetClickAction (IEnumerable<Application> apps) | 412 | #endregion |
1943 | 365 | { | ||
1944 | 366 | if (!apps.Any ()) | ||
1945 | 367 | return ClickAction.None; | ||
1946 | 368 | |||
1947 | 369 | foreach (Wnck.Application app in apps) { | ||
1948 | 370 | foreach (Wnck.Window window in app.Windows) { | ||
1949 | 371 | if (window.IsMinimized && window.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)) | ||
1950 | 372 | return ClickAction.Restore; | ||
1951 | 373 | } | ||
1952 | 374 | } | ||
1953 | 375 | |||
1954 | 376 | foreach (Wnck.Application app in apps) { | ||
1955 | 377 | foreach (Wnck.Window window in app.Windows) { | ||
1956 | 378 | if (window.IsActive && window.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)) | ||
1957 | 379 | return ClickAction.Minimize; | ||
1958 | 380 | } | ||
1959 | 381 | } | ||
1960 | 382 | |||
1961 | 383 | return ClickAction.Focus; | ||
1962 | 384 | } | ||
1964 | 385 | } | 413 | } |
1965 | 386 | } | 414 | } |
1966 | 387 | 415 | ||
1967 | === added directory 'Do.Interface.Wink/src/Do.Interface.Xlib' | |||
1968 | === renamed file 'Do.Interface.Linux.Docky/src/XLib/X11Atoms.cs' => 'Do.Interface.Wink/src/Do.Interface.Xlib/X11Atoms.cs' | |||
1969 | --- Do.Interface.Linux.Docky/src/XLib/X11Atoms.cs 2009-02-23 04:01:36 +0000 | |||
1970 | +++ Do.Interface.Wink/src/Do.Interface.Xlib/X11Atoms.cs 2009-03-31 16:23:23 +0000 | |||
1971 | @@ -23,9 +23,18 @@ | |||
1972 | 23 | 23 | ||
1973 | 24 | using System; | 24 | using System; |
1974 | 25 | 25 | ||
1976 | 26 | namespace Docky.XLib { | 26 | namespace Do.Interface.Xlib { |
1977 | 27 | 27 | ||
1979 | 28 | internal class X11Atoms { | 28 | public class X11Atoms { |
1980 | 29 | |||
1981 | 30 | static X11Atoms instance; | ||
1982 | 31 | public static X11Atoms Instance { | ||
1983 | 32 | get { | ||
1984 | 33 | if (instance == null) | ||
1985 | 34 | instance = new X11Atoms (Gdk.Screen.Default.Display); | ||
1986 | 35 | return instance; | ||
1987 | 36 | } | ||
1988 | 37 | } | ||
1989 | 29 | 38 | ||
1990 | 30 | // Our atoms | 39 | // Our atoms |
1991 | 31 | public readonly IntPtr AnyPropertyType = (IntPtr)0; | 40 | public readonly IntPtr AnyPropertyType = (IntPtr)0; |
1992 | @@ -169,8 +178,8 @@ | |||
1993 | 169 | public readonly IntPtr AsyncAtom; | 178 | public readonly IntPtr AsyncAtom; |
1994 | 170 | 179 | ||
1995 | 171 | 180 | ||
1998 | 172 | public X11Atoms (Gdk.Window window) { | 181 | X11Atoms (Gdk.Display dsp) { |
1999 | 173 | IntPtr display = XLib.Xlib.GdkDrawableXDisplay (window); | 182 | IntPtr display = Xlib.GdkDisplayXDisplay (dsp); |
2000 | 174 | // make sure this array stays in sync with the statements below | 183 | // make sure this array stays in sync with the statements below |
2001 | 175 | string [] atom_names = new string[] { | 184 | string [] atom_names = new string[] { |
2002 | 176 | "WM_PROTOCOLS", | 185 | "WM_PROTOCOLS", |
2003 | 177 | 186 | ||
2004 | === renamed file 'Do.Interface.Linux.Docky/src/XLib/Xlib.cs' => 'Do.Interface.Wink/src/Do.Interface.Xlib/Xlib.cs' | |||
2005 | --- Do.Interface.Linux.Docky/src/XLib/Xlib.cs 2009-01-12 20:15:41 +0000 | |||
2006 | +++ Do.Interface.Wink/src/Do.Interface.Xlib/Xlib.cs 2009-03-31 16:23:23 +0000 | |||
2007 | @@ -27,7 +27,7 @@ | |||
2008 | 27 | using System.Collections.Generic; | 27 | using System.Collections.Generic; |
2009 | 28 | using System.Linq; | 28 | using System.Linq; |
2010 | 29 | 29 | ||
2012 | 30 | namespace Docky.XLib { | 30 | namespace Do.Interface.Xlib { |
2013 | 31 | 31 | ||
2014 | 32 | public enum PropertyMode | 32 | public enum PropertyMode |
2015 | 33 | { | 33 | { |
2016 | @@ -52,7 +52,7 @@ | |||
2017 | 52 | BottomEnd = 11 | 52 | BottomEnd = 11 |
2018 | 53 | } | 53 | } |
2019 | 54 | 54 | ||
2021 | 55 | internal class Xlib { | 55 | public static class Xlib { |
2022 | 56 | const string libX11 = "X11"; | 56 | const string libX11 = "X11"; |
2023 | 57 | const string libGdkX11 = "libgdk-x11"; | 57 | const string libGdkX11 = "libgdk-x11"; |
2024 | 58 | 58 | ||
2025 | @@ -61,7 +61,24 @@ | |||
2026 | 61 | 61 | ||
2027 | 62 | [DllImport (libGdkX11)] | 62 | [DllImport (libGdkX11)] |
2028 | 63 | static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr handle); | 63 | static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr handle); |
2029 | 64 | |||
2030 | 65 | [DllImport (libGdkX11)] | ||
2031 | 66 | static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display); | ||
2032 | 64 | 67 | ||
2033 | 68 | [DllImport (libX11)] | ||
2034 | 69 | public extern static IntPtr XOpenDisplay (IntPtr display); | ||
2035 | 70 | |||
2036 | 71 | [DllImport (libX11)] | ||
2037 | 72 | public extern static int XInternAtoms (IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms); | ||
2038 | 73 | |||
2039 | 74 | [DllImport (libX11)] | ||
2040 | 75 | extern static int XChangeProperty (IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, int mode, IntPtr[] data, int nelements); | ||
2041 | 76 | |||
2042 | 77 | [DllImport (libX11)] | ||
2043 | 78 | public extern static int XGetWindowProperty (IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, | ||
2044 | 79 | IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, | ||
2045 | 80 | out int actual_format, out IntPtr nitems, out IntPtr bytes_after, out IntPtr prop); | ||
2046 | 81 | |||
2047 | 65 | public static IntPtr GdkWindowX11Xid (Gdk.Window window) | 82 | public static IntPtr GdkWindowX11Xid (Gdk.Window window) |
2048 | 66 | { | 83 | { |
2049 | 67 | return gdk_x11_drawable_get_xid (window.Handle); | 84 | return gdk_x11_drawable_get_xid (window.Handle); |
2050 | @@ -72,19 +89,16 @@ | |||
2051 | 72 | return gdk_x11_drawable_get_xdisplay (window.Handle); | 89 | return gdk_x11_drawable_get_xdisplay (window.Handle); |
2052 | 73 | } | 90 | } |
2053 | 74 | 91 | ||
2063 | 75 | [DllImport (libX11)] | 92 | public static IntPtr GdkDisplayXDisplay (Gdk.Display display) |
2064 | 76 | public extern static IntPtr XOpenDisplay (IntPtr display); | 93 | { |
2065 | 77 | 94 | return gdk_x11_display_get_xdisplay (display.Handle); | |
2066 | 78 | [DllImport (libX11)] | 95 | } |
2067 | 79 | public extern static int XInternAtoms (IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms); | 96 | |
2059 | 80 | |||
2060 | 81 | [DllImport (libX11)] | ||
2061 | 82 | extern static int XChangeProperty (IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, int mode, IntPtr[] data, int nelements); | ||
2062 | 83 | |||
2068 | 84 | public static int XChangeProperty (Gdk.Window window, IntPtr property, IntPtr type, int mode, uint[] data) | 97 | public static int XChangeProperty (Gdk.Window window, IntPtr property, IntPtr type, int mode, uint[] data) |
2069 | 85 | { | 98 | { |
2070 | 86 | IntPtr [] dataArray = data.Select (i => (IntPtr) i).ToArray (); | 99 | IntPtr [] dataArray = data.Select (i => (IntPtr) i).ToArray (); |
2071 | 87 | return XChangeProperty (GdkDrawableXDisplay (window), GdkWindowX11Xid (window), property, type, 32, mode, dataArray, data.Length); | 100 | return XChangeProperty (GdkDrawableXDisplay (window), GdkWindowX11Xid (window), property, type, 32, mode, dataArray, data.Length); |
2072 | 88 | } | 101 | } |
2073 | 102 | |||
2074 | 89 | } | 103 | } |
2075 | 90 | } | 104 | } |
2076 | 91 | 105 | ||
2077 | === modified file 'Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs' | |||
2078 | --- Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs 2009-01-21 23:44:40 +0000 | |||
2079 | +++ Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs 2009-03-24 15:04:23 +0000 | |||
2080 | @@ -18,6 +18,8 @@ | |||
2081 | 18 | // | 18 | // |
2082 | 19 | 19 | ||
2083 | 20 | using System; | 20 | using System; |
2084 | 21 | using System.Collections.Generic; | ||
2085 | 22 | using System.Linq; | ||
2086 | 21 | 23 | ||
2087 | 22 | using Do.Universe; | 24 | using Do.Universe; |
2088 | 23 | using Do.Universe.Linux; | 25 | using Do.Universe.Linux; |
2089 | @@ -28,7 +30,6 @@ | |||
2090 | 28 | 30 | ||
2091 | 29 | public class UniverseFactoryService : IUniverseFactoryService | 31 | public class UniverseFactoryService : IUniverseFactoryService |
2092 | 30 | { | 32 | { |
2093 | 31 | |||
2094 | 32 | public IFileItem NewFileItem (string path) | 33 | public IFileItem NewFileItem (string path) |
2095 | 33 | { | 34 | { |
2096 | 34 | return new FileItem (path); | 35 | return new FileItem (path); |
2097 | @@ -41,5 +42,10 @@ | |||
2098 | 41 | IApplicationItem maybe = ApplicationItem.MaybeCreateFromDesktopItem (path); | 42 | IApplicationItem maybe = ApplicationItem.MaybeCreateFromDesktopItem (path); |
2099 | 42 | return maybe ?? new NullApplicationItem (path); | 43 | return maybe ?? new NullApplicationItem (path); |
2100 | 43 | } | 44 | } |
2101 | 45 | |||
2102 | 46 | public IApplicationItem MaybeApplicationItemFromCommand (string cmd) | ||
2103 | 47 | { | ||
2104 | 48 | return ApplicationItem.MaybeCreateFromCmd (cmd); | ||
2105 | 49 | } | ||
2106 | 44 | } | 50 | } |
2107 | 45 | } | 51 | } |
2108 | 46 | 52 | ||
2109 | === modified file 'Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs' | |||
2110 | --- Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs 2009-01-23 23:01:37 +0000 | |||
2111 | +++ Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs 2009-03-29 17:52:17 +0000 | |||
2112 | @@ -22,6 +22,7 @@ | |||
2113 | 22 | using System.Linq; | 22 | using System.Linq; |
2114 | 23 | using System.Collections.Generic; | 23 | using System.Collections.Generic; |
2115 | 24 | using System.Runtime.InteropServices; | 24 | using System.Runtime.InteropServices; |
2116 | 25 | using System.Text.RegularExpressions; | ||
2117 | 25 | 26 | ||
2118 | 26 | using Gnome; | 27 | using Gnome; |
2119 | 27 | using Mono.Unix; | 28 | using Mono.Unix; |
2120 | @@ -68,6 +69,34 @@ | |||
2121 | 68 | } | 69 | } |
2122 | 69 | return appItem; | 70 | return appItem; |
2123 | 70 | } | 71 | } |
2124 | 72 | |||
2125 | 73 | public static ApplicationItem MaybeCreateFromCmd (string cmd) | ||
2126 | 74 | { | ||
2127 | 75 | ApplicationItem appItem = null; | ||
2128 | 76 | |||
2129 | 77 | if (string.IsNullOrEmpty (cmd)) | ||
2130 | 78 | return appItem; | ||
2131 | 79 | |||
2132 | 80 | cmd = Regex.Escape (cmd); | ||
2133 | 81 | Regex regex = new Regex (string .Format ("(^| ){0}( |)", cmd)); | ||
2134 | 82 | foreach (ApplicationItem item in Instances.Values) { | ||
2135 | 83 | string path = item.Location; | ||
2136 | 84 | try { | ||
2137 | 85 | if (path.StartsWith ("file://")) | ||
2138 | 86 | path = path.Substring ("file://".Length); | ||
2139 | 87 | |||
2140 | 88 | path = Path.GetFileName (path); | ||
2141 | 89 | } catch { continue; } | ||
2142 | 90 | |||
2143 | 91 | if (regex.IsMatch (path) || regex.IsMatch (item.Exec)) { | ||
2144 | 92 | appItem = item; | ||
2145 | 93 | if (item.IsAppropriateForCurrentDesktop && !item.Hidden) | ||
2146 | 94 | break; | ||
2147 | 95 | } | ||
2148 | 96 | } | ||
2149 | 97 | |||
2150 | 98 | return appItem; | ||
2151 | 99 | } | ||
2152 | 71 | 100 | ||
2153 | 72 | protected DesktopItem item; | 101 | protected DesktopItem item; |
2154 | 73 | string name, description, icon, mimetype; | 102 | string name, description, icon, mimetype; |
2155 | @@ -115,6 +144,10 @@ | |||
2156 | 115 | public string Exec { | 144 | public string Exec { |
2157 | 116 | get { return item.GetString ("Exec"); } | 145 | get { return item.GetString ("Exec"); } |
2158 | 117 | } | 146 | } |
2159 | 147 | |||
2160 | 148 | protected string Location { | ||
2161 | 149 | get { return item.Location; } | ||
2162 | 150 | } | ||
2163 | 118 | 151 | ||
2164 | 119 | public bool Hidden { | 152 | public bool Hidden { |
2165 | 120 | get { return item.GetBoolean ("NoDisplay"); } | 153 | get { return item.GetBoolean ("NoDisplay"); } |
2166 | 121 | 154 | ||
2167 | === modified file 'Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs' | |||
2168 | --- Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs 2008-12-12 01:41:51 +0000 | |||
2169 | +++ Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs 2009-03-24 15:04:23 +0000 | |||
2170 | @@ -41,6 +41,12 @@ | |||
2171 | 41 | Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem."); | 41 | Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem."); |
2172 | 42 | return new EmptyApplicationItem (); | 42 | return new EmptyApplicationItem (); |
2173 | 43 | } | 43 | } |
2174 | 44 | |||
2175 | 45 | public IApplicationItem MaybeApplicationItemFromCommand (string cmd) | ||
2176 | 46 | { | ||
2177 | 47 | Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem."); | ||
2178 | 48 | return null; | ||
2179 | 49 | } | ||
2180 | 44 | 50 | ||
2181 | 45 | class EmptyFileItem : EmptyItem, IFileItem | 51 | class EmptyFileItem : EmptyItem, IFileItem |
2182 | 46 | { | 52 | { |
2183 | 47 | 53 | ||
2184 | === modified file 'Do.Platform/src/Do.Platform/IUniverseFactoryService.cs' | |||
2185 | --- Do.Platform/src/Do.Platform/IUniverseFactoryService.cs 2008-12-22 00:36:53 +0000 | |||
2186 | +++ Do.Platform/src/Do.Platform/IUniverseFactoryService.cs 2009-03-24 15:04:23 +0000 | |||
2187 | @@ -31,5 +31,6 @@ | |||
2188 | 31 | { | 31 | { |
2189 | 32 | IFileItem NewFileItem (string path); | 32 | IFileItem NewFileItem (string path); |
2190 | 33 | IApplicationItem NewApplicationItem (string path); | 33 | IApplicationItem NewApplicationItem (string path); |
2191 | 34 | IApplicationItem MaybeApplicationItemFromCommand (string cmd); | ||
2192 | 34 | } | 35 | } |
2193 | 35 | } | 36 | } |
2194 | 36 | 37 | ||
2195 | === modified file 'Do.mds' | |||
2196 | --- Do.mds 2009-03-28 15:34:37 +0000 | |||
2197 | +++ Do.mds 2009-03-31 17:48:02 +0000 | |||
2198 | @@ -64,4 +64,4 @@ | |||
2199 | 64 | <Entry filename="Do.Interface.Linux.HUD/Do.Interface.Linux.HUD.mdp" /> | 64 | <Entry filename="Do.Interface.Linux.HUD/Do.Interface.Linux.HUD.mdp" /> |
2200 | 65 | <Entry filename="Do.Interface.Wink/Do.Interface.Wink.mdp" /> | 65 | <Entry filename="Do.Interface.Wink/Do.Interface.Wink.mdp" /> |
2201 | 66 | </Entries> | 66 | </Entries> |
2203 | 67 | </Combine> | 67 | </Combine> |
2204 | 68 | \ No newline at end of file | 68 | \ No newline at end of file |
2205 | 69 | 69 | ||
2206 | === modified file 'Do/gnome-do.in' | |||
2207 | --- Do/gnome-do.in 2008-10-27 07:23:04 +0000 | |||
2208 | +++ Do/gnome-do.in 2009-03-24 15:04:23 +0000 | |||
2209 | @@ -18,8 +18,8 @@ | |||
2210 | 18 | 18 | ||
2211 | 19 | # If Do is not running, run it. | 19 | # If Do is not running, run it. |
2212 | 20 | if pgrep -u "`id -un`" '^gnome-do$' >/dev/null; then | 20 | if pgrep -u "`id -un`" '^gnome-do$' >/dev/null; then |
2214 | 21 | mono "$GNOME_DO_EXE" "$@" | 21 | mono --debug "$GNOME_DO_EXE" "$@" > ~/do.trace 2>&1 |
2215 | 22 | fi | 22 | fi |
2216 | 23 | while [ "$?" -eq "20" ]; do | 23 | while [ "$?" -eq "20" ]; do |
2218 | 24 | mono "$GNOME_DO_EXE" "$@" | 24 | mono --debug "$GNOME_DO_EXE" "$@" > ~/do.trace 2>&1 |
2219 | 25 | done | 25 | done |
Can you combine HandleWindowClosed and Opened methods? They do exactly the same thing, you should be able to at the very least use EventArgs, but they probably both inherit from a higher level base class. Take a look.
Constify the delay in DelayedUpdate. Magic numbers are evil!
on diff line 182, i really dont like the variable name api, it's confusing since api has a meaning.
There are a bunch of WriteLines, clean them up. If you need them, make them into Log.Debugs
In UnregisterWindo wEvents why do you need a try catch? Whats going to throw an exception adding and removing an event handler?
Diff line 960: Do you need to GetString? This should be done before you get passed the string.
removed the commented out line from ScreenUtils.cs
Again, constify the delay in WindowControl.cs, FocusWindows ()
Looks good otherwise! Fix those things then merge!