Do

Merge lp:~jassmith/do/glitch-free-docky into lp:do

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
Reviewer Review Type Date Requested Status
Alex Launi (community) Approve
Review via email: mp+5092@code.launchpad.net
To post a comment you must log in.
lp:~jassmith/do/glitch-free-docky updated
1135. By Jason Smith

remove debug

Revision history for this message
Alex Launi (alexlauni) wrote :

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 UnregisterWindowEvents 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!

review: Approve
lp:~jassmith/do/glitch-free-docky updated
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
=== removed file 'Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config'
--- Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config 2009-01-11 20:30:50 +0000
+++ Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.dll.config 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
1<configuration>
2 <dllmap dll="X11" target="libX11.so.6"/>
3 <dllmap dll="libgdk-x11" target="libgdk-x11-2.0.so.0"/>
4</configuration>
50
=== modified file 'Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp'
--- Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/Do.Interface.Linux.Docky.mdp 2009-03-31 03:39:44 +0000
@@ -19,7 +19,6 @@
19 <File name="src" subtype="Directory" buildaction="Compile" />19 <File name="src" subtype="Directory" buildaction="Compile" />
20 <File name="Resources" subtype="Directory" buildaction="Compile" />20 <File name="Resources" subtype="Directory" buildaction="Compile" />
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" />
22 <File name="src/XLib" subtype="Directory" buildaction="Compile" />
23 <File name="src/Docky.Interface" subtype="Directory" buildaction="Compile" />22 <File name="src/Docky.Interface" subtype="Directory" buildaction="Compile" />
24 <File name="src/Docky.Utilities" subtype="Directory" buildaction="Compile" />23 <File name="src/Docky.Utilities" subtype="Directory" buildaction="Compile" />
25 <File name="src/Docky.Interface/DockArea.cs" subtype="Code" buildaction="Compile" />24 <File name="src/Docky.Interface/DockArea.cs" subtype="Code" buildaction="Compile" />
@@ -32,8 +31,6 @@
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" />
33 <File name="src/Docky.Utilities/DockPreferences.cs" subtype="Code" buildaction="Compile" />32 <File name="src/Docky.Utilities/DockPreferences.cs" subtype="Code" buildaction="Compile" />
34 <File name="src/Docky.Utilities/GtkUtils.cs" subtype="Code" buildaction="Compile" />33 <File name="src/Docky.Utilities/GtkUtils.cs" subtype="Code" buildaction="Compile" />
35 <File name="src/XLib/X11Atoms.cs" subtype="Code" buildaction="Compile" />
36 <File name="src/XLib/Xlib.cs" subtype="Code" buildaction="Compile" />
37 <File name="src/Docky.Interface/IRightClickable.cs" subtype="Code" buildaction="Compile" />34 <File name="src/Docky.Interface/IRightClickable.cs" subtype="Code" buildaction="Compile" />
38 <File name="src/Docky.Interface/UpdateRequestArgs.cs" subtype="Code" buildaction="Compile" />35 <File name="src/Docky.Interface/UpdateRequestArgs.cs" subtype="Code" buildaction="Compile" />
39 <File name="src/Docky.Interface/DockAnimationState.cs" subtype="Code" buildaction="Compile" />36 <File name="src/Docky.Interface/DockAnimationState.cs" subtype="Code" buildaction="Compile" />
4037
=== modified file 'Do.Interface.Linux.Docky/Makefile.am'
--- Do.Interface.Linux.Docky/Makefile.am 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/Makefile.am 2009-03-31 16:33:58 +0000
@@ -65,9 +65,7 @@
65 src/Docky.Interface/Util.cs \65 src/Docky.Interface/Util.cs \
66 src/Docky.Utilities/DockOrientation.cs \66 src/Docky.Utilities/DockOrientation.cs \
67 src/Docky.Utilities/DockPreferences.cs \67 src/Docky.Utilities/DockPreferences.cs \
68 src/Docky.Utilities/GtkUtils.cs \68 src/Docky.Utilities/GtkUtils.cs
69 src/XLib/X11Atoms.cs \
70 src/XLib/Xlib.cs
7169
72RESOURCES = \70RESOURCES = \
73 Resources/Do.Interface.Linux.Docky.addin.xml \71 Resources/Do.Interface.Linux.Docky.addin.xml \
@@ -91,6 +89,3 @@
91 Do.Interface.Wink \89 Do.Interface.Wink \
92 Do.Platform \90 Do.Platform \
93 Do.Universe91 Do.Universe
94
95module_DATA += $(ASSEMBLY).dll.config
96EXTRA_DIST += $(ASSEMBLY).dll.config
9792
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs'
--- Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Core/Docky.Core.Default/ItemsService.cs 2009-04-01 01:08:07 +0000
@@ -199,14 +199,15 @@
199199
200 void HandleWindowOpened(object o, WindowOpenedArgs args)200 void HandleWindowOpened(object o, WindowOpenedArgs args)
201 {201 {
202 // we do a delayed update so that we allow a small gap for wnck to catch up
202 if (!args.Window.IsSkipTasklist)203 if (!args.Window.IsSkipTasklist)
203 UpdateItems ();204 DelayUpdateItems ();
204 }205 }
205206
206 void HandleWindowClosed(object o, WindowClosedArgs args)207 void HandleWindowClosed(object o, WindowClosedArgs args)
207 {208 {
208 if (!args.Window.IsSkipTasklist)209 if (!args.Window.IsSkipTasklist)
209 UpdateItems ();210 DelayUpdateItems ();
210 }211 }
211212
212 void HandleUniverseInitialized(object sender, EventArgs e)213 void HandleUniverseInitialized(object sender, EventArgs e)
@@ -259,17 +260,25 @@
259 item.Position = i++;260 item.Position = i++;
260 }261 }
261 262
263 void DelayUpdateItems ()
264 {
265 GLib.Timeout.Add (20, delegate {
266 UpdateItems ();
267 return false;
268 });
269 }
270
262 void UpdateItems ()271 void UpdateItems ()
263 {272 {
264 if (!UpdatesEnabled)273 if (!UpdatesEnabled)
265 return;274 return;
266 275
267 UpdateStatItems ();
268
269 if (!CustomItemsRead) {276 if (!CustomItemsRead) {
270 foreach (string s in ReadCustomItems ())277 foreach (string s in ReadCustomItems ())
271 InternalAddItemToDock (s, LastPosition + 1);278 InternalAddItemToDock (s, LastPosition + 1);
272 279
280 UpdateStatItems ();
281
273 Dictionary<string, int> sortDictionary = ReadSortDictionary ();282 Dictionary<string, int> sortDictionary = ReadSortDictionary ();
274 foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) {283 foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) {
275 if (sortDictionary.ContainsKey (item.Element.UniqueId))284 if (sortDictionary.ContainsKey (item.Element.UniqueId))
@@ -277,6 +286,8 @@
277 }286 }
278 287
279 CustomItemsRead = true;288 CustomItemsRead = true;
289 } else {
290 UpdateStatItems ();
280 }291 }
281 292
282 UpdateTaskItems ();293 UpdateTaskItems ();
@@ -329,24 +340,22 @@
329 340
330 void UpdateTaskItems ()341 void UpdateTaskItems ()
331 {342 {
332 foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem)) {343 foreach (ItemDockItem item in OrderedItems.Where (di => di is ItemDockItem))
333 item.UpdateApplication ();344 item.UpdateApplication ();
334 }
335 345
336 List<ApplicationDockItem> out_items = new List<ApplicationDockItem> ();346 List<ApplicationDockItem> out_items = new List<ApplicationDockItem> ();
337347
338 IEnumerable<int> knownPids = OrderedItems348 IEnumerable<Window> knownWindows = OrderedItems
339 .Where (di => di is ItemDockItem)349 .Where (di => di is ItemDockItem)
340 .Cast<ItemDockItem> ()350 .Cast<ItemDockItem> ()
341 .SelectMany (di => di.Pids);351 .SelectMany (di => di.Windows);
342 352
343 IEnumerable<Application> prunedApps = WindowUtils.GetApplications ()353 var prunedWindows = WindowUtils.GetWindows ()
344 .Where (app => app.Windows.Any (w => !w.IsSkipTasklist))354 .Where (w => !w.IsSkipTasklist && !knownWindows.Contains (w))
345 .Where (app => !knownPids.Contains (app.Pid) && app.Windows.Any ());355 .GroupBy (w => SafeResClass (w));
346 356
347 foreach (IEnumerable<Wnck.Application> apps in prunedApps357 foreach (IEnumerable<Wnck.Window> windows in prunedWindows) {
348 .GroupBy (app => (app as Wnck.Application).Windows [0].ClassGroup.ResClass)) {358 ApplicationDockItem api = new ApplicationDockItem (windows);
349 ApplicationDockItem api = new ApplicationDockItem (apps);
350359
351 if (task_items.Any (di => di.Equals (api))) {360 if (task_items.Any (di => di.Equals (api))) {
352 AbstractDockItem match = task_items.Where (di => di.Equals (api)).First ();361 AbstractDockItem match = task_items.Where (di => di.Equals (api)).First ();
@@ -374,6 +383,13 @@
374 task_items.AddRange (out_items.Cast<AbstractDockItem> ());383 task_items.AddRange (out_items.Cast<AbstractDockItem> ());
375 }384 }
376 385
386 string SafeResClass (Wnck.Window window)
387 {
388 if (window.ClassGroup != null && window.ClassGroup.ResClass != null)
389 return window.ClassGroup.ResClass;
390 return string.Empty;
391 }
392
377 void OnDockItemsChanged ()393 void OnDockItemsChanged ()
378 {394 {
379 output_items.Clear ();395 output_items.Clear ();
@@ -506,15 +522,6 @@
506 return DockItems.Contains (item) && 0 <= position && position < DockItems.Count;522 return DockItems.Contains (item) && 0 <= position && position < DockItems.Count;
507 }523 }
508 524
509 int LastNonTaskItemPosition ()
510 {
511 if (!OrderedItems.Any (di => !(di is ApplicationDockItem)))
512 return 0;
513 return OrderedItems
514 .Where (di => !(di is ApplicationDockItem))
515 .Max ((Func<AbstractDockItem, int>) (di => di.Position));
516 }
517
518 /// <summary>525 /// <summary>
519 /// Returns the most used items out of GNOME Do and does a tiny bit of filtering and sorting on them526 /// Returns the most used items out of GNOME Do and does a tiny bit of filtering and sorting on them
520 /// This is mostly to encourage a better first run experience, but overall this can be improved527 /// This is mostly to encourage a better first run experience, but overall this can be improved
@@ -616,19 +623,22 @@
616 continue;623 continue;
617 }624 }
618 625
619 if (item is ApplicationDockItem && position <= LastNonTaskItemPosition ()) {626 if (item is ApplicationDockItem) {
620 ApplicationDockItem api = item as ApplicationDockItem;627 ApplicationDockItem api = item as ApplicationDockItem;
621 string desktop_file = api.DesktopFile;628
622 629 if (api.Launcher == null) continue;
623 if (string.IsNullOrEmpty (desktop_file)) continue;630
624 631 Item launcher = api.Launcher as Item;
625 AbstractDockItem newItem = MaybeCreateCustomItem (desktop_file);632 if (launcher == null)
626 633 continue;
627 if (newItem == null) continue;634
635 AbstractDockItem newItem = new ItemDockItem (launcher);
628 636
629 newItem.Position = item.Position;637 newItem.Position = item.Position;
630 newItem.DockAddItem = item.DockAddItem;638 newItem.DockAddItem = item.DockAddItem;
631 custom_items [desktop_file] = newItem;639 custom_items [launcher.UniqueId] = newItem;
640
641 RegisterDockItem (newItem);
632 UpdateItems ();642 UpdateItems ();
633 WriteData ();643 WriteData ();
634 }644 }
635645
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs 2009-03-15 17:41:40 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/DockArea.cs 2009-04-01 01:08:07 +0000
@@ -26,6 +26,7 @@
26using Gtk;26using Gtk;
2727
28using Do.Platform;28using Do.Platform;
29using Do.Interface.Xlib;
2930
30using Docky.Core;31using Docky.Core;
31using Docky.Utilities;32using Docky.Utilities;
@@ -99,14 +100,14 @@
99 100
100 switch (DockPreferences.Orientation) {101 switch (DockPreferences.Orientation) {
101 case DockOrientation.Bottom:102 case DockOrientation.Bottom:
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)));
103 values [(int) XLib.Struts.BottomStart] = (uint) geo.X;104 values [(int) Struts.BottomStart] = (uint) geo.X;
104 values [(int) XLib.Struts.BottomEnd] = (uint) (geo.X + geo.Width - 1);105 values [(int) Struts.BottomEnd] = (uint) (geo.X + geo.Width - 1);
105 break;106 break;
106 case DockOrientation.Top:107 case DockOrientation.Top:
107 values [(int) XLib.Struts.Top] = (uint) (DockHeight + geo.Y);108 values [(int) Struts.Top] = (uint) (DockHeight + geo.Y);
108 values [(int) XLib.Struts.TopStart] = (uint) geo.X;109 values [(int) Struts.TopStart] = (uint) geo.X;
109 values [(int) XLib.Struts.TopEnd] = (uint) (geo.X + geo.Width - 1);110 values [(int) Struts.TopEnd] = (uint) (geo.X + geo.Width - 1);
110 break;111 break;
111 }112 }
112 return values;113 return values;
@@ -175,8 +176,11 @@
175 break;176 break;
176 }177 }
177 }178 }
179
178 CursorIsOverDockArea = dockRegion.Contains (cursor);180 CursorIsOverDockArea = dockRegion.Contains (cursor);
179 }181 }
182 Console.WriteLine (cursor);
183 Console.WriteLine (dockRegion);
180 184
181 // When we change over this boundry, it will normally trigger an animation, we need to be sure to catch it185 // When we change over this boundry, it will normally trigger an animation, we need to be sure to catch it
182 if (CursorIsOverDockArea != cursorIsOverDockArea) {186 if (CursorIsOverDockArea != cursorIsOverDockArea) {
183187
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs 2009-03-11 16:29:55 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/DockArea_Rendering.cs 2009-04-01 01:08:07 +0000
@@ -207,6 +207,8 @@
207 207
208 void DrawDrock (Context cr)208 void DrawDrock (Context cr)
209 {209 {
210 Console.WriteLine (VerticalOffset);
211 Console.WriteLine (CursorIsOverDockArea);
210 Gdk.Rectangle dockArea = GetDockArea ();212 Gdk.Rectangle dockArea = GetDockArea ();
211 DockBackgroundRenderer.RenderDockBackground (cr, dockArea);213 DockBackgroundRenderer.RenderDockBackground (cr, dockArea);
212214
213215
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs 2009-03-15 18:30:41 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/DockWindow.cs 2009-04-01 01:09:29 +0000
@@ -25,11 +25,11 @@
25using Cairo;25using Cairo;
2626
27using Docky.Utilities;27using Docky.Utilities;
28using Docky.XLib;
2928
30using Do.Universe;29using Do.Universe;
31using Do.Platform;30using Do.Platform;
32using Do.Interface;31using Do.Interface;
32using Do.Interface.Xlib;
33using Do.Interface.CairoUtils;33using Do.Interface.CairoUtils;
34using Do.Interface.AnimationBase;34using Do.Interface.AnimationBase;
3535
@@ -243,7 +243,9 @@
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);
244 break;244 break;
245 }245 }
246 Display.Sync ();246
247 if (Display != null)
248 Display.Sync ();
247 249
248 is_repositioned_hidden = false;250 is_repositioned_hidden = false;
249 }251 }
@@ -264,7 +266,8 @@
264 break;266 break;
265 }267 }
266268
267 Display.Sync ();269 if (Display != null)
270 Display.Sync ();
268 271
269 is_repositioned_hidden = true;272 is_repositioned_hidden = true;
270 }273 }
@@ -272,20 +275,21 @@
272 public void WindowHideOffset (out int x, out int y)275 public void WindowHideOffset (out int x, out int y)
273 {276 {
274 x = y = 0;277 x = y = 0;
275 278
276 if (!is_repositioned_hidden) {279 Gdk.Rectangle main, geo;
277 return;280 main.Width = dock_area.Width;
278 }281 main.Height = dock_area.Height;
279 282 GetBufferedPosition (out main.X, out main.Y);
280 Gdk.Rectangle main;283 geo = LayoutUtils.MonitorGemonetry ();
281 GetSize (out main.Width, out main.Height);284
285
282 switch (DockPreferences.Orientation) {286 switch (DockPreferences.Orientation) {
283 case DockOrientation.Bottom:287 case DockOrientation.Bottom:
284 y = main.Height;288 y = main.Y - ((geo.Y + geo.Height) - main.Height);
285 break;289 return;
286 case DockOrientation.Top:290 case DockOrientation.Top:
287 y = 0 - main.Height;291 y = main.Y - geo.Y;
288 break;292 return;
289 }293 }
290 }294 }
291 295
@@ -308,7 +312,7 @@
308 312
309 public bool SetStruts ()313 public bool SetStruts ()
310 {314 {
311 X11Atoms atoms = new X11Atoms (GdkWindow);315 X11Atoms atoms = X11Atoms.Instance;
312316
313 uint [] struts = dock_area.StrutRequest;317 uint [] struts = dock_area.StrutRequest;
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] };
@@ -318,10 +322,10 @@
318 if (!IsRealized)322 if (!IsRealized)
319 return false;323 return false;
320 Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT_PARTIAL, atoms.XA_CARDINAL,324 Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT_PARTIAL, atoms.XA_CARDINAL,
321 (int) XLib.PropertyMode.PropModeReplace, struts);325 (int) PropertyMode.PropModeReplace, struts);
322 326
323 Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT, atoms.XA_CARDINAL, 327 Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT, atoms.XA_CARDINAL,
324 (int) XLib.PropertyMode.PropModeReplace, first_struts);328 (int) PropertyMode.PropModeReplace, first_struts);
325 329
326 return false;330 return false;
327 }331 }
328332
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ApplicationDockItem.cs 2009-04-01 02:13:22 +0000
@@ -43,16 +43,6 @@
43 {43 {
44 public event EventHandler RemoveClicked;44 public event EventHandler RemoveClicked;
45 45
46 static readonly IEnumerable<string> DesktopFilesDirectories = new [] {
47 "~/.local/share/applications/wine",
48 "~/.local/share/applications",
49 "/usr/share/applications",
50 "/usr/share/applications/kde",
51 "/usr/share/applications/kde4",
52 "/usr/share/gdm/applications",
53 "/usr/local/share/applications",
54 };
55
56 string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore");46 string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore");
57 string MaximizeText = Catalog.GetString ("Maximize");47 string MaximizeText = Catalog.GetString ("Maximize");
58 string CloseText = Catalog.GetString ("Close All");48 string CloseText = Catalog.GetString ("Close All");
@@ -77,33 +67,23 @@
77 Gdk.Rectangle icon_region;67 Gdk.Rectangle icon_region;
78 Gdk.Pixbuf drag_pixbuf;68 Gdk.Pixbuf drag_pixbuf;
79 69
80 IEnumerable<Wnck.Application> applications;70 IEnumerable<Wnck.Window> windows;
81 71
82 string desktop_file;72 IApplicationItem launcher;
83 bool checked_desktop_file;73
84 74 public IApplicationItem Launcher {
85 public string DesktopFile {
86 get {75 get {
87 if (desktop_file == null && !checked_desktop_file) {76 if (launcher == null && Exec != null) {
88 checked_desktop_file = true;77 string command = WindowUtils.ProcessExecString (Exec);
89 foreach (string s in GetIconGuesses ()) {78 launcher = Services.UniverseFactory.MaybeApplicationItemFromCommand (command);
90 desktop_file = GetDesktopFile (s);
91 if (desktop_file != null)
92 break;
93 }
94 }79 }
95 return desktop_file;80 return launcher;
96 }81 }
97 }82 }
98 83
99 string Exec {84 string Exec {
100 get {85 get {
101 string exec;86 string exec;
102 foreach (Wnck.Application app in Applications) {
103 exec = MaybeGetExecStringForPID (app.Pid);
104 if (exec != null)
105 return exec;
106 }
10787
108 foreach (Wnck.Window win in VisibleWindows) {88 foreach (Wnck.Window win in VisibleWindows) {
109 exec = MaybeGetExecStringForPID (win.Pid);89 exec = MaybeGetExecStringForPID (win.Pid);
@@ -130,34 +110,23 @@
130 protected override Gdk.Pixbuf GetSurfacePixbuf (int size)110 protected override Gdk.Pixbuf GetSurfacePixbuf (int size)
131 {111 {
132 Gdk.Pixbuf pbuf = null;112 Gdk.Pixbuf pbuf = null;
133 foreach (string guess in GetIconGuesses ()) {113
134 if (pbuf != null) {114 if (Launcher == null) {
115 foreach (string guess in GetIconGuesses ()) {
116 bool found = IconProvider.PixbufFromIconName (guess, size, out pbuf);
117 if (found && (pbuf.Width == size || pbuf.Height == size))
118 break;
119
135 pbuf.Dispose ();120 pbuf.Dispose ();
136 pbuf = null;121 pbuf = null;
137 }122 }
138 123 } else {
139 bool found = IconProvider.PixbufFromIconName (guess, size, out pbuf);124 IconProvider.PixbufFromIconName (Launcher.Icon, size, out pbuf);
140 if (found && (pbuf.Width == size || pbuf.Height == size))
141 break;
142
143 pbuf.Dispose ();
144 pbuf = null;
145
146 string desktopPath = GetDesktopFile (guess);
147 if (!string.IsNullOrEmpty (desktopPath)) {
148 try {
149 string icon = Services.UniverseFactory.NewApplicationItem (desktopPath).Icon;
150 pbuf = IconProvider.PixbufFromIconName (icon, size);
151 break;
152 } catch {
153 continue;
154 }
155 }
156 }125 }
157 126
158 // we failed to find an icon, lets use an uggggly one127 // we failed to find an icon, lets use an uggggly one
159 if (pbuf == null)128 if (pbuf == null)
160 pbuf = Applications.First ().Icon;129 pbuf = Windows.First ().Icon;
161 130
162 if (pbuf.Height != size && pbuf.Width != size ) {131 if (pbuf.Height != size && pbuf.Width != size ) {
163 double scale = (double)size / Math.Max (pbuf.Width, pbuf.Height);132 double scale = (double)size / Math.Max (pbuf.Width, pbuf.Height);
@@ -170,14 +139,16 @@
170 139
171 string Name {140 string Name {
172 get {141 get {
173 foreach (Wnck.Application application in Applications) {142 if (NeedsAttention) {
174 if (StringIsValidName (application.IconName))143 return VisibleWindows.Where (w => w.NeedsAttention ()).First ().Name;
175 return application.IconName;144 }
176 else if (StringIsValidName (application.Name))145 if (VisibleWindows.Any () && VisibleWindows.Count () == 1) {
177 return application.Name;146 return VisibleWindows.First ().Name;
178 }147 }
179148
180 foreach (Wnck.Window window in VisibleWindows) {149 foreach (Wnck.Window window in VisibleWindows) {
150 if (StringIsValidName (window.ClassGroup.ResClass))
151 return window.ClassGroup.ResClass;
181 if (StringIsValidName (window.IconName))152 if (StringIsValidName (window.IconName))
182 return window.IconName;153 return window.IconName;
183 else if (StringIsValidName (window.Name))154 else if (StringIsValidName (window.Name))
@@ -191,13 +162,13 @@
191 get { return windowCount; }162 get { return windowCount; }
192 }163 }
193 164
194 protected override IEnumerable<Wnck.Application> Applications { 165 public override IEnumerable<Wnck.Window> Windows {
195 get { return applications; } 166 get { return windows; }
196 }167 }
197168
198 public ApplicationDockItem (IEnumerable<Wnck.Application> applications) : base ()169 public ApplicationDockItem (IEnumerable<Wnck.Window> windows) : base ()
199 {170 {
200 this.applications = applications;171 this.windows = windows;
201 windowCount = VisibleWindows.Count ();172 windowCount = VisibleWindows.Count ();
202 173
203 foreach (Wnck.Window w in VisibleWindows) {174 foreach (Wnck.Window w in VisibleWindows) {
@@ -227,41 +198,49 @@
227 if (VisibleWindows.Count () == 0)198 if (VisibleWindows.Count () == 0)
228 Core.DockServices.ItemsService.ForceUpdate ();199 Core.DockServices.ItemsService.ForceUpdate ();
229 }200 }
201
202 SetText (Name);
230 }203 }
231 204
232 IEnumerable<string> GetIconGuesses ()205 IEnumerable<string> GetIconGuesses ()
233 {206 {
234 List<string> guesses = new List<string> ();207 List<string> guesses = new List<string> ();
235 208
236 if (!string.IsNullOrEmpty (Exec)) {209 // open office hack...
237 yield return Exec;210 if (VisibleWindows.Any () &&
238 yield return Exec.Split ('-')[0];211 VisibleWindows.First ().ClassGroup != null &&
212 VisibleWindows.First ().ClassGroup.ResClass.ToLower ().Contains ("openoffice")) {
213 yield return "openoffice";
214 yield break;
239 }215 }
240 216
241 foreach (Wnck.Application app in Applications) {217 string exec = Exec;
242 if (!guesses.Contains (PrepName (app.Name)))218 if (!string.IsNullOrEmpty (exec)) {
243 guesses.Add (PrepName (app.Name));219 yield return exec;
244 if (!guesses.Contains (PrepName (app.IconName)))220 yield return exec.Split ('-')[0];
245 guesses.Add (PrepName (app.IconName));221 yield return WindowUtils.ProcessExecString (exec);
246 }222 }
247223
248 foreach (Wnck.Window win in VisibleWindows) {224 foreach (Wnck.Window win in VisibleWindows) {
249 if (!guesses.Contains (PrepName (win.Name)))225 if (!guesses.Contains (PrepName (win.Name)))
250 guesses.Add (PrepName (win.Name));226 guesses.Add (PrepName (win.Name));
227
251 if (!guesses.Contains (PrepName (win.IconName)))228 if (!guesses.Contains (PrepName (win.IconName)))
252 guesses.Add (PrepName (win.IconName));229 guesses.Add (PrepName (win.IconName));
230
231 if (win.ClassGroup == null)
232 continue;
233
253 if (!guesses.Contains (PrepName (win.ClassGroup.ResClass)))234 if (!guesses.Contains (PrepName (win.ClassGroup.ResClass)))
254 guesses.Add (PrepName (win.ClassGroup.ResClass));235 guesses.Add (PrepName (win.ClassGroup.ResClass));
236
237 if (!guesses.Contains (PrepName (win.ClassGroup.Name)))
238 guesses.Add (PrepName (win.ClassGroup.Name));
255 }239 }
256 240
257 foreach (string s in guesses)241 foreach (string s in guesses) {
258 yield return s;242 yield return s;
259 243 }
260 foreach (string s in guesses)
261 yield return "gnome-" + s;
262
263 if (Name.Length > 4 && Name.Contains (" "))
264 yield return Name.Split (' ') [0].ToLower ();
265 }244 }
266245
267 string PrepName (string s)246 string PrepName (string s)
@@ -283,27 +262,14 @@
283 return exec;262 return exec;
284 }263 }
285 264
286 string GetDesktopFile (string base_name)
287 {
288 foreach (string dir in DesktopFilesDirectories) {
289 try {
290 if (File.Exists (System.IO.Path.Combine (dir, base_name+".desktop")))
291 return System.IO.Path.Combine (dir, base_name+".desktop");
292 if (File.Exists (System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop")))
293 return System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop");
294 } catch { return null; }
295 }
296 return null;
297 }
298
299 bool StringIsValidName (string s)265 bool StringIsValidName (string s)
300 {266 {
301 s = s.Trim ();267 s = s.Trim ();
302 if (string.IsNullOrEmpty (s) || s == "<unknown>")268 if (string.IsNullOrEmpty (s) || s == "<unknown>")
303 return false;269 return false;
304 270
305 foreach (string prefix in WindowUtils.BadPrefixes) {271 foreach (System.Text.RegularExpressions.Regex prefix in WindowUtils.BadPrefixes) {
306 if (string.Compare (s, prefix, true) == 0)272 if (prefix.IsMatch (s))
307 return false;273 return false;
308 }274 }
309 275
@@ -324,14 +290,15 @@
324 if (!(other is ApplicationDockItem))290 if (!(other is ApplicationDockItem))
325 return false;291 return false;
326292
327 return Applications.Any (app => (other as ApplicationDockItem).Applications.Contains (app));293 return Windows.Any (w => (other as ApplicationDockItem).Windows.Contains (w));
328 }294 }
329 295
330 public IEnumerable<AbstractMenuArgs> GetMenuItems ()296 public IEnumerable<AbstractMenuArgs> GetMenuItems ()
331 {297 {
332 yield return new SeparatorMenuButtonArgs ();298 yield return new SeparatorMenuButtonArgs ();
333 299
334 if (DesktopFile == null) {300 Item item = Launcher as Item;
301 if (item == null) {
335 yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows), 302 yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows),
336 MinimizeRestoreText, MinimizeIcon).AsDark ();303 MinimizeRestoreText, MinimizeIcon).AsDark ();
337 304
@@ -341,8 +308,6 @@
341 yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows), 308 yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows),
342 CloseText, CloseIcon).AsDark ();309 CloseText, CloseIcon).AsDark ();
343 } else {310 } else {
344 Item item = Services.UniverseFactory.NewApplicationItem (DesktopFile) as Item;
345
346 foreach (Act act in ActionsForItem (item))311 foreach (Act act in ActionsForItem (item))
347 yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark ();312 yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark ();
348 }313 }
@@ -352,6 +317,12 @@
352 yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon);317 yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon);
353 }318 }
354 }319 }
320
321 protected override void Launch ()
322 {
323 if (Launcher != null)
324 Launcher.Run ();
325 }
355326
356 public override void Dispose ()327 public override void Dispose ()
357 {328 {
358329
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/ItemDockItem.cs 2009-03-25 03:40:59 +0000
@@ -52,7 +52,7 @@
52 bool accepting_drops;52 bool accepting_drops;
53 Gdk.Pixbuf drag_pixbuf;53 Gdk.Pixbuf drag_pixbuf;
54 Gdk.Rectangle icon_region;54 Gdk.Rectangle icon_region;
55 List<Wnck.Application> apps;55 List<Wnck.Window> windows;
56 56
57 public event EventHandler RemoveClicked;57 public event EventHandler RemoveClicked;
58 58
@@ -64,16 +64,32 @@
64 get { return element.Icon; } 64 get { return element.Icon; }
65 }65 }
66 66
67 string Name {
68 get {
69 if (NeedsAttention && AttentionWindows.Any ())
70 return AttentionWindows.First ().Name;
71
72 if (VisibleWindows.Any () && WindowCount == 1)
73 return VisibleWindows.First ().Name;
74
75 return Element.Name;
76 }
77 }
78
67 public Item Element { 79 public Item Element {
68 get { return element; } 80 get { return element; }
69 }81 }
70 82
71 protected override IEnumerable<Wnck.Application> Applications { 83 public override IEnumerable<Wnck.Window> Windows {
72 get { return apps; } 84 get { return windows; }
85 }
86
87 IEnumerable<Wnck.Window> AttentionWindows {
88 get { return VisibleWindows.Where (w => w.NeedsAttention ()); }
73 }89 }
74 90
75 public IEnumerable<int> Pids { 91 public IEnumerable<int> Pids {
76 get { return apps.Select (win => win.Pid).ToArray (); } 92 get { return windows.Select (win => win.Pid).ToArray (); }
77 }93 }
78 94
79 public override int WindowCount {95 public override int WindowCount {
@@ -84,9 +100,7 @@
84 {100 {
85 Position = -1;101 Position = -1;
86 this.element = element;102 this.element = element;
87 apps = new List<Wnck.Application> ();103 windows = new List<Wnck.Window> ();
88
89 SetText (element.Name);
90104
91 UpdateApplication ();105 UpdateApplication ();
92 NeedsAttention = DetermineUrgencyStatus ();106 NeedsAttention = DetermineUrgencyStatus ();
@@ -95,6 +109,8 @@
95 accepting_drops = true;109 accepting_drops = true;
96 else110 else
97 accepting_drops = false;111 accepting_drops = false;
112
113 SetText (Name);
98 }114 }
99 115
100 public override bool ReceiveItem (string item)116 public override bool ReceiveItem (string item)
@@ -126,46 +142,49 @@
126 142
127 public void UpdateApplication ()143 public void UpdateApplication ()
128 {144 {
129 UnregisterStateChangeEvents ();145 UnregisterWindowEvents ();
130 146
131 if (element is IApplicationItem) {147 if (element is IApplicationItem) {
132 apps = WindowUtils.GetApplicationList ((element as IApplicationItem).Exec);148 windows = WindowUtils.WindowListForCmd ((element as IApplicationItem).Exec);
133 window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();149 window_count = windows.Where (w => !w.IsSkipTasklist).Count ();
134 }150 }
135 151
136 RegisterStateChangeEvents ();152 RegisterWindowEvents ();
137 }153 SetText (Name);
138 154 }
139 void RegisterStateChangeEvents ()155
140 {156 void RegisterWindowEvents ()
141 foreach (Application app in Applications) {157 {
142 foreach (Wnck.Window w in app.Windows) {158 foreach (Wnck.Window w in VisibleWindows) {
143 if (!w.IsSkipTasklist)159 w.StateChanged += HandleStateChanged;
144 w.StateChanged += OnWindowStateChanged;160 w.NameChanged += HandleNameChanged;
145 }161 }
146 }162 }
147 }163
148 164 void UnregisterWindowEvents ()
149 void UnregisterStateChangeEvents ()165 {
150 {166 foreach (Wnck.Window w in Windows) {
151 foreach (Application app in Applications) {167 try {
152 foreach (Wnck.Window w in app.Windows) {168 w.StateChanged -= HandleStateChanged;
153 try {169 w.NameChanged += HandleNameChanged;
154 w.StateChanged -= OnWindowStateChanged;170 } catch {}
155 } catch {}171 }
156 }172 }
157 }173
158 }174 void HandleStateChanged (object o, StateChangedArgs args)
159
160 void OnWindowStateChanged (object o, StateChangedArgs args)
161 {175 {
162 if (handle_timer > 0) return;176 if (handle_timer > 0) return;
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.
164 handle_timer = GLib.Timeout.Add (100, HandleUpdate);178 handle_timer = GLib.Timeout.Add (100, HandleUpdate);
165 window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();179 window_count = VisibleWindows.Count ();
166 SetIconRegionFromCache ();180 SetIconRegionFromCache ();
167 }181 }
168 182
183 void HandleNameChanged(object sender, EventArgs e)
184 {
185 SetText (Name);
186 }
187
169 bool HandleUpdate ()188 bool HandleUpdate ()
170 {189 {
171 bool needed_attention = NeedsAttention;190 bool needed_attention = NeedsAttention;
@@ -180,6 +199,7 @@
180 OnUpdateNeeded (new UpdateRequestArgs (this, req));199 OnUpdateNeeded (new UpdateRequestArgs (this, req));
181 }200 }
182 201
202 SetText (Name);
183 handle_timer = 0;203 handle_timer = 0;
184 return false;204 return false;
185 }205 }
@@ -250,9 +270,9 @@
250 270
251 public override void Dispose ()271 public override void Dispose ()
252 {272 {
253 UnregisterStateChangeEvents ();273 UnregisterWindowEvents ();
254 element = null;274 element = null;
255 apps.Clear ();275 windows.Clear ();
256 276
257 if (drag_pixbuf != null)277 if (drag_pixbuf != null)
258 drag_pixbuf.Dispose ();278 drag_pixbuf.Dispose ();
259279
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Items/WnckDockItem.cs 2009-04-01 01:08:07 +0000
@@ -42,20 +42,26 @@
42 42
43 public abstract class WnckDockItem : AbstractDockItem43 public abstract class WnckDockItem : AbstractDockItem
44 {44 {
45 // a bad hack, but it works
46 static string [] blacklist = new [] {
47 "CopyToClipboardAction",
48 "WindowFocusAction",
49 };
50
45 int last_raised;51 int last_raised;
4652
47 DateTime last_scroll = new DateTime (0);53 DateTime last_scroll = new DateTime (0);
48 TimeSpan scroll_rate = new TimeSpan (0, 0, 0, 0, 300);54 TimeSpan scroll_rate = new TimeSpan (0, 0, 0, 0, 300);
49 55
50 protected abstract IEnumerable<Wnck.Application> Applications { get; }56 public abstract IEnumerable<Wnck.Window> Windows { get; }
51 57
52 protected IEnumerable<Wnck.Window> VisibleWindows {58 protected IEnumerable<Wnck.Window> VisibleWindows {
53 get { return Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist); }59 get { return Windows.Where (w => !w.IsSkipTasklist); }
54 }60 }
55 61
56 protected bool HasVisibleApps {62 protected bool HasVisibleApps {
57 get {63 get {
58 if (Applications == null)64 if (Windows == null)
59 return false;65 return false;
60 return VisibleWindows.Any ();66 return VisibleWindows.Any ();
61 }67 }
@@ -69,7 +75,7 @@
69 protected IEnumerable<Act> ActionsForItem (Item item) 75 protected IEnumerable<Act> ActionsForItem (Item item)
70 {76 {
71 return Services.Core.GetActionsForItemOrderedByRelevance (item, false)77 return Services.Core.GetActionsForItemOrderedByRelevance (item, false)
72 .Where (act => act.GetType ().Name != "CopyToClipboardAction")78 .Where (act => !blacklist.Contains (act.GetType ().Name))
73 .OrderByDescending (act => act.GetType ().Name != "WindowCloseAction")79 .OrderByDescending (act => act.GetType ().Name != "WindowCloseAction")
74 .ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction")80 .ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction")
75 .ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction")81 .ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction")
@@ -77,10 +83,7 @@
77 .ThenBy (act => act.Name);83 .ThenBy (act => act.Name);
78 }84 }
79 85
80 protected virtual void Launch ()86 protected abstract void Launch ();
81 {
82 return;
83 }
84 87
85 public override void Scrolled (Gdk.ScrollDirection direction)88 public override void Scrolled (Gdk.ScrollDirection direction)
86 {89 {
@@ -115,12 +118,12 @@
115 118
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)
117 {120 {
118 if (!Applications.Any () || !HasVisibleApps || button == 2) {121 if (!Windows.Any () || !HasVisibleApps || button == 2) {
119 AnimationType = ClickAnimationType.Bounce;122 AnimationType = ClickAnimationType.Bounce;
120 Launch ();123 Launch ();
121 } else if (button == 1) {124 } else if (button == 1) {
122 AnimationType = ClickAnimationType.Darken;125 AnimationType = ClickAnimationType.Darken;
123 WindowUtils.PerformLogicalClick (Applications);126 WindowUtils.PerformLogicalClick (Windows);
124 } else {127 } else {
125 AnimationType = ClickAnimationType.None;128 AnimationType = ClickAnimationType.None;
126 }129 }
127130
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs 2009-03-07 22:50:28 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/AbstractMenuButtonArgs.cs 2009-03-26 14:42:21 +0000
@@ -39,7 +39,8 @@
39 const int Height = 22;39 const int Height = 22;
40 40
41 Gtk.Widget widget;41 Gtk.Widget widget;
42 bool hovered;42 bool hovered, tooltip;
43 string description, icon;
43 44
44 public bool Dark { get; set; }45 public bool Dark { get; set; }
45 46
@@ -47,33 +48,60 @@
47 get { return 1; }48 get { return 1; }
48 }49 }
49 50
50 public override Gtk.Widget Widget { 51 public override Gtk.Widget Widget {
51 get {52 get { return widget; }
52 if (widget == null)53 }
53 widget = BuildWidget ();54
54 return widget;55 private Gdk.Pixbuf Pixbuf { get; set; }
55 }56
56 }57 protected string Description {
57 58 get {
58 protected virtual string Description { get; set; }59 return description;
59 60 }
60 protected virtual string Icon { get; set; }61 set {
61 62 description = value;
62 protected virtual bool UseTooltip { get; set; }63 BuildWidget ();
64 }
65 }
66
67 protected string Icon {
68 get {
69 return icon;
70 }
71 set {
72 icon = value;
73 BuildWidget ();
74 }
75 }
76
77 protected bool UseTooltip {
78 get {
79 return tooltip;
80 }
81 set {
82
83 tooltip = value;
84 BuildWidget ();
85 }
86 }
63 87
64 public AbstractMenuButtonArgs ()88 public AbstractMenuButtonArgs ()
65 {89 {
66
67 }90 }
68 91
69 public AbstractMenuButtonArgs (string description, string icon)92 public AbstractMenuButtonArgs (string description, string icon)
70 {93 {
71 Description = GLib.Markup.EscapeText (Catalog.GetString (description));94 this.description = GLib.Markup.EscapeText (Catalog.GetString (description));
72 Icon = icon;95 this.icon = icon;
96
97 BuildWidget ();
73 }98 }
74 99
75 Widget BuildWidget ()100 void BuildWidget ()
76 {101 {
102 if (widget != null)
103 widget.Destroy ();
104
77 DrawingArea button = new DrawingArea ();105 DrawingArea button = new DrawingArea ();
78 106
79 button.ExposeEvent += HandleExposeEvent;107 button.ExposeEvent += HandleExposeEvent;
@@ -88,7 +116,12 @@
88 if (UseTooltip)116 if (UseTooltip)
89 button.TooltipText = Description;117 button.TooltipText = Description;
90 118
91 return button;119 widget = button;
120
121 if (Pixbuf != null)
122 Pixbuf.Dispose ();
123
124 Pixbuf = GetPixbuf (Height - 8);
92 }125 }
93 126
94 void HandleButtonReleaseEvent(object o, ButtonReleaseEventArgs args)127 void HandleButtonReleaseEvent(object o, ButtonReleaseEventArgs args)
@@ -135,27 +168,31 @@
135 168
136 int width = area.Width - WidthBuffer * 2 - 25;169 int width = area.Width - WidthBuffer * 2 - 25;
137 170
138 TextRenderContext renderContext = new TextRenderContext (cr, string.Format (FormatString, Description), width);171 if (!string.IsNullOrEmpty (Description)) {
139 172 TextRenderContext renderContext = new TextRenderContext (cr, string.Format (FormatString, Description), width);
140 renderContext.LeftCenteredPoint = new Gdk.Point (area.X + WidthBuffer + 25, area.Y + area.Height / 2);173
141 renderContext.Alignment = Pango.Alignment.Left;174 renderContext.LeftCenteredPoint = new Gdk.Point (area.X + WidthBuffer + 25, area.Y + area.Height / 2);
142 renderContext.EllipsizeMode = Pango.EllipsizeMode.End;175 renderContext.Alignment = Pango.Alignment.Left;
143 176 renderContext.EllipsizeMode = Pango.EllipsizeMode.End;
144 DockServices.DrawingService.TextPathAtPoint (renderContext);177
145 178 DockServices.DrawingService.TextPathAtPoint (renderContext);
146 cr.Color = new Cairo.Color (1, 1, 1);179
147 cr.Fill ();180 cr.Color = new Cairo.Color (1, 1, 1);
148 181 cr.Fill ();
149 Gdk.Pixbuf pbuf = GetPixbuf (Height - 8);182 }
150 CairoHelper.SetSourcePixbuf (cr, pbuf, WidthBuffer, (Height - pbuf.Height) / 2);183
151 cr.PaintWithAlpha (IconOpacity);184 if (Pixbuf != null) {
152 pbuf.Dispose ();185 CairoHelper.SetSourcePixbuf (cr, Pixbuf, WidthBuffer, (Height - Pixbuf.Height) / 2);
186 cr.PaintWithAlpha (IconOpacity);
187 }
153 }188 }
154 }189 }
155 190
156 protected virtual Gdk.Pixbuf GetPixbuf (int size)191 protected virtual Gdk.Pixbuf GetPixbuf (int size)
157 {192 {
158 return IconProvider.PixbufFromIconName (Icon, size);193 if (!string.IsNullOrEmpty (Icon))
194 return IconProvider.PixbufFromIconName (Icon, size);
195 return null;
159 }196 }
160 197
161 public abstract void Action ();198 public abstract void Action ();
@@ -169,6 +206,7 @@
169 public override void Dispose ()206 public override void Dispose ()
170 {207 {
171 Widget.Destroy ();208 Widget.Destroy ();
209 Pixbuf.Dispose ();
172 base.Dispose ();210 base.Dispose ();
173 }211 }
174212
175213
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Docky.Interface.Menus/WindowMenuButtonArgs.cs 2009-03-26 04:33:12 +0000
@@ -38,7 +38,6 @@
38 return (window.IsMinimized) ? .5 : base.IconOpacity;38 return (window.IsMinimized) ? .5 : base.IconOpacity;
39 }39 }
40 }40 }
41
42 41
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)
44 {43 {
4544
=== modified file 'Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs'
--- Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Linux.Docky/src/Docky.Interface/Util.cs 2009-03-24 16:08:07 +0000
@@ -78,7 +78,8 @@
78 DockOrientation orientation)78 DockOrientation orientation)
79 {79 {
80 Surface sr;80 Surface sr;
81 sr = similar.CreateSimilar (similar.Content, maxWidth, Height);81 // we are going to give ourselves a bit of a buffer due to pango weirdness
82 sr = similar.CreateSimilar (similar.Content, maxWidth + 5, Height);
82 83
83 Context cr = new Context (sr);84 Context cr = new Context (sr);
84 85
@@ -89,7 +90,7 @@
89 cr.NewPath ();90 cr.NewPath ();
90 91
91 int localHeight = textArea.Height;92 int localHeight = textArea.Height;
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);
93 94
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);
95 cr.FillPreserve ();96 cr.FillPreserve ();
9697
=== modified file 'Do.Interface.Wink/Do.Interface.Wink.mdp'
--- Do.Interface.Wink/Do.Interface.Wink.mdp 2009-03-20 20:43:06 +0000
+++ Do.Interface.Wink/Do.Interface.Wink.mdp 2009-03-31 03:39:44 +0000
@@ -20,11 +20,20 @@
20 <File name="src/AssemblyInfo.cs" subtype="Code" buildaction="Compile" />20 <File name="src/AssemblyInfo.cs" subtype="Code" buildaction="Compile" />
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" />
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" />
23 <File name="src/Do.Interface.Wink/ClickAction.cs" subtype="Code" buildaction="Compile" />
24 <File name="src/Do.Interface.Wink/ScreenUtils.cs" subtype="Code" buildaction="Compile" />
25 <File name="src/Do.Interface.Wink/Viewport.cs" subtype="Code" buildaction="Compile" />
26 <File name="src/Do.Interface.Xlib" subtype="Directory" buildaction="Compile" />
27 <File name="src/Do.Interface.Xlib/X11Atoms.cs" subtype="Code" buildaction="Compile" />
28 <File name="src/Do.Interface.Xlib/Xlib.cs" subtype="Code" buildaction="Compile" />
23 </Contents>29 </Contents>
24 <References>30 <References>
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" />
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" />
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" />
28 <ProjectReference type="Project" localcopy="True" refto="Do.Platform" />34 <ProjectReference type="Project" localcopy="True" refto="Do.Platform" />
35 <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
36 <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
37 <ProjectReference type="Gac" localcopy="True" refto="Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
29 </References>38 </References>
30</Project>39</Project>
31\ No newline at end of file40\ No newline at end of file
3241
=== modified file 'Do.Interface.Wink/Makefile.am'
--- Do.Interface.Wink/Makefile.am 2009-03-20 23:06:10 +0000
+++ Do.Interface.Wink/Makefile.am 2009-03-31 16:23:23 +0000
@@ -8,8 +8,13 @@
88
9FILES = \9FILES = \
10 src/AssemblyInfo.cs \10 src/AssemblyInfo.cs \
11 src/Do.Interface.Xlib/Xlib.cs \
12 src/Do.Interface.Xlib/X11Atoms.cs \
13 src/Do.Interface.Wink/ClickAction.cs \
11 src/Do.Interface.Wink/WindowControl.cs \14 src/Do.Interface.Wink/WindowControl.cs \
12 src/Do.Interface.Wink/WindowUtils.cs15 src/Do.Interface.Wink/WindowUtils.cs \
16 src/Do.Interface.Wink/ScreenUtils.cs \
17 src/Do.Interface.Wink/Viewport.cs
1318
14#RESOURCES = \19#RESOURCES = \
15# Resources/Do.Interface.Wnck.addin.xml20# Resources/Do.Interface.Wnck.addin.xml
@@ -17,11 +22,12 @@
17REFERENCES = \22REFERENCES = \
18 System \23 System \
19 System.Core \24 System.Core \
25 Mono.Posix \
20 $(GTK_SHARP_20_LIBS) \26 $(GTK_SHARP_20_LIBS) \
21 $(WNCK_SHARP_10_LIBS)27 $(WNCK_SHARP_10_LIBS)
2228
23PROJECT_REFERENCES = \29PROJECT_REFERENCES = \
24 Do.Platform30 Do.Platform
2531
26#module_DATA += $(ASSEMBLY).dll.config32module_DATA += $(ASSEMBLY).dll.config
27#EXTRA_DIST += $(ASSEMBLY).dll.config33EXTRA_DIST += $(ASSEMBLY).dll.config
2834
=== added file 'Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs'
--- Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs 1970-01-01 00:00:00 +0000
+++ Do.Interface.Wink/src/Do.Interface.Wink/ClickAction.cs 2009-03-25 19:49:42 +0000
@@ -0,0 +1,31 @@
1//
2// Copyright (C) 2009 GNOME Do
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17
18using System;
19
20namespace Do.Interface.Wink
21{
22
23
24 public enum ClickAction
25 {
26 Focus,
27 Minimize,
28 Restore,
29 None,
30 }
31}
032
=== added file 'Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs'
--- Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs 1970-01-01 00:00:00 +0000
+++ Do.Interface.Wink/src/Do.Interface.Wink/ScreenUtils.cs 2009-04-01 01:08:07 +0000
@@ -0,0 +1,138 @@
1//
2// Copyright (C) 2009 GNOME Do
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17
18using System;
19using System.Collections.Generic;
20using System.Linq;
21
22using Mono.Unix;
23
24using Wnck;
25
26namespace Do.Interface.Wink
27{
28
29
30 public static class ScreenUtils
31 {
32 static string ViewportFormatString = Catalog.GetString ("Desktop") + " {0}";
33 static List<Viewport> viewports;
34
35 public static Viewport ActiveViewport {
36 get {
37 Workspace wsp = Wnck.Screen.Default.ActiveWorkspace;
38 Gdk.Rectangle geo = new Gdk.Rectangle (wsp.ViewportX, wsp.ViewportY, wsp.Screen.Width, wsp.Screen.Height);
39 if (viewports.Any (vp => vp.Area == geo))
40 return viewports.First (vp => vp.Area == geo);
41 return null;
42 }
43 }
44
45 public static IEnumerable<Viewport> Viewports {
46 get { return viewports.AsEnumerable (); }
47 }
48
49 static ScreenUtils ()
50 {
51 Wnck.Screen.Default.ViewportsChanged += HandleViewportsChanged;
52 Wnck.Screen.Default.WorkspaceCreated += HandleWorkspaceCreated;
53 Wnck.Screen.Default.WorkspaceDestroyed += HandleWorkspaceDestroyed;
54
55// Wnck.Screen.Default.ForceUpdate ();
56 UpdateViewports ();
57 }
58
59 static void HandleWorkspaceDestroyed(object o, WorkspaceDestroyedArgs args)
60 {
61 UpdateViewports ();
62 }
63
64 static void HandleWorkspaceCreated(object o, WorkspaceCreatedArgs args)
65 {
66 UpdateViewports ();
67 }
68
69 static void HandleViewportsChanged(object sender, EventArgs e)
70 {
71 UpdateViewports ();
72 }
73
74 public static bool DesktopShow (Screen screen)
75 {
76 return screen.ShowingDesktop;
77 }
78
79 public static void ShowDesktop (Screen screen)
80 {
81 if (!screen.ShowingDesktop)
82 screen.ToggleShowingDesktop (true);
83 }
84
85 public static void UnshowDesktop (Screen screen)
86 {
87 if (screen.ShowingDesktop)
88 screen.ToggleShowingDesktop (false);
89 }
90
91 public static IEnumerable<Window> ViewportWindows (Viewport viewport)
92 {
93 var windows = WindowUtils.GetWindows ()
94 .Where (w => w.WindowType != WindowType.Dock && !w.IsSkipTasklist);
95
96 foreach (Window window in windows) {
97 if (viewport.WindowCenterInViewport (window))
98 yield return window;
99 }
100 }
101
102 static void UpdateViewports ()
103 {
104 viewports = new List<Viewport> ();
105 int currentViewport = 1;
106 foreach (Wnck.Workspace workspace in Wnck.Screen.Default.Workspaces) {
107 if (workspace.IsVirtual) {
108 int viewportWidth;
109 int viewportHeight;
110 viewportWidth = workspace.Screen.Width;
111 viewportHeight = workspace.Screen.Height;
112
113 int rows = workspace.Height / viewportHeight;
114 int columns = workspace.Width / viewportWidth;
115
116 for (int i = 0; i < rows; i++) {
117 for (int j = 0; j < columns; j++) {
118 Gdk.Rectangle area = new Gdk.Rectangle (j * viewportWidth,
119 i * viewportHeight,
120 viewportWidth,
121 viewportHeight);
122 viewports.Add (new Viewport (string.Format (ViewportFormatString, currentViewport),
123 area,
124 workspace));
125 currentViewport++;
126 }
127 }
128 } else {
129 Viewport viewport = new Viewport (string.Format (ViewportFormatString, currentViewport),
130 new Gdk.Rectangle (0, 0, workspace.Width, workspace.Height),
131 workspace);
132 viewports.Add (viewport);
133 currentViewport++;
134 }
135 }
136 }
137 }
138}
0139
=== added file 'Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs'
--- Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs 1970-01-01 00:00:00 +0000
+++ Do.Interface.Wink/src/Do.Interface.Wink/Viewport.cs 2009-03-31 16:23:23 +0000
@@ -0,0 +1,142 @@
1//
2// Copyright (C) 2009 GNOME Do
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17
18using System;
19using System.Collections.Generic;
20using System.Runtime.InteropServices;
21
22
23using Gdk;
24using Wnck;
25
26using Do.Platform;
27using Do.Interface.Xlib;
28
29namespace Do.Interface.Wink
30{
31
32
33 public class Viewport
34 {
35 Workspace parent;
36 Rectangle area;
37
38 public string Name { get; private set; }
39
40 internal Rectangle Area {
41 get { return area; }
42 }
43
44 internal Viewport(string name, Rectangle area, Workspace parent)
45 {
46 this.area = area;
47 this.parent = parent;
48 Name = name;
49 }
50
51 public void MoveWindowInto (Wnck.Window window)
52 {
53 if (parent.IsVirtual) {
54 Rectangle geo;
55 window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height);
56
57 geo.X += window.Workspace.ViewportX;
58 geo.Y += window.Workspace.ViewportY;
59
60 int x = area.X + (geo.X % area.Width);
61 int y = area.Y + (geo.Y % area.Height);
62
63 x -= window.Workspace.ViewportX;
64 y -= window.Workspace.ViewportY;
65
66 if (string.Compare (window.Screen.WindowManagerName, "compiz", true) == 0) {
67 // This is a compiz-ism. Don't know when they will fix it. You must subtract the top and left
68 // frame extents from a move operation to get the window to actually show in the right spot.
69 // Save for maybe kwin, I think only compiz uses Viewports anyhow, so this is ok.
70 int [] extents = GetWindowFrameExtents (window);
71 int left_extent = extents [0];
72 int top_extent = extents [2];
73
74 x -= left_extent;
75 y -= top_extent;
76 }
77
78 WindowMoveResizeMask mask = WindowMoveResizeMask.X | WindowMoveResizeMask.Y;
79 window.SetGeometry (WindowGravity.Current, mask, x, y, 0, 0);
80 } else {
81 window.MoveToWorkspace (parent);
82 }
83 }
84
85 int[] GetWindowFrameExtents (Wnck.Window window)
86 {
87 X11Atoms atoms = X11Atoms.Instance;
88
89 IntPtr display;
90 IntPtr type;
91 int format;
92 IntPtr prop_return;
93 IntPtr nitems, bytes_after;
94 int result;
95 int [] extents = new int[4];
96
97 IntPtr window_handle = (IntPtr) window.Xid;
98
99 display = Xlib.Xlib.GdkDisplayXDisplay (Gdk.Screen.Default.Display);
100 type = IntPtr.Zero;
101
102 result = Xlib.Xlib.XGetWindowProperty (display, window_handle, atoms._NET_FRAME_EXTENTS, (IntPtr) 0,
103 (IntPtr) System.Int32.MaxValue, false, atoms.XA_CARDINAL, out type, out format,
104 out nitems, out bytes_after, out prop_return);
105
106 if (type == atoms.XA_CARDINAL && format == 32) {
107 extents = new int [(int) nitems];
108 for (int i = 0; i < (int) nitems; i++) {
109 extents [i] = Marshal.ReadInt32 (prop_return, i * 4);
110 }
111 }
112
113 return extents;
114 }
115
116 public bool WindowVisibleInVeiwport (Wnck.Window window)
117 {
118 Rectangle geo;
119 window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height);
120 geo.X += parent.ViewportX;
121 geo.Y += parent.ViewportY;
122
123 return area.IntersectsWith (geo);
124 }
125
126 public bool WindowCenterInViewport (Wnck.Window window)
127 {
128 Rectangle geo;
129 window.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height);
130 geo.X += parent.ViewportX;
131 geo.Y += parent.ViewportY;
132
133 Point center = new Point (geo.X + geo.Width / 2, geo.Y + geo.Height / 2);
134 return Contains (center);
135 }
136
137 public bool Contains (Gdk.Point point)
138 {
139 return area.Contains (point);
140 }
141 }
142}
0143
=== modified file 'Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs'
--- Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs 2009-03-20 20:43:06 +0000
+++ Do.Interface.Wink/src/Do.Interface.Wink/WindowControl.cs 2009-03-31 03:39:44 +0000
@@ -88,11 +88,18 @@
88 88
89 public static void FocusWindows (IEnumerable<Window> windows)89 public static void FocusWindows (IEnumerable<Window> windows)
90 {90 {
91 foreach (Window window in windows.Reverse ()) {91 if (!windows.Any ())
92 if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {92 return;
93 window.CenterAndFocusWindow ();93
94 System.Threading.Thread.Sleep (SleepTime);94 if (windows.Any (w => w.IsInViewport (w.Screen.ActiveWorkspace))) {
95 foreach (Window window in windows.Reverse ()) {
96 if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
97 window.CenterAndFocusWindow ();
98 System.Threading.Thread.Sleep (SleepTime);
99 }
95 }100 }
101 } else {
102 windows.First ().CenterAndFocusWindow ();
96 }103 }
97 104
98 if (windows.Count () <= 1)105 if (windows.Count () <= 1)
@@ -102,7 +109,9 @@
102 // sometimes compiz plays badly. This hacks around it109 // sometimes compiz plays badly. This hacks around it
103 uint time = Gtk.Global.CurrentEventTime + 200;110 uint time = Gtk.Global.CurrentEventTime + 200;
104 GLib.Timeout.Add (200, delegate {111 GLib.Timeout.Add (200, delegate {
105 windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time);112 try { //unimportant if this fails, its just "nice"
113 windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time);
114 } catch { }
106 return false;115 return false;
107 });116 });
108 }117 }
@@ -187,6 +196,17 @@
187 window.Maximize ();196 window.Maximize ();
188 }197 }
189 198
199 public static void MoveToWorkspace (Window window, Workspace workspace)
200 {
201 MoveToWorkspace (new [] {window}, workspace);
202 }
203
204 public static void MoveToWorkspace (IEnumerable<Window> windows, Workspace workspace)
205 {
206 foreach (Window window in windows.Where (w => w.Workspace != workspace))
207 window.MoveToWorkspace (workspace);
208 }
209
190 /// <summary>210 /// <summary>
191 /// Moves the current viewport to the selected window and then raises it211 /// Moves the current viewport to the selected window and then raises it
192 /// </summary>212 /// </summary>
193213
=== modified file 'Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs'
--- Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs 2009-03-21 02:35:05 +0000
+++ Do.Interface.Wink/src/Do.Interface.Wink/WindowUtils.cs 2009-04-01 01:08:07 +0000
@@ -29,12 +29,6 @@
2929
30namespace Do.Interface.Wink30namespace Do.Interface.Wink
31{31{
32 public enum ClickAction {
33 Focus,
34 Minimize,
35 Restore,
36 None,
37 }
38 32
39 public static class WindowUtils33 public static class WindowUtils
40 {34 {
@@ -42,7 +36,7 @@
42 get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); }36 get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); }
43 }37 }
44 38
45 public static IEnumerable<string> BadPrefixes {39 static IEnumerable<string> PrefixStrings {
46 get {40 get {
47 yield return "gksu";41 yield return "gksu";
48 yield return "sudo";42 yield return "sudo";
@@ -55,35 +49,46 @@
55 }49 }
56 }50 }
57 51
52 public static IEnumerable<Regex> BadPrefixes { get; private set; }
53
58 static Dictionary<string, string> RemapDictionary { get; set; }54 static Dictionary<string, string> RemapDictionary { get; set; }
59 55
60 static List<Application> application_list;56 static List<Window> window_list;
61 static bool application_list_update_needed;57 static bool window_list_update_needed;
62 58
63 static Dictionary<int, string> exec_lines = new Dictionary<int, string> ();59 static Dictionary<int, string> exec_lines = new Dictionary<int, string> ();
64 static DateTime last_update = new DateTime (0);60 static DateTime last_update = new DateTime (0);
65 61
62 #region ctor
66 static WindowUtils ()63 static WindowUtils ()
67 {64 {
65 List<Regex> regex = new List<Regex> ();
66 foreach (string s in PrefixStrings) {
67 regex.Add (new Regex (string.Format ("^{0}$", s), RegexOptions.IgnoreCase));
68 }
69 BadPrefixes = regex.AsEnumerable ();
70
68 Wnck.Screen.Default.WindowClosed += delegate {71 Wnck.Screen.Default.WindowClosed += delegate {
69 application_list_update_needed = true;72 window_list_update_needed = true;
70 };73 };
71 74
72 Wnck.Screen.Default.WindowOpened += delegate {75 Wnck.Screen.Default.WindowOpened += delegate {
73 application_list_update_needed = true;76 window_list_update_needed = true;
74 };77 };
75 78
76 Wnck.Screen.Default.ApplicationOpened += delegate {79 Wnck.Screen.Default.ApplicationOpened += delegate {
77 application_list_update_needed = true;80 window_list_update_needed = true;
78 };81 };
79 82
80 Wnck.Screen.Default.ApplicationClosed += delegate {83 Wnck.Screen.Default.ApplicationClosed += delegate {
81 application_list_update_needed = true;84 window_list_update_needed = true;
82 };85 };
83 86
84 BuildRemapDictionary ();87 BuildRemapDictionary ();
85 }88 }
89 #endregion
86 90
91 #region Private Methods
87 static void BuildRemapDictionary ()92 static void BuildRemapDictionary ()
88 {93 {
89 if (!File.Exists (RemapFile)) {94 if (!File.Exists (RemapFile)) {
@@ -151,117 +156,39 @@
151 return remapDict;156 return remapDict;
152 }157 }
153 158
154 /// <summary>
155 /// Returns a list of all applications on the default screen
156 /// </summary>
157 /// <returns>
158 /// A <see cref="Application"/> array
159 /// </returns>
160 public static List<Application> GetApplications ()
161 {
162 if (application_list == null || application_list_update_needed) {
163 application_list = new List<Application> ();
164 foreach (Window w in Wnck.Screen.Default.Windows) {
165 if (!application_list.Contains (w.Application))
166 application_list.Add (w.Application);
167 }
168 }
169 return application_list;
170 }
171
172 /// <summary>
173 /// Gets the command line excec string for a PID
174 /// </summary>
175 /// <param name="pid">
176 /// A <see cref="System.Int32"/>
177 /// </param>
178 /// <returns>
179 /// A <see cref="System.String"/>
180 /// </returns>
181 public static string CmdLineForPid (int pid)
182 {
183 StreamReader reader;
184 string cmdline = null;
185
186 try {
187 string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine);
188 reader = new StreamReader (procPath);
189 cmdline = reader.ReadLine ().Replace (Convert.ToChar (0x0), ' ');
190 reader.Close ();
191 reader.Dispose ();
192 } catch { }
193
194 return cmdline;
195 }
196
197 /// <summary>
198 /// Returns a list of applications that match an exec string
199 /// </summary>
200 /// <param name="exec">
201 /// A <see cref="System.String"/>
202 /// </param>
203 /// <returns>
204 /// A <see cref="List"/>
205 /// </returns>
206 public static List<Application> GetApplicationList (string exec)
207 {
208 List<Application> apps = new List<Application> ();
209 if (string.IsNullOrEmpty (exec))
210 return apps;
211
212 exec = ProcessExecString (exec);
213 if (string.IsNullOrEmpty (exec))
214 return apps;
215
216 UpdateExecList ();
217
218 foreach (KeyValuePair<int, string> kvp in exec_lines) {
219 if (kvp.Value != null && kvp.Value.Contains (exec)) {
220 foreach (Application app in GetApplications ()) {
221 if (app == null)
222 continue;
223
224 if (app.Pid == kvp.Key || app.Windows.Any (w => w.Pid == kvp.Key)) {
225 if (app.Windows.Any (win => !win.IsSkipTasklist))
226 apps.Add (app);
227 break;
228 }
229 }
230 }
231 }
232 return apps;
233 }
234
235 static void UpdateExecList ()159 static void UpdateExecList ()
236 {160 {
237 if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return;161 if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return;
238 162
239 exec_lines.Clear ();163 Dictionary<int, string> old = exec_lines;
164
165 exec_lines = new Dictionary<int, string> ();
240 166
241 foreach (string dir in Directory.GetDirectories ("/proc")) {167 foreach (string dir in Directory.GetDirectories ("/proc")) {
242 int pid;168 int pid;
243 try { pid = Convert.ToInt32 (Path.GetFileName (dir)); } 169 try { pid = Convert.ToInt32 (Path.GetFileName (dir)); }
244 catch { continue; }170 catch { continue; }
245 171
172 if (old.ContainsKey (pid)) {
173 exec_lines [pid] = old [pid];
174 continue;
175 }
176
246 string exec_line = CmdLineForPid (pid);177 string exec_line = CmdLineForPid (pid);
247 if (string.IsNullOrEmpty (exec_line))178 if (string.IsNullOrEmpty (exec_line))
248 continue;179 continue;
249 180
250 if (exec_line.Contains ("java") && exec_line.Contains ("jar")) {181 if (exec_line.Contains ("java") && exec_line.Contains ("jar")) {
251 foreach (Application app in GetApplications ()) {182 foreach (Window window in GetWindows ()) {
252 if (app == null)183 if (window == null)
253 continue;184 continue;
254 185
255 if (app.Pid == pid || app.Windows.Any (w => w.Pid == pid)) {186 if (window.Pid == pid || window.Application.Pid == pid) {
256 foreach (Wnck.Window window in app.Windows.Where (win => !win.IsSkipTasklist)) {187 exec_line = window.ClassGroup.ResClass;
257 exec_line = window.ClassGroup.ResClass;
258 188
259 // Vuze is retarded189 // Vuze is retarded
260 if (exec_line == "SWT")190 if (exec_line == "SWT")
261 exec_line = window.Name;191 exec_line = window.Name;
262 Console.WriteLine (exec_line);
263 break;
264 }
265 }192 }
266 }193 }
267 } 194 }
@@ -273,16 +200,126 @@
273 200
274 last_update = DateTime.UtcNow;201 last_update = DateTime.UtcNow;
275 }202 }
276203
204 static ClickAction GetClickAction (IEnumerable<Window> windows)
205 {
206 if (!windows.Any ())
207 return ClickAction.None;
208
209 if (windows.Any (w => w.IsMinimized && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)))
210 return ClickAction.Restore;
211
212 if (windows.Any (w => w.IsActive && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)))
213 return ClickAction.Minimize;
214
215 return ClickAction.Focus;
216 }
217 #endregion
218
219 #region Public Methods
220 /// <summary>
221 /// Returns a list of all windows on the default screen
222 /// </summary>
223 /// <returns>
224 /// A <see cref="List"/>
225 /// </returns>
226 public static List<Window> GetWindows ()
227 {
228 if (window_list == null || window_list_update_needed)
229 window_list = new List<Window> (Wnck.Screen.Default.WindowsStacked);
230
231 return window_list;
232 }
233
234 /// <summary>
235 /// Gets the command line excec string for a PID
236 /// </summary>
237 /// <param name="pid">
238 /// A <see cref="System.Int32"/>
239 /// </param>
240 /// <returns>
241 /// A <see cref="System.String"/>
242 /// </returns>
243 public static string CmdLineForPid (int pid)
244 {
245 string cmdline = null;
246
247 try {
248 string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine);
249 using (StreamReader reader = new StreamReader (procPath)) {
250 cmdline = reader.ReadLine ();
251 reader.Close ();
252 }
253 } catch { }
254
255 return cmdline;
256 }
257
258 public static List<Window> WindowListForCmd (string exec)
259 {
260 List<Window> windows = new List<Window> ();
261 if (string.IsNullOrEmpty (exec))
262 return windows;
263
264 exec = ProcessExecString (exec);
265 if (string.IsNullOrEmpty (exec))
266 return windows;
267
268 UpdateExecList ();
269
270 foreach (KeyValuePair<int, string> kvp in exec_lines) {
271 if (!string.IsNullOrEmpty (kvp.Value) && kvp.Value.Contains (exec)) {
272 // we have a matching exec, now we just find every window whose PID matches this exec
273 foreach (Window window in GetWindows ()) {
274 if (window == null)
275 continue;
276
277 // this window matches the right PID and exec string, we can match it.
278 bool pidMatch = window.Pid == kvp.Key ||
279 (window.Application != null && window.Application.Pid == kvp.Key);
280
281 if (pidMatch && !windows.Contains (window))
282 windows.Add (window);
283 }
284 }
285 }
286
287 return windows;
288 }
289
290 /// <summary>
291 /// This method takes in an "execution string" from proc and applies a heureustic to try
292 /// to magic out the name of the actual executing application. The executing binary is not
293 /// the desired target all the time.
294 /// </summary>
295 /// <param name="exec">
296 /// A <see cref="System.String"/>
297 /// </param>
298 /// <returns>
299 /// A <see cref="System.String"/>
300 /// </returns>
277 public static string ProcessExecString (string exec)301 public static string ProcessExecString (string exec)
278 {302 {
303 if (string.IsNullOrEmpty (exec))
304 return exec;
305
306 // lower it and trim off white space so we can abuse whitespace a bit
279 exec = exec.ToLower ().Trim ();307 exec = exec.ToLower ().Trim ();
280 308
309 // if the user has specified a specific mapping, we can use that here
281 if (RemapDictionary.ContainsKey (exec))310 if (RemapDictionary.ContainsKey (exec))
282 return RemapDictionary [exec];311 return RemapDictionary [exec];
283 312
313 // this is the "split" character or the argument separator. If the string contains a null
314 // it was fetched from /proc/PID/cmdline and will be nicely split up. Otherwise things get a bit
315 // nasty, and it likely came from a .desktop file.
316 char splitChar = Convert.ToChar (0x0);
317 splitChar = exec.Contains (splitChar) ? splitChar : ' ';
318
319 // this part is here soley for the remap file so that users may specify to remap based on just the name
320 // without the full path. If no remap file match is found, the net effect of this is nothing.
284 if (exec.StartsWith ("/")) {321 if (exec.StartsWith ("/")) {
285 string first_part = exec.Split (' ') [0];322 string first_part = exec.Split (splitChar) [0];
286 int length = first_part.Length;323 int length = first_part.Length;
287 first_part = first_part.Split ('/').Last ();324 first_part = first_part.Split ('/').Last ();
288 325
@@ -294,25 +331,38 @@
294 }331 }
295 }332 }
296 333
297 string [] parts = exec.Split (' ');334 string [] parts = exec.Split (splitChar);
298 for (int i = 0; i < parts.Length; i++) {335 for (int i = 0; i < parts.Length; i++) {
299 if (parts [i].StartsWith ("-"))336 // we're going to use this a lot
337 string out_val = parts [i];
338
339 // arguments are useless
340 if (out_val.StartsWith ("-"))
300 continue;341 continue;
301 342
302 if (parts [i].Contains ("/"))343 // we want the end of paths
303 parts [i] = parts [i].Split ('/').Last ();344 if (out_val.Contains ("/"))
304 345 out_val = out_val.Split ('/').Last ();
305 Regex regex;346
306 foreach (string prefix in BadPrefixes) {347 // wine apps can do it backwards... who knew?
307 regex = new Regex (string.Format ("^{0}$", prefix), RegexOptions.IgnoreCase);348 if (out_val.Contains ("\\"))
308 if (regex.IsMatch (parts [i])) {349 out_val = out_val.Split ('\\').Last ();
309 parts [i] = null;350
351 // null out our part if is a bad prefix
352 foreach (Regex regex in BadPrefixes) {
353 if (regex.IsMatch (out_val)) {
354 out_val = null;
310 break;355 break;
311 }356 }
312 }357 }
313 358
314 if (!string.IsNullOrEmpty (parts [i])) {359 // check if it was a bad prefix...
315 string out_val = parts [i];360 if (!string.IsNullOrEmpty (out_val)) {
361 // sometimes we hide things with shell scripts. This is the most common method of doing it.
362 if (out_val.EndsWith (".real"))
363 out_val = out_val.Substring (0, out_val.Length - ".real".Length);
364
365 // give the remap dictionary one last shot at this
316 if (RemapDictionary.ContainsKey (out_val))366 if (RemapDictionary.ContainsKey (out_val))
317 out_val = RemapDictionary [out_val];367 out_val = RemapDictionary [out_val];
318 return out_val;368 return out_val;
@@ -327,12 +377,10 @@
327 /// <param name="apps">377 /// <param name="apps">
328 /// A <see cref="IEnumerable"/>378 /// A <see cref="IEnumerable"/>
329 /// </param>379 /// </param>
330 public static void PerformLogicalClick (IEnumerable<Application> apps)380 public static void PerformLogicalClick (IEnumerable<Window> windows)
331 {381 {
332 List<Window> stack = new List<Window> (Wnck.Screen.Default.WindowsStacked);382 List<Window> stack = new List<Window> (Wnck.Screen.Default.WindowsStacked);
333 IEnumerable<Window> windows = apps383 windows = windows.OrderByDescending (w => stack.IndexOf (w));
334 .SelectMany (app => app.Windows)
335 .OrderByDescending (w => stack.IndexOf (w));
336 384
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));
338 bool urgent = windows.Any (w => w.NeedsAttention ());386 bool urgent = windows.Any (w => w.NeedsAttention ());
@@ -348,7 +396,7 @@
348 }396 }
349 }397 }
350 398
351 switch (GetClickAction (apps)) {399 switch (GetClickAction (windows)) {
352 case ClickAction.Focus:400 case ClickAction.Focus:
353 WindowControl.FocusWindows (windows);401 WindowControl.FocusWindows (windows);
354 break;402 break;
@@ -361,26 +409,6 @@
361 }409 }
362 }410 }
363 411
364 static ClickAction GetClickAction (IEnumerable<Application> apps)412 #endregion
365 {
366 if (!apps.Any ())
367 return ClickAction.None;
368
369 foreach (Wnck.Application app in apps) {
370 foreach (Wnck.Window window in app.Windows) {
371 if (window.IsMinimized && window.IsInViewport (Wnck.Screen.Default.ActiveWorkspace))
372 return ClickAction.Restore;
373 }
374 }
375
376 foreach (Wnck.Application app in apps) {
377 foreach (Wnck.Window window in app.Windows) {
378 if (window.IsActive && window.IsInViewport (Wnck.Screen.Default.ActiveWorkspace))
379 return ClickAction.Minimize;
380 }
381 }
382
383 return ClickAction.Focus;
384 }
385 }413 }
386}414}
387415
=== added directory 'Do.Interface.Wink/src/Do.Interface.Xlib'
=== renamed file 'Do.Interface.Linux.Docky/src/XLib/X11Atoms.cs' => 'Do.Interface.Wink/src/Do.Interface.Xlib/X11Atoms.cs'
--- Do.Interface.Linux.Docky/src/XLib/X11Atoms.cs 2009-02-23 04:01:36 +0000
+++ Do.Interface.Wink/src/Do.Interface.Xlib/X11Atoms.cs 2009-03-31 16:23:23 +0000
@@ -23,9 +23,18 @@
2323
24using System;24using System;
2525
26namespace Docky.XLib {26namespace Do.Interface.Xlib {
2727
28 internal class X11Atoms {28 public class X11Atoms {
29
30 static X11Atoms instance;
31 public static X11Atoms Instance {
32 get {
33 if (instance == null)
34 instance = new X11Atoms (Gdk.Screen.Default.Display);
35 return instance;
36 }
37 }
2938
30 // Our atoms39 // Our atoms
31 public readonly IntPtr AnyPropertyType = (IntPtr)0;40 public readonly IntPtr AnyPropertyType = (IntPtr)0;
@@ -169,8 +178,8 @@
169 public readonly IntPtr AsyncAtom;178 public readonly IntPtr AsyncAtom;
170179
171180
172 public X11Atoms (Gdk.Window window) {181 X11Atoms (Gdk.Display dsp) {
173 IntPtr display = XLib.Xlib.GdkDrawableXDisplay (window);182 IntPtr display = Xlib.GdkDisplayXDisplay (dsp);
174 // make sure this array stays in sync with the statements below183 // make sure this array stays in sync with the statements below
175 string [] atom_names = new string[] {184 string [] atom_names = new string[] {
176 "WM_PROTOCOLS",185 "WM_PROTOCOLS",
177186
=== renamed file 'Do.Interface.Linux.Docky/src/XLib/Xlib.cs' => 'Do.Interface.Wink/src/Do.Interface.Xlib/Xlib.cs'
--- Do.Interface.Linux.Docky/src/XLib/Xlib.cs 2009-01-12 20:15:41 +0000
+++ Do.Interface.Wink/src/Do.Interface.Xlib/Xlib.cs 2009-03-31 16:23:23 +0000
@@ -27,7 +27,7 @@
27using System.Collections.Generic;27using System.Collections.Generic;
28using System.Linq;28using System.Linq;
2929
30namespace Docky.XLib {30namespace Do.Interface.Xlib {
3131
32 public enum PropertyMode32 public enum PropertyMode
33 {33 {
@@ -52,7 +52,7 @@
52 BottomEnd = 1152 BottomEnd = 11
53 }53 }
54 54
55 internal class Xlib {55 public static class Xlib {
56 const string libX11 = "X11";56 const string libX11 = "X11";
57 const string libGdkX11 = "libgdk-x11";57 const string libGdkX11 = "libgdk-x11";
58 58
@@ -61,7 +61,24 @@
61 61
62 [DllImport (libGdkX11)]62 [DllImport (libGdkX11)]
63 static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr handle);63 static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr handle);
64
65 [DllImport (libGdkX11)]
66 static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
6467
68 [DllImport (libX11)]
69 public extern static IntPtr XOpenDisplay (IntPtr display);
70
71 [DllImport (libX11)]
72 public extern static int XInternAtoms (IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
73
74 [DllImport (libX11)]
75 extern static int XChangeProperty (IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, int mode, IntPtr[] data, int nelements);
76
77 [DllImport (libX11)]
78 public extern static int XGetWindowProperty (IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset,
79 IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type,
80 out int actual_format, out IntPtr nitems, out IntPtr bytes_after, out IntPtr prop);
81
65 public static IntPtr GdkWindowX11Xid (Gdk.Window window)82 public static IntPtr GdkWindowX11Xid (Gdk.Window window)
66 {83 {
67 return gdk_x11_drawable_get_xid (window.Handle);84 return gdk_x11_drawable_get_xid (window.Handle);
@@ -72,19 +89,16 @@
72 return gdk_x11_drawable_get_xdisplay (window.Handle);89 return gdk_x11_drawable_get_xdisplay (window.Handle);
73 }90 }
74 91
75 [DllImport (libX11)]92 public static IntPtr GdkDisplayXDisplay (Gdk.Display display)
76 public extern static IntPtr XOpenDisplay (IntPtr display);93 {
77 94 return gdk_x11_display_get_xdisplay (display.Handle);
78 [DllImport (libX11)]95 }
79 public extern static int XInternAtoms (IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);96
80
81 [DllImport (libX11)]
82 extern static int XChangeProperty (IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, int mode, IntPtr[] data, int nelements);
83
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)
85 {98 {
86 IntPtr [] dataArray = data.Select (i => (IntPtr) i).ToArray ();99 IntPtr [] dataArray = data.Select (i => (IntPtr) i).ToArray ();
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);
88 }101 }
102
89 }103 }
90}104}
91105
=== modified file 'Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs'
--- Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs 2009-01-21 23:44:40 +0000
+++ Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs 2009-03-24 15:04:23 +0000
@@ -18,6 +18,8 @@
18//18//
1919
20using System;20using System;
21using System.Collections.Generic;
22using System.Linq;
2123
22using Do.Universe;24using Do.Universe;
23using Do.Universe.Linux;25using Do.Universe.Linux;
@@ -28,7 +30,6 @@
28 30
29 public class UniverseFactoryService : IUniverseFactoryService31 public class UniverseFactoryService : IUniverseFactoryService
30 {32 {
31
32 public IFileItem NewFileItem (string path)33 public IFileItem NewFileItem (string path)
33 {34 {
34 return new FileItem (path);35 return new FileItem (path);
@@ -41,5 +42,10 @@
41 IApplicationItem maybe = ApplicationItem.MaybeCreateFromDesktopItem (path);42 IApplicationItem maybe = ApplicationItem.MaybeCreateFromDesktopItem (path);
42 return maybe ?? new NullApplicationItem (path);43 return maybe ?? new NullApplicationItem (path);
43 }44 }
45
46 public IApplicationItem MaybeApplicationItemFromCommand (string cmd)
47 {
48 return ApplicationItem.MaybeCreateFromCmd (cmd);
49 }
44 }50 }
45}51}
4652
=== modified file 'Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs'
--- Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs 2009-01-23 23:01:37 +0000
+++ Do.Platform.Linux/src/Do.Universe/ApplicationItem.cs 2009-03-29 17:52:17 +0000
@@ -22,6 +22,7 @@
22using System.Linq;22using System.Linq;
23using System.Collections.Generic;23using System.Collections.Generic;
24using System.Runtime.InteropServices;24using System.Runtime.InteropServices;
25using System.Text.RegularExpressions;
2526
26using Gnome;27using Gnome;
27using Mono.Unix;28using Mono.Unix;
@@ -68,6 +69,34 @@
68 }69 }
69 return appItem;70 return appItem;
70 }71 }
72
73 public static ApplicationItem MaybeCreateFromCmd (string cmd)
74 {
75 ApplicationItem appItem = null;
76
77 if (string.IsNullOrEmpty (cmd))
78 return appItem;
79
80 cmd = Regex.Escape (cmd);
81 Regex regex = new Regex (string .Format ("(^| ){0}( |)", cmd));
82 foreach (ApplicationItem item in Instances.Values) {
83 string path = item.Location;
84 try {
85 if (path.StartsWith ("file://"))
86 path = path.Substring ("file://".Length);
87
88 path = Path.GetFileName (path);
89 } catch { continue; }
90
91 if (regex.IsMatch (path) || regex.IsMatch (item.Exec)) {
92 appItem = item;
93 if (item.IsAppropriateForCurrentDesktop && !item.Hidden)
94 break;
95 }
96 }
97
98 return appItem;
99 }
71100
72 protected DesktopItem item;101 protected DesktopItem item;
73 string name, description, icon, mimetype;102 string name, description, icon, mimetype;
@@ -115,6 +144,10 @@
115 public string Exec {144 public string Exec {
116 get { return item.GetString ("Exec"); }145 get { return item.GetString ("Exec"); }
117 }146 }
147
148 protected string Location {
149 get { return item.Location; }
150 }
118151
119 public bool Hidden {152 public bool Hidden {
120 get { return item.GetBoolean ("NoDisplay"); }153 get { return item.GetBoolean ("NoDisplay"); }
121154
=== modified file 'Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs'
--- Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs 2008-12-12 01:41:51 +0000
+++ Do.Platform/src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs 2009-03-24 15:04:23 +0000
@@ -41,6 +41,12 @@
41 Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem.");41 Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem.");
42 return new EmptyApplicationItem ();42 return new EmptyApplicationItem ();
43 }43 }
44
45 public IApplicationItem MaybeApplicationItemFromCommand (string cmd)
46 {
47 Log.Debug ("Default IUniverseFactoryService cannot return a useful IApplicationItem.");
48 return null;
49 }
4450
45 class EmptyFileItem : EmptyItem, IFileItem51 class EmptyFileItem : EmptyItem, IFileItem
46 {52 {
4753
=== modified file 'Do.Platform/src/Do.Platform/IUniverseFactoryService.cs'
--- Do.Platform/src/Do.Platform/IUniverseFactoryService.cs 2008-12-22 00:36:53 +0000
+++ Do.Platform/src/Do.Platform/IUniverseFactoryService.cs 2009-03-24 15:04:23 +0000
@@ -31,5 +31,6 @@
31 {31 {
32 IFileItem NewFileItem (string path);32 IFileItem NewFileItem (string path);
33 IApplicationItem NewApplicationItem (string path); 33 IApplicationItem NewApplicationItem (string path);
34 IApplicationItem MaybeApplicationItemFromCommand (string cmd);
34 }35 }
35}36}
3637
=== modified file 'Do.mds'
--- Do.mds 2009-03-28 15:34:37 +0000
+++ Do.mds 2009-03-31 17:48:02 +0000
@@ -64,4 +64,4 @@
64 <Entry filename="Do.Interface.Linux.HUD/Do.Interface.Linux.HUD.mdp" />64 <Entry filename="Do.Interface.Linux.HUD/Do.Interface.Linux.HUD.mdp" />
65 <Entry filename="Do.Interface.Wink/Do.Interface.Wink.mdp" />65 <Entry filename="Do.Interface.Wink/Do.Interface.Wink.mdp" />
66 </Entries>66 </Entries>
67</Combine>67</Combine>
68\ No newline at end of file68\ No newline at end of file
6969
=== modified file 'Do/gnome-do.in'
--- Do/gnome-do.in 2008-10-27 07:23:04 +0000
+++ Do/gnome-do.in 2009-03-24 15:04:23 +0000
@@ -18,8 +18,8 @@
1818
19# If Do is not running, run it.19# If Do is not running, run it.
20if pgrep -u "`id -un`" '^gnome-do$' >/dev/null; then20if pgrep -u "`id -un`" '^gnome-do$' >/dev/null; then
21 mono "$GNOME_DO_EXE" "$@"21 mono --debug "$GNOME_DO_EXE" "$@" > ~/do.trace 2>&1
22fi22fi
23while [ "$?" -eq "20" ]; do23while [ "$?" -eq "20" ]; do
24 mono "$GNOME_DO_EXE" "$@"24 mono --debug "$GNOME_DO_EXE" "$@" > ~/do.trace 2>&1
25done25done