Merge lp://qastaging/~docky-core/docky/dbus-menus into lp://qastaging/docky

Proposed by Jason Smith
Status: Merged
Merged at revision: not available
Proposed branch: lp://qastaging/~docky-core/docky/dbus-menus
Merge into: lp://qastaging/docky
Diff against target: 1738 lines (+1230/-26)
28 files modified
Docky-2.sln (+6/-0)
Docky.DBus/Docky.DBus.csproj (+77/-0)
Docky.DBus/Docky.DBus/DBusManager.cs (+121/-0)
Docky.DBus/Docky.DBus/DockyDBus.cs (+117/-0)
Docky.DBus/Docky.DBus/DockyDBusItem.cs (+276/-0)
Docky.DBus/Docky.DBus/IDockyDBus.cs (+50/-0)
Docky.DBus/Docky.DBus/IDockyDBusItem.cs (+64/-0)
Docky.DBus/Docky.DBus/RemoteMenuEntry.cs (+41/-0)
Docky.DBus/Makefile.am (+27/-0)
Docky.Items/Docky.Items/AbstractDockItem.cs (+25/-8)
Docky.Items/Docky.Items/ApplicationDockItem.cs (+1/-1)
Docky.Items/Docky.Items/IconDockItem.cs (+10/-1)
Docky.Items/Docky.Menus/MenuList.cs (+32/-0)
Docky.Windowing/Windowing/DesktopItem.cs (+6/-0)
Docky/Docky.csproj (+4/-0)
Docky/Docky/CairoHelper/DockySurface_Extensions.cs (+71/-5)
Docky/Docky/Docky.cs (+26/-1)
Docky/Docky/Interface/DockPreferences.cs (+25/-1)
Docky/Docky/Interface/DockWindow.cs (+18/-3)
Docky/Docky/Interface/IDockPreferences.cs (+2/-0)
Docky/Docky/Items/DockyItem.cs (+1/-1)
Docky/Makefile.am (+1/-0)
Docky/gtk-gui/gui.stetic (+6/-5)
Makefile.am (+2/-0)
configure.ac (+2/-0)
examples/docky_remote.py (+43/-0)
scripts/Makefile.am (+2/-0)
scripts/zeitgeist_docky.py (+174/-0)
To merge this branch: bzr merge lp://qastaging/~docky-core/docky/dbus-menus
Reviewer Review Type Date Requested Status
Robert Dyer (community) Needs Fixing
Review via email: mp+16110@code.qastaging.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Dyer (psybers) wrote :
Download full text (3.3 KiB)

All lines numbers refer to the diff.

-----------------------------------------------------------

153 + static DBusManager manager;
154 + public static DBusManager Default {
155 + get {
156 + if (manager == null)
157 + manager = new DBusManager ();
158 + return manager;
159 + }
160 + }

The proper way to do this would be:

public static DBusManager Default { get; protected set; }

static DBusManager ()
{
 Default = new DBusManager ();
}

-----------------------------------------------------------

163 + Dictionary<AbstractDockItem, DockyDBusItem> items;
165 + internal IEnumerable<AbstractDockItem> Items {

I think one needs renamed. This is confusing, because lowercase items is a dictionary while uppercase Icons is an enum. Perhaps use items_dict or item_buses or something for the first?

-----------------------------------------------------------

387 + public struct Tuple

Rename. What is this? ItemTuple?

-----------------------------------------------------------

429 + uint GetRandomID ()
430 + {
431 + Random rand = new Random ();
432 +
433 + uint number;
434 +
435 + do {
436 + // should we ever get 100,000 items in here, I hope we crash, though we will likely get an infinite loop
437 + number = (uint) rand.Next (0, 100000);
438 + } while (known_ids.BinarySearch (number) >= 0);
439 +
440 + known_ids.Add (number);
441 + known_ids.Sort ();
442 +
443 + return number;
444 + }

Correct me if I am wrong, but the purpose of this is to get a unique id that isnt currently in use (aka, not in known_ids)? If that is the case, using rand is not needed. Do a sort on known_ids, grab the last one, add one. This is as good as random and doesnt require such a hack.

-----------------------------------------------------------

886 - icon_buffers = new DockySurface [2];
887 - badgeColors = new Cairo.Color [2];
888 - redraw = new bool [2];
889 + icon_buffers = new DockySurface[2];
890 + badgeColors = new Cairo.Color[2];
891 + redraw = new bool[2];

Undo that. Mono coding guidelines say space before the '['.

-----------------------------------------------------------

929 +// var remote = DBusManager.Default.RemoteEntries
930 +// .Where (e => e.Target == OwnedItem.DesktopID)
931 +// .GroupBy (e => e.Title);
932 +//
933 +// MenuListContainer container = MenuListContainer.Footer + 1;
934 +// foreach (var entries in remote) {
935 +// list.SetContainerTitle (container, entries.Key);
936 +// foreach (RemoteMenuEntry entry in entries) {
937 +// list[container].Add (new MenuItem (entry.Name, entry.Icon, (o, a) => entry.OnActivated ()));
938 +// }
939 +// container++;
940 +// }
941 +

Just remove this. No need to comment out. :-)

-----------------------------------------------------------

1004 + MenuListContainer container = kvp.Key;
1005 + result[container].AddRange (kvp.Value);

Simplify:

result[kvp.Key].AddRange (kvp.Value);

Same thing here too:

1010 + MenuListContainer container = kvp.Key;
1011 + result[container].AddRange (kvp.Value);

-----------------------------------------------------------

1243 +
1244 + public static void Quit ()
1245 + {
1246 + DBusManager.Default.Shutdown ();
1247 + Gtk.Application.Quit ();
1248 + }

Cant this just be g...

Read more...

review: Needs Fixing
820. By Jason Smith

Fix issues raised in review

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Docky-2.sln'
2--- Docky-2.sln 2009-12-03 20:49:01 +0000
3+++ Docky-2.sln 2009-12-14 04:44:13 +0000
4@@ -39,6 +39,8 @@
5 EndProject
6 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Docky.Widgets", "Docky.Widgets\Docky.Widgets.csproj", "{9CF2F475-7848-4333-9A35-93E8224653B3}"
7 EndProject
8+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Docky.DBus", "Docky.DBus\Docky.DBus.csproj", "{487D3B93-FAAF-4734-B337-85810A60ACCF}"
9+EndProject
10 Global
11 GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 Debug|Any CPU = Debug|Any CPU
13@@ -49,6 +51,10 @@
14 {2F5FDD02-4BDA-4E80-8B92-A8BD55FFBC81}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 {2F5FDD02-4BDA-4E80-8B92-A8BD55FFBC81}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 {2F5FDD02-4BDA-4E80-8B92-A8BD55FFBC81}.Release|Any CPU.Build.0 = Release|Any CPU
17+ {487D3B93-FAAF-4734-B337-85810A60ACCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
18+ {487D3B93-FAAF-4734-B337-85810A60ACCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
19+ {487D3B93-FAAF-4734-B337-85810A60ACCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
20+ {487D3B93-FAAF-4734-B337-85810A60ACCF}.Release|Any CPU.Build.0 = Release|Any CPU
21 {48D9779F-BBEE-4DB4-95DA-844C12C51B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 {48D9779F-BBEE-4DB4-95DA-844C12C51B32}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 {48D9779F-BBEE-4DB4-95DA-844C12C51B32}.Release|Any CPU.ActiveCfg = Release|Any CPU
24
25=== added directory 'Docky.DBus'
26=== added directory 'Docky.DBus/Docky.DBus'
27=== added file 'Docky.DBus/Docky.DBus.csproj'
28--- Docky.DBus/Docky.DBus.csproj 1970-01-01 00:00:00 +0000
29+++ Docky.DBus/Docky.DBus.csproj 2009-12-14 04:44:13 +0000
30@@ -0,0 +1,77 @@
31+<?xml version="1.0" encoding="utf-8"?>
32+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
33+ <PropertyGroup>
34+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
35+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
36+ <ProductVersion>9.0.21022</ProductVersion>
37+ <SchemaVersion>2.0</SchemaVersion>
38+ <ProjectGuid>{487D3B93-FAAF-4734-B337-85810A60ACCF}</ProjectGuid>
39+ <OutputType>Library</OutputType>
40+ <RootNamespace>Docky.DBus</RootNamespace>
41+ <AssemblyName>Docky.DBus</AssemblyName>
42+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
43+ <ReleaseVersion>2.0</ReleaseVersion>
44+ </PropertyGroup>
45+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
46+ <DebugSymbols>true</DebugSymbols>
47+ <DebugType>full</DebugType>
48+ <Optimize>false</Optimize>
49+ <OutputPath>bin\Debug</OutputPath>
50+ <DefineConstants>DEBUG</DefineConstants>
51+ <ErrorReport>prompt</ErrorReport>
52+ <WarningLevel>4</WarningLevel>
53+ <ConsolePause>false</ConsolePause>
54+ </PropertyGroup>
55+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
56+ <DebugType>none</DebugType>
57+ <Optimize>false</Optimize>
58+ <OutputPath>bin\Release</OutputPath>
59+ <ErrorReport>prompt</ErrorReport>
60+ <WarningLevel>4</WarningLevel>
61+ <ConsolePause>false</ConsolePause>
62+ </PropertyGroup>
63+ <ItemGroup>
64+ <Reference Include="System" />
65+ <Reference Include="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
66+ <Reference Include="System.Core">
67+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
68+ </Reference>
69+ <Reference Include="NDesk.DBus, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f6716e4f9b2ed099">
70+ <Package>ndesk-dbus-1.0</Package>
71+ </Reference>
72+ <Reference Include="NDesk.DBus.GLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f6716e4f9b2ed099">
73+ <Package>ndesk-dbus-glib-1.0</Package>
74+ </Reference>
75+ <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
76+ <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
77+ <Reference Include="wnck-sharp, Version=2.20.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
78+ <Package>wnck-sharp-2.20</Package>
79+ </Reference>
80+ </ItemGroup>
81+ <ItemGroup>
82+ <Folder Include="Docky.DBus\" />
83+ </ItemGroup>
84+ <ItemGroup>
85+ <Compile Include="Docky.DBus\DBusManager.cs" />
86+ <Compile Include="Docky.DBus\IDockyDBus.cs" />
87+ <Compile Include="Docky.DBus\IDockyDBusItem.cs" />
88+ <Compile Include="Docky.DBus\DockyDBusItem.cs" />
89+ <Compile Include="Docky.DBus\DockyDBus.cs" />
90+ <Compile Include="Docky.DBus\RemoteMenuEntry.cs" />
91+ </ItemGroup>
92+ <ItemGroup>
93+ <ProjectReference Include="..\Docky.Services\Docky.Services.csproj">
94+ <Project>{8A6E0EDD-6443-4F99-9EAC-D9CC906F080D}</Project>
95+ <Name>Docky.Services</Name>
96+ </ProjectReference>
97+ <ProjectReference Include="..\Docky.Items\Docky.Items.csproj">
98+ <Project>{AB6E0EDD-6443-4F99-9EAC-DABC906F080D}</Project>
99+ <Name>Docky.Items</Name>
100+ </ProjectReference>
101+ <ProjectReference Include="..\Docky.Windowing\Docky.Windowing.csproj">
102+ <Project>{888FCD95-7C79-45C4-A744-9C840DF4B9B0}</Project>
103+ <Name>Docky.Windowing</Name>
104+ </ProjectReference>
105+ </ItemGroup>
106+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
107+</Project>
108\ No newline at end of file
109
110=== added file 'Docky.DBus/Docky.DBus/DBusManager.cs'
111--- Docky.DBus/Docky.DBus/DBusManager.cs 1970-01-01 00:00:00 +0000
112+++ Docky.DBus/Docky.DBus/DBusManager.cs 2009-12-14 04:44:13 +0000
113@@ -0,0 +1,121 @@
114+//
115+// Copyright (C) 2009 Jason Smith
116+//
117+// This program is free software: you can redistribute it and/or modify
118+// it under the terms of the GNU General Public License as published by
119+// the Free Software Foundation, either version 3 of the License, or
120+// (at your option) any later version.
121+//
122+// This program is distributed in the hope that it will be useful,
123+// but WITHOUT ANY WARRANTY; without even the implied warranty of
124+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
125+// GNU General Public License for more details.
126+//
127+// You should have received a copy of the GNU General Public License
128+// along with this program. If not, see <http://www.gnu.org/licenses/>.
129+//
130+
131+using System;
132+using System.Collections.Generic;
133+using System.Collections.ObjectModel;
134+using System.Linq;
135+using System.Text;
136+using System.Text.RegularExpressions;
137+
138+using org.freedesktop.DBus;
139+using NDesk.DBus;
140+
141+using Docky.Items;
142+using Docky.Services;
143+
144+namespace Docky.DBus
145+{
146+
147+ public class DBusManager
148+ {
149+ const string BusName = "org.gnome.Docky";
150+ const string DockyPath = "/org/gnome/Docky";
151+ const string ItemsPath = "/org/gnome/Docky/Items";
152+
153+ static DBusManager manager;
154+ public static DBusManager Default {
155+ get {
156+ return manager;
157+ }
158+ }
159+
160+ static DBusManager ()
161+ {
162+ manager = new DBusManager ();
163+ }
164+
165+ DockyDBus docky;
166+ Dictionary<AbstractDockItem, DockyDBusItem> item_dict;
167+
168+ internal IEnumerable<AbstractDockItem> Items {
169+ get {
170+ return item_dict.Keys;
171+ }
172+ }
173+
174+ private DBusManager ()
175+ {
176+ }
177+
178+ public void Initialize ()
179+ {
180+ Bus bus = Bus.Session;
181+
182+ if (bus.RequestName (BusName) != RequestNameReply.PrimaryOwner) {
183+ Log<DBusManager>.Error ("Bus Name is already owned");
184+ return;
185+ }
186+
187+ item_dict = new Dictionary<AbstractDockItem, DockyDBusItem> ();
188+
189+ ObjectPath dockyPath = new ObjectPath (DockyPath);
190+ docky = new DockyDBus ();
191+
192+ bus.Register (dockyPath, docky);
193+ }
194+
195+ public void Shutdown ()
196+ {
197+ docky.Shutdown ();
198+ }
199+
200+ public void RegisterItem (AbstractDockItem item)
201+ {
202+ if (item_dict.ContainsKey (item))
203+ return;
204+
205+ string path = PathForItem (item);
206+ DockyDBusItem dbusitem = new DockyDBusItem (item);
207+
208+ item_dict[item] = dbusitem;
209+ Bus.Session.Register (new ObjectPath (path), dbusitem);
210+
211+ docky.OnItemAdded (path);
212+ }
213+
214+ public void UnregisterItem (AbstractDockItem item)
215+ {
216+ if (!item_dict.ContainsKey (item))
217+ return;
218+
219+ item_dict[item].Dispose ();
220+ item_dict.Remove (item);
221+
222+ ObjectPath path = new ObjectPath (PathForItem (item));
223+ Bus.Session.Unregister (path);
224+
225+ docky.OnItemRemoved (PathForItem (item));
226+ }
227+
228+ internal string PathForItem (AbstractDockItem item)
229+ {
230+
231+ return ItemsPath + "/" + Math.Abs (item.UniqueID ().GetHashCode ());
232+ }
233+ }
234+}
235
236=== added file 'Docky.DBus/Docky.DBus/DockyDBus.cs'
237--- Docky.DBus/Docky.DBus/DockyDBus.cs 1970-01-01 00:00:00 +0000
238+++ Docky.DBus/Docky.DBus/DockyDBus.cs 2009-12-14 04:44:13 +0000
239@@ -0,0 +1,117 @@
240+//
241+// Copyright (C) 2009 Jason Smith
242+//
243+// This program is free software: you can redistribute it and/or modify
244+// it under the terms of the GNU General Public License as published by
245+// the Free Software Foundation, either version 3 of the License, or
246+// (at your option) any later version.
247+//
248+// This program is distributed in the hope that it will be useful,
249+// but WITHOUT ANY WARRANTY; without even the implied warranty of
250+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
251+// GNU General Public License for more details.
252+//
253+// You should have received a copy of the GNU General Public License
254+// along with this program. If not, see <http://www.gnu.org/licenses/>.
255+//
256+
257+using System;
258+using System.Collections.Generic;
259+using System.Collections.ObjectModel;
260+using System.Linq;
261+using System.Text;
262+
263+using Docky.Items;
264+
265+namespace Docky.DBus
266+{
267+
268+
269+ public class DockyDBus : IDockyDBus
270+ {
271+ #region IDockyDBus implementation
272+ public event ItemChangedHandler ItemAdded;
273+
274+ public event ItemChangedHandler ItemRemoved;
275+
276+ public event Action ShuttingDown;
277+
278+ public string[] DockItemPaths ()
279+ {
280+ return DBusManager.Default.Items
281+ .Select (adi => DBusManager.Default.PathForItem (adi))
282+ .ToArray ();
283+ }
284+
285+ public string DockItemPathForDesktopID (string id)
286+ {
287+ return DBusManager.Default.Items
288+ .OfType<ApplicationDockItem> ()
289+ .Where (adi => adi.OwnedItem.DesktopID == id)
290+ .Select (adi => DBusManager.Default.PathForItem (adi))
291+ .DefaultIfEmpty ("")
292+ .FirstOrDefault ();
293+ }
294+
295+ public string DockItemPathForDesktopFile (string path)
296+ {
297+ return DBusManager.Default.Items
298+ .OfType<ApplicationDockItem> ()
299+ .Where (adi => adi.OwnedItem.Location == path)
300+ .Select (adi => DBusManager.Default.PathForItem (adi))
301+ .DefaultIfEmpty ("")
302+ .FirstOrDefault ();
303+ }
304+
305+ public string DockItemPathForWindowXID (uint xid)
306+ {
307+ return DBusManager.Default.Items
308+ .OfType<WnckDockItem> ()
309+ .Where (wdi => wdi.Windows.Any (w => (uint) w.Xid == xid))
310+ .Select (wdi => DBusManager.Default.PathForItem (wdi))
311+ .DefaultIfEmpty ("")
312+ .FirstOrDefault ();
313+ }
314+
315+
316+ public void ShowAbout ()
317+ {
318+ }
319+
320+
321+ public void ShowSettings ()
322+ {
323+ }
324+
325+
326+ public void Quit ()
327+ {
328+ // fixme
329+ System.Environment.Exit (0);
330+ }
331+
332+ #endregion
333+
334+ public DockyDBus ()
335+ {
336+ }
337+
338+ public void Shutdown ()
339+ {
340+ if (ShuttingDown != null)
341+ ShuttingDown ();
342+ }
343+
344+ public void OnItemAdded (string path)
345+ {
346+ if (ItemAdded != null)
347+ ItemAdded (path);
348+ }
349+
350+ public void OnItemRemoved (string path)
351+ {
352+ if (ItemRemoved != null)
353+ ItemRemoved (path);
354+ }
355+ }
356+}
357
358=== added file 'Docky.DBus/Docky.DBus/DockyDBusItem.cs'
359--- Docky.DBus/Docky.DBus/DockyDBusItem.cs 1970-01-01 00:00:00 +0000
360+++ Docky.DBus/Docky.DBus/DockyDBusItem.cs 2009-12-14 04:44:13 +0000
361@@ -0,0 +1,276 @@
362+//
363+// Copyright (C) 2009 Jason Smith
364+//
365+// This program is free software: you can redistribute it and/or modify
366+// it under the terms of the GNU General Public License as published by
367+// the Free Software Foundation, either version 3 of the License, or
368+// (at your option) any later version.
369+//
370+// This program is distributed in the hope that it will be useful,
371+// but WITHOUT ANY WARRANTY; without even the implied warranty of
372+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
373+// GNU General Public License for more details.
374+//
375+// You should have received a copy of the GNU General Public License
376+// along with this program. If not, see <http://www.gnu.org/licenses/>.
377+//
378+
379+using System;
380+using System.Collections.Generic;
381+using System.Collections.ObjectModel;
382+using System.Linq;
383+using System.Text;
384+
385+using Docky.Items;
386+using Docky.Menus;
387+
388+namespace Docky.DBus
389+{
390+ public struct ItemTuple
391+ {
392+ public string Name;
393+ public string Icon;
394+ public string Title;
395+
396+ public ItemTuple (string name, string icon, string title)
397+ {
398+ Name = name;
399+ Icon = icon;
400+ Title = title;
401+ }
402+ }
403+
404+ public class DockyDBusItem : IDockyDBusItem, IDisposable
405+ {
406+
407+ uint timer;
408+ Dictionary<uint, RemoteMenuEntry> items;
409+ Dictionary<uint, DateTime> update_time;
410+
411+ List<uint> known_ids;
412+
413+ AbstractDockItem owner;
414+
415+ public DockyDBusItem (AbstractDockItem item)
416+ {
417+ owner = item;
418+ known_ids = new List<uint> ();
419+ items = new Dictionary<uint, RemoteMenuEntry> ();
420+ update_time = new Dictionary<uint, DateTime> ();
421+
422+ timer = GLib.Timeout.Add (4 * 60 * 1000, delegate {
423+ foreach (uint i in update_time
424+ .Where (kvp => (DateTime.UtcNow - kvp.Value).TotalMinutes > 5)
425+ .Select (kvp => kvp.Key))
426+
427+ RemoveItem (i);
428+ return true;
429+ });
430+ }
431+
432+ uint GetRandomID ()
433+ {
434+ Random rand = new Random ();
435+
436+ uint number;
437+
438+ do {
439+ // should we ever get 100,000 items in here, I hope we crash, though we will likely get an infinite loop
440+ number = (uint) rand.Next (0, 100000);
441+ } while (known_ids.BinarySearch (number) >= 0);
442+
443+ known_ids.Add (number);
444+ known_ids.Sort ();
445+
446+ return number;
447+ }
448+
449+ #region IDockyDBusMenus implementation
450+ public event MenuItemActivatedHandler MenuItemActivated;
451+
452+ public string Name {
453+ get {
454+ return owner.ShortName;
455+ }
456+ }
457+
458+ public string Text {
459+ get {
460+ return owner.HoverText;
461+ }
462+ set {
463+ owner.SetRemoteText (value);
464+ }
465+
466+ }
467+
468+ public string Icon {
469+ get {
470+ if (CanSetIcon)
471+ return (owner as IconDockItem).Icon;
472+ return "custom";
473+ }
474+ set {
475+ if (!CanSetIcon)
476+ return;
477+
478+ (owner as IconDockItem).SetRemoteIcon (value);
479+ }
480+ }
481+
482+ public bool CanSetIcon {
483+ get {
484+ return owner is IconDockItem;
485+ }
486+ }
487+
488+ public bool OwnsDesktopFile {
489+ get {
490+ return owner is ApplicationDockItem;
491+ }
492+ }
493+
494+ public bool OwnsUri {
495+ get {
496+ return owner is FileDockItem;
497+ }
498+ }
499+
500+ public bool Attention {
501+ get { return (owner.State & ItemState.Urgent) == ItemState.Urgent; }
502+ }
503+
504+ public bool Wait {
505+ get { return (owner.State & ItemState.Wait) == ItemState.Wait; }
506+ }
507+
508+ public string DesktopFile {
509+ get {
510+ if (owner is ApplicationDockItem)
511+ return (owner as ApplicationDockItem).OwnedItem.Location;
512+ return "";
513+ }
514+ }
515+
516+ public string Uri {
517+ get {
518+ if (owner is FileDockItem)
519+ return (owner as FileDockItem).Uri;
520+ return "";
521+ }
522+ }
523+
524+ public uint[] Items {
525+ get {
526+ return items.Keys.ToArray ();
527+ }
528+ }
529+
530+ public uint AddMenuItem (string name, string icon, string title)
531+ {
532+ uint number = GetRandomID ();
533+
534+ RemoteMenuEntry rem = new RemoteMenuEntry (number, name, icon, title);
535+ rem.Clicked += HandleActivated;
536+
537+ items[number] = rem;
538+ update_time[number] = DateTime.UtcNow;
539+
540+ //Insert items into list... this is stupid but whatever fix later
541+ foreach (MenuItem item in items.Values)
542+ owner.RemoteMenuItems.Remove (item);
543+
544+ MenuListContainer container = MenuListContainer.Footer + 1;
545+ var groupedItems = items.Values
546+ .GroupBy (rmi => rmi.Title);
547+
548+ foreach (var itemGroup in groupedItems) {
549+ owner.RemoteMenuItems.SetContainerTitle (container, itemGroup.Key);
550+ foreach (MenuItem item in itemGroup) {
551+ owner.RemoteMenuItems[container].Add (item);
552+ }
553+ container++;
554+ }
555+
556+ return number;
557+ }
558+
559+ public void RemoveItem (uint item)
560+ {
561+
562+ if (items.ContainsKey (item)) {
563+ RemoteMenuEntry entry = items[item];
564+ items.Remove (item);
565+
566+ owner.RemoteMenuItems.Remove (entry);
567+ }
568+
569+ known_ids.Remove (item);
570+ }
571+
572+ public void ConfirmItem (uint item)
573+ {
574+ update_time[item] = DateTime.UtcNow;
575+ }
576+
577+ public void SetAttention ()
578+ {
579+ owner.State |= ItemState.Urgent;
580+ }
581+
582+ public void UnsetAttention ()
583+ {
584+ owner.State &= ~ItemState.Urgent;
585+ }
586+
587+ public void SetWaiting ()
588+ {
589+ owner.State |= ItemState.Wait;
590+ }
591+
592+ public void UnsetWaiting ()
593+ {
594+ owner.State &= ~ItemState.Wait;
595+ }
596+
597+ public void ResetText ()
598+ {
599+ owner.SetRemoteText ("");
600+ }
601+
602+ public void ResetIcon ()
603+ {
604+ if (!CanSetIcon)
605+ return;
606+
607+ (owner as IconDockItem).SetRemoteIcon ("");
608+ }
609+
610+ public ItemTuple GetItem (uint item)
611+ {
612+ if (!items.ContainsKey (item))
613+ return new ItemTuple ("", "", "");
614+
615+ RemoteMenuEntry entry = items[item];
616+ return new ItemTuple (entry.Text, entry.Icon, entry.Title);
617+ }
618+
619+ #endregion
620+
621+ void HandleActivated (object sender, EventArgs args)
622+ {
623+ if (!(sender is RemoteMenuEntry))
624+ return;
625+
626+ if (MenuItemActivated != null)
627+ MenuItemActivated ((sender as RemoteMenuEntry).ID);
628+ }
629+ #region IDisposable implementation
630+ public void Dispose ()
631+ {
632+ GLib.Source.Remove (timer);
633+ }
634+
635+ #endregion
636+ }
637+}
638
639=== added file 'Docky.DBus/Docky.DBus/IDockyDBus.cs'
640--- Docky.DBus/Docky.DBus/IDockyDBus.cs 1970-01-01 00:00:00 +0000
641+++ Docky.DBus/Docky.DBus/IDockyDBus.cs 2009-12-14 04:44:13 +0000
642@@ -0,0 +1,50 @@
643+//
644+// Copyright (C) 2009 Jason Smith
645+//
646+// This program is free software: you can redistribute it and/or modify
647+// it under the terms of the GNU General Public License as published by
648+// the Free Software Foundation, either version 3 of the License, or
649+// (at your option) any later version.
650+//
651+// This program is distributed in the hope that it will be useful,
652+// but WITHOUT ANY WARRANTY; without even the implied warranty of
653+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
654+// GNU General Public License for more details.
655+//
656+// You should have received a copy of the GNU General Public License
657+// along with this program. If not, see <http://www.gnu.org/licenses/>.
658+//
659+
660+using System;
661+
662+using org.freedesktop.DBus;
663+using NDesk.DBus;
664+
665+namespace Docky.DBus
666+{
667+ public delegate void ItemChangedHandler (string path);
668+
669+ [Interface("org.gnome.Docky")]
670+ public interface IDockyDBus
671+ {
672+ event Action ShuttingDown;
673+
674+ event ItemChangedHandler ItemAdded;
675+
676+ event ItemChangedHandler ItemRemoved;
677+
678+ string[] DockItemPaths ();
679+
680+ string DockItemPathForDesktopID (string id);
681+
682+ string DockItemPathForDesktopFile (string path);
683+
684+ string DockItemPathForWindowXID (uint xid);
685+
686+ void ShowAbout ();
687+
688+ void ShowSettings ();
689+
690+ void Quit ();
691+ }
692+}
693
694=== added file 'Docky.DBus/Docky.DBus/IDockyDBusItem.cs'
695--- Docky.DBus/Docky.DBus/IDockyDBusItem.cs 1970-01-01 00:00:00 +0000
696+++ Docky.DBus/Docky.DBus/IDockyDBusItem.cs 2009-12-14 04:44:13 +0000
697@@ -0,0 +1,64 @@
698+//
699+// Copyright (C) 2009 Jason Smith
700+//
701+// This program is free software: you can redistribute it and/or modify
702+// it under the terms of the GNU General Public License as published by
703+// the Free Software Foundation, either version 3 of the License, or
704+// (at your option) any later version.
705+//
706+// This program is distributed in the hope that it will be useful,
707+// but WITHOUT ANY WARRANTY; without even the implied warranty of
708+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
709+// GNU General Public License for more details.
710+//
711+// You should have received a copy of the GNU General Public License
712+// along with this program. If not, see <http://www.gnu.org/licenses/>.
713+//
714+
715+using System;
716+
717+using org.freedesktop.DBus;
718+using NDesk.DBus;
719+
720+namespace Docky.DBus
721+{
722+ public delegate void MenuItemActivatedHandler (uint menuHandle);
723+
724+ public delegate void DockItemActivatedHandler (uint menuHandle, uint button);
725+
726+ [Interface ("org.gnome.Docky.Item")]
727+ public interface IDockyDBusItem
728+ {
729+ bool OwnsDesktopFile { get; }
730+ bool OwnsUri { get; }
731+ bool CanSetIcon { get; }
732+ bool Attention { get; }
733+ bool Wait { get; }
734+
735+ string Text { get; set; }
736+ string Icon { get; set; }
737+
738+ string Name { get; }
739+ string DesktopFile { get; }
740+ string Uri { get; }
741+
742+ uint[] Items { get; }
743+
744+ event MenuItemActivatedHandler MenuItemActivated;
745+
746+ uint AddMenuItem (string name, string icon, string title);
747+ void RemoveItem (uint item);
748+ void ConfirmItem (uint item);
749+
750+ void SetAttention ();
751+ void UnsetAttention ();
752+
753+ void SetWaiting ();
754+ void UnsetWaiting ();
755+
756+ void ResetText ();
757+ void ResetIcon ();
758+
759+ Tuple GetItem (uint item);
760+ }
761+}
762
763=== added file 'Docky.DBus/Docky.DBus/RemoteMenuEntry.cs'
764--- Docky.DBus/Docky.DBus/RemoteMenuEntry.cs 1970-01-01 00:00:00 +0000
765+++ Docky.DBus/Docky.DBus/RemoteMenuEntry.cs 2009-12-14 04:44:13 +0000
766@@ -0,0 +1,41 @@
767+//
768+// Copyright (C) 2009 Jason Smith
769+//
770+// This program is free software: you can redistribute it and/or modify
771+// it under the terms of the GNU General Public License as published by
772+// the Free Software Foundation, either version 3 of the License, or
773+// (at your option) any later version.
774+//
775+// This program is distributed in the hope that it will be useful,
776+// but WITHOUT ANY WARRANTY; without even the implied warranty of
777+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
778+// GNU General Public License for more details.
779+//
780+// You should have received a copy of the GNU General Public License
781+// along with this program. If not, see <http://www.gnu.org/licenses/>.
782+//
783+
784+using System;
785+using System.Collections.Generic;
786+using System.Collections.ObjectModel;
787+using System.Linq;
788+using System.Text;
789+
790+using Docky.Menus;
791+
792+namespace Docky.DBus
793+{
794+
795+
796+ public class RemoteMenuEntry : MenuItem
797+ {
798+ public uint ID { get; private set; }
799+ public string Title { get; private set; }
800+
801+ public RemoteMenuEntry (uint id, string name, string icon, string title) : base(name, icon)
802+ {
803+ ID = id;
804+ Title = title;
805+ }
806+ }
807+}
808
809=== added file 'Docky.DBus/Makefile.am'
810--- Docky.DBus/Makefile.am 1970-01-01 00:00:00 +0000
811+++ Docky.DBus/Makefile.am 2009-12-14 04:44:13 +0000
812@@ -0,0 +1,27 @@
813+# Simple component buildsystem
814+include $(top_srcdir)/build.rules.core.mk
815+
816+ASSEMBLY = Docky.DBus
817+TARGET = library
818+
819+FILES = \
820+ Docky.DBus/DBusManager.cs \
821+ Docky.DBus/DockyDBus.cs \
822+ Docky.DBus/DockyDBusItem.cs \
823+ Docky.DBus/IDockyDBus.cs \
824+ Docky.DBus/IDockyDBusItem.cs \
825+ Docky.DBus/RemoteMenuEntry.cs
826+
827+PROJECT_REFERENCES = \
828+ Docky.Items \
829+ Docky.Windowing \
830+ Docky.Services
831+
832+REFERENCES = \
833+ System \
834+ System.Core \
835+ $(GLIB_SHARP_20_LIBS) \
836+ $(GTK_SHARP_20_LIBS) \
837+ $(WNCK_SHARP_10_LIBS) \
838+ $(NDESK_DBUS_10_LIBS) \
839+ $(NDESK_DBUS_GLIB_10_LIBS)
840
841=== modified file 'Docky.Items/Docky.Items/AbstractDockItem.cs'
842--- Docky.Items/Docky.Items/AbstractDockItem.cs 2009-12-10 00:10:27 +0000
843+++ Docky.Items/Docky.Items/AbstractDockItem.cs 2009-12-14 04:44:13 +0000
844@@ -43,6 +43,7 @@
845 public abstract class AbstractDockItem : IDisposable
846 {
847 string hover_text;
848+ string remote_text;
849 bool[] redraw;
850 DockySurface text_buffer;
851 DockySurface[] icon_buffers;
852@@ -76,7 +77,7 @@
853 /// </summary>
854 public ItemState State {
855 get { return state; }
856- protected set {
857+ set {
858 if (state == value)
859 return;
860
861@@ -151,7 +152,7 @@
862 /// </summary>
863 public string HoverText {
864 get {
865- return hover_text;
866+ return string.IsNullOrEmpty (remote_text) ? hover_text : remote_text;
867 }
868 protected set {
869 if (hover_text == value)
870@@ -193,6 +194,14 @@
871 internal set;
872 }
873
874+ /// <summary>
875+ ///
876+ /// </summary>
877+ public Docky.Menus.MenuList RemoteMenuItems {
878+ get;
879+ private set;
880+ }
881+
882 public const int HoverTextHeight = 26;
883
884 protected int IconSize { get; private set; }
885@@ -202,16 +211,24 @@
886 public AbstractDockItem ()
887 {
888 ScalableRendering = true;
889- icon_buffers = new DockySurface [2];
890- badgeColors = new Cairo.Color [2];
891- redraw = new bool [2];
892+ icon_buffers = new DockySurface[2];
893+ badgeColors = new Cairo.Color[2];
894+ redraw = new bool[2];
895 state_times = new Dictionary<ItemState, DateTime> ();
896- foreach (ItemState val in Enum.GetValues (typeof (ItemState)))
897- state_times [val] = new DateTime (0);
898+ foreach (ItemState val in Enum.GetValues (typeof(ItemState)))
899+ state_times[val] = new DateTime (0);
900 Gtk.IconTheme.Default.Changed += HandleIconThemeChanged;
901+ RemoteMenuItems = new Docky.Menus.MenuList ();
902
903 AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
904 }
905+
906+ public void SetRemoteText (string text)
907+ {
908+ remote_text = text;
909+ text_buffer = ResetBuffer (text_buffer);
910+ OnHoverTextChanged ();
911+ }
912
913 void HandleProcessExit (object sender, EventArgs e)
914 {
915@@ -733,7 +750,7 @@
916 public Docky.Menus.MenuList GetMenuItems ()
917 {
918 try {
919- return OnGetMenuItems ();
920+ return OnGetMenuItems ().Combine (RemoteMenuItems);
921 } catch (Exception e) {
922 Log<AbstractDockItem>.Error (e.Message);
923 Log<AbstractDockItem>.Debug (e.StackTrace);
924
925=== modified file 'Docky.Items/Docky.Items/ApplicationDockItem.cs'
926--- Docky.Items/Docky.Items/ApplicationDockItem.cs 2009-12-10 10:14:57 +0000
927+++ Docky.Items/Docky.Items/ApplicationDockItem.cs 2009-12-14 04:44:13 +0000
928@@ -200,7 +200,7 @@
929 }
930 }
931 }
932-
933+
934 return list;
935 }
936
937
938=== modified file 'Docky.Items/Docky.Items/IconDockItem.cs'
939--- Docky.Items/Docky.Items/IconDockItem.cs 2009-12-10 06:28:43 +0000
940+++ Docky.Items/Docky.Items/IconDockItem.cs 2009-12-14 04:44:13 +0000
941@@ -37,9 +37,10 @@
942 {
943 public event EventHandler IconUpdated;
944
945+ string remote_icon;
946 string icon;
947 public string Icon {
948- get { return icon; }
949+ get { return string.IsNullOrEmpty (remote_icon) ? icon : remote_icon; }
950 protected set {
951 // if we set this, clear the forced pixbuf
952 if (forced_pixbuf != null)
953@@ -88,6 +89,14 @@
954 Icon = "";
955 }
956
957+ public void SetRemoteIcon (string icon)
958+ {
959+ remote_icon = icon;
960+
961+ OnIconUpdated ();
962+ QueueRedraw ();
963+ }
964+
965 protected override void PaintIconSurface (DockySurface surface)
966 {
967 Gdk.Pixbuf pbuf;
968
969=== modified file 'Docky.Items/Docky.Menus/MenuList.cs'
970--- Docky.Items/Docky.Menus/MenuList.cs 2009-12-06 08:11:22 +0000
971+++ Docky.Items/Docky.Menus/MenuList.cs 2009-12-14 04:44:13 +0000
972@@ -85,6 +85,12 @@
973 }
974 }
975
976+ public void Remove (MenuItem item)
977+ {
978+ foreach (List<MenuItem> lst in list.Values)
979+ lst.Remove (item);
980+ }
981+
982 public bool Any ()
983 {
984 return list.Values.Any (sl => sl.Any ());
985@@ -94,5 +100,31 @@
986 {
987 return list.Values.Count ();
988 }
989+
990+ public MenuList Combine (MenuList other)
991+ {
992+ MenuList result = new MenuList ();
993+
994+ foreach (KeyValuePair<MenuListContainer, List<MenuItem>> kvp in list)
995+ {
996+ result[kvp.Key].AddRange (kvp.Value);
997+ }
998+
999+ foreach (KeyValuePair<MenuListContainer, List<MenuItem>> kvp in other.list)
1000+ {
1001+ result[kvp.Key].AddRange (kvp.Value);
1002+ }
1003+
1004+ // copy other first so any conflicts are resolved with this copy winning
1005+ foreach (KeyValuePair<MenuListContainer, string> kvp in other.titles) {
1006+ result.SetContainerTitle (kvp.Key, kvp.Value);
1007+ }
1008+
1009+ foreach (KeyValuePair<MenuListContainer, string> kvp in titles) {
1010+ result.SetContainerTitle (kvp.Key, kvp.Value);
1011+ }
1012+
1013+ return result;
1014+ }
1015 }
1016 }
1017
1018=== modified file 'Docky.Windowing/Windowing/DesktopItem.cs'
1019--- Docky.Windowing/Windowing/DesktopItem.cs 2009-12-01 18:32:14 +0000
1020+++ Docky.Windowing/Windowing/DesktopItem.cs 2009-12-14 04:44:13 +0000
1021@@ -35,6 +35,12 @@
1022
1023 public string Location { get; private set; }
1024
1025+ public string DesktopID {
1026+ get {
1027+ return Path.GetFileNameWithoutExtension (Location);
1028+ }
1029+ }
1030+
1031 public DesktopItem (string path)
1032 {
1033 Location = path;
1034
1035=== modified file 'Docky/Docky.csproj'
1036--- Docky/Docky.csproj 2009-12-10 04:56:27 +0000
1037+++ Docky/Docky.csproj 2009-12-14 04:44:13 +0000
1038@@ -155,6 +155,10 @@
1039 <Project>{888FCD95-7C79-45C4-A744-9C840DF4B9B0}</Project>
1040 <Name>Docky.Windowing</Name>
1041 </ProjectReference>
1042+ <ProjectReference Include="..\Docky.DBus\Docky.DBus.csproj">
1043+ <Project>{487D3B93-FAAF-4734-B337-85810A60ACCF}</Project>
1044+ <Name>Docky.DBus</Name>
1045+ </ProjectReference>
1046 </ItemGroup>
1047 <ItemGroup>
1048 <EmbeddedResource Include="gtk-gui\gui.stetic">
1049
1050=== modified file 'Docky/Docky/CairoHelper/DockySurface_Extensions.cs'
1051--- Docky/Docky/CairoHelper/DockySurface_Extensions.cs 2009-11-29 05:40:32 +0000
1052+++ Docky/Docky/CairoHelper/DockySurface_Extensions.cs 2009-12-14 04:44:13 +0000
1053@@ -64,6 +64,52 @@
1054 cr.IdentityMatrix ();
1055 }
1056
1057+ public static void ShowAsReflection (this DockySurface self, DockySurface target, PointD point, double zoom,
1058+ double rotation, double opacity, double height, DockPosition position)
1059+ {
1060+ if (target == null)
1061+ throw new ArgumentNullException ("target");
1062+
1063+ Cairo.Context cr = target.Context;
1064+
1065+ switch (position) {
1066+ case DockPosition.Left:
1067+ point.X -= self.Width * zoom + height;
1068+ break;
1069+ case DockPosition.Top:
1070+ point.Y -= self.Height * zoom + height;
1071+ break;
1072+ case DockPosition.Right:
1073+ point.X += self.Width * zoom + height;
1074+ break;
1075+ case DockPosition.Bottom:
1076+ point.Y += self.Height * zoom + height;
1077+ break;
1078+ }
1079+
1080+ double cos, sin;
1081+ cos = Math.Cos (rotation);
1082+ sin = Math.Sin (rotation);
1083+ Matrix m = new Matrix (cos, sin, 0 - sin, cos, point.X, point.Y);
1084+ cr.Transform (m);
1085+
1086+ if (zoom != 1)
1087+ cr.Scale (zoom, zoom);
1088+
1089+ if (position == DockPosition.Left || position == DockPosition.Right)
1090+ cr.Scale (-1, 1);
1091+ else
1092+ cr.Scale (1, -1);
1093+
1094+ cr.SetSource (self.Internal,
1095+ 0 - self.Width / 2,
1096+ 0 - self.Height / 2);
1097+
1098+ cr.PaintWithAlpha (opacity * .3);
1099+
1100+ cr.IdentityMatrix ();
1101+ }
1102+
1103 public static void ShowAtEdge (this DockySurface self, DockySurface target, PointD point, DockPosition position)
1104 {
1105 if (target == null)
1106@@ -94,14 +140,16 @@
1107 cr.Paint ();
1108 }
1109
1110- public static void TileOntoSurface (this DockySurface self, DockySurface target, Gdk.Rectangle area, int edgeBuffer, DockPosition orientation)
1111+ public static void TileOntoSurface (this DockySurface self, DockySurface target, Gdk.Rectangle area, int edgeBuffer, double tilt, DockPosition orientation)
1112 {
1113 if (orientation == DockPosition.Left || orientation == DockPosition.Right) {
1114+
1115 int x = area.X;
1116 if (orientation == DockPosition.Left)
1117 x -= self.Width - area.Width;
1118
1119 Cairo.Context cr = target.Context;
1120+
1121 // draw left edge
1122 cr.Rectangle (area.X, area.Y, area.Width, edgeBuffer);
1123 cr.SetSource (self.Internal, x, area.Y);
1124@@ -121,17 +169,29 @@
1125 cr.Rectangle (area.X, position, area.Width, edgeBuffer);
1126 cr.SetSource (self.Internal, x, area.Y + area.Height - self.Height);
1127 cr.Fill ();
1128+
1129 } else {
1130+ if (tilt != 1) {
1131+ area.Y += (int) (area.Height * tilt);
1132+ area.Height -= (int) (area.Height * tilt);
1133+ }
1134+
1135 int y = area.Y;
1136 if (orientation == DockPosition.Top)
1137 y -= self.Height - area.Height;
1138
1139 Cairo.Context cr = target.Context;
1140+ cr.Rectangle (area.X - 100, area.Y, edgeBuffer + 100, area.Height);
1141+
1142+ Matrix m = new Matrix (1, 0, -tilt, 1, 0, y);
1143+ cr.Transform (m);
1144+
1145 // draw left edge
1146- cr.Rectangle (area.X, area.Y, edgeBuffer, area.Height);
1147- cr.SetSource (self.Internal, area.X, y);
1148+ cr.SetSource (self.Internal, area.X, 0);
1149 cr.Fill ();
1150
1151+ cr.IdentityMatrix ();
1152+
1153 int maxMiddleMove = self.Width - 2 * edgeBuffer;
1154 int position = area.X + edgeBuffer;
1155 int edgeTarget = area.X + area.Width - edgeBuffer;
1156@@ -143,9 +203,15 @@
1157 position += width;
1158 }
1159
1160- cr.Rectangle (position, area.Y, edgeBuffer, area.Height);
1161- cr.SetSource (self.Internal, area.X + area.Width - self.Width, y);
1162+ cr.Rectangle (position, area.Y, edgeBuffer + 100, area.Height);
1163+
1164+ m = new Matrix (1, 0, tilt, 1, 0, y);
1165+ cr.Transform (m);
1166+
1167+ cr.SetSource (self.Internal, area.X + area.Width - self.Width, 0);
1168 cr.Fill ();
1169+
1170+ cr.IdentityMatrix ();
1171 }
1172 }
1173
1174
1175=== modified file 'Docky/Docky/Docky.cs'
1176--- Docky/Docky/Docky.cs 2009-12-06 07:57:57 +0000
1177+++ Docky/Docky/Docky.cs 2009-12-14 04:44:13 +0000
1178@@ -20,13 +20,14 @@
1179 using System.ComponentModel;
1180 using System.Linq;
1181 using System.Text;
1182+using System.IO;
1183
1184 using Mono.Unix;
1185
1186-using Cairo;
1187 using Gdk;
1188 using Gtk;
1189
1190+using Docky.DBus;
1191 using Docky.Windowing;
1192 using Docky.Services;
1193
1194@@ -87,18 +88,37 @@
1195 CheckComposite ();
1196 };
1197
1198+ DBusManager.Default.Initialize ();
1199 PluginManager.Initialize ();
1200 Controller.Initialize ();
1201
1202+
1203+ GLib.Idle.Add (delegate {
1204+ LaunchHelpers ();
1205+ return false;
1206+ });
1207+
1208 Gdk.Threads.Enter ();
1209 Gtk.Application.Run ();
1210 Gdk.Threads.Leave ();
1211
1212+ DBusManager.Default.Shutdown ();
1213 Controller.Dispose ();
1214 PluginManager.Shutdown ();
1215 Gnome.Vfs.Vfs.Shutdown ();
1216 }
1217
1218+ static void LaunchHelpers ()
1219+ {
1220+ string directory = Path.Combine (DockServices.System.SystemDataFolder, "helpers");
1221+
1222+ if (!Directory.Exists (directory))
1223+ return;
1224+
1225+ foreach (string file in Directory.GetFiles (directory))
1226+ DockServices.System.Execute (file);
1227+ }
1228+
1229 static void CheckComposite ()
1230 {
1231 if (!Gdk.Screen.Default.IsComposited)
1232@@ -134,5 +154,10 @@
1233 };
1234
1235 }
1236+
1237+ public static void Quit ()
1238+ {
1239+ Gtk.Application.Quit ();
1240+ }
1241 }
1242 }
1243
1244=== modified file 'Docky/Docky/Interface/DockPreferences.cs'
1245--- Docky/Docky/Interface/DockPreferences.cs 2009-12-14 02:27:41 +0000
1246+++ Docky/Docky/Interface/DockPreferences.cs 2009-12-14 04:44:13 +0000
1247@@ -62,6 +62,7 @@
1248 public event EventHandler FadeOnHideChanged;
1249 public event EventHandler FadeOpacityChanged;
1250 public event EventHandler IndicatorSettingChanged;
1251+ public event EventHandler ThreeDimensionalChanged;
1252 public event EventHandler ZoomEnabledChanged;
1253 public event EventHandler ZoomPercentChanged;
1254
1255@@ -185,6 +186,22 @@
1256 }
1257 }
1258
1259+ bool? three_dimensional;
1260+ public bool ThreeDimensional {
1261+ get {
1262+ if (!three_dimensional.HasValue)
1263+ three_dimensional = GetOption<bool?> ("ThreeDimensional", false);
1264+ return three_dimensional.Value;
1265+ }
1266+ set {
1267+ if (three_dimensional == value)
1268+ return;
1269+ three_dimensional = value;
1270+ SetOption<bool?> ("ThreeDimensional", three_dimensional.Value);
1271+ OnThreeDimensionalChanged ();
1272+ }
1273+ }
1274+
1275 bool? zoom_enabled;
1276 public bool ZoomEnabled {
1277 get {
1278@@ -288,6 +305,7 @@
1279 SetOption<int?> ("MonitorNumber", 0);
1280 SetOption<string[]> ("Plugins", new string[0]);
1281 SetOption<string[]> ("SortList", new string[0]);
1282+ SetOption<bool?> ("ThreeDimensional", false);
1283 SetOption<bool?> ("WindowManager", false);
1284 SetOption<bool?> ("ZoomEnabled", true);
1285 SetOption<double?> ("ZoomPercent", 2.0);
1286@@ -668,7 +686,13 @@
1287 if (PanelModeChanged != null)
1288 PanelModeChanged (this, EventArgs.Empty);
1289 }
1290-
1291+
1292+ void OnThreeDimensionalChanged ()
1293+ {
1294+ if (ThreeDimensionalChanged != null)
1295+ ThreeDimensionalChanged (this, EventArgs.Empty);
1296+ }
1297+
1298 void OnZoomEnabledChanged ()
1299 {
1300 if (ZoomEnabledChanged != null)
1301
1302=== modified file 'Docky/Docky/Interface/DockWindow.cs'
1303--- Docky/Docky/Interface/DockWindow.cs 2009-12-14 00:56:34 +0000
1304+++ Docky/Docky/Interface/DockWindow.cs 2009-12-14 04:44:13 +0000
1305@@ -30,6 +30,7 @@
1306 using Mono.Unix;
1307 using Wnck;
1308
1309+using Docky.DBus;
1310 using Docky.Items;
1311 using Docky.CairoHelper;
1312 using Docky.Menus;
1313@@ -448,6 +449,11 @@
1314 get { return Preferences.Position; }
1315 }
1316
1317+ bool ThreeDimensional {
1318+ get { return Position == DockPosition.Bottom && Preferences.ThreeDimensional; }
1319+ }
1320+
1321+
1322 bool ZoomEnabled {
1323 get { return !Preferences.PanelMode && Preferences.ZoomEnabled; }
1324 }
1325@@ -516,7 +522,7 @@
1326 }
1327
1328 int DockHeightBuffer {
1329- get { return (Preferences.PanelMode) ? 3 : 7; }
1330+ get { return (Preferences.PanelMode) ? 3 : 7 + (ThreeDimensional ? 5 : 0); }
1331 }
1332
1333 int ItemWidthBuffer {
1334@@ -799,6 +805,8 @@
1335 item.HoverTextChanged += ItemHoverTextChanged;
1336 item.PaintNeeded += ItemPaintNeeded;
1337 item.PainterRequest += ItemPainterRequest;
1338+
1339+ DBusManager.Default.RegisterItem (item);
1340 }
1341
1342 void UnregisterItem (AbstractDockItem item)
1343@@ -807,6 +815,8 @@
1344 item.PaintNeeded -= ItemPaintNeeded;
1345 item.PainterRequest -= ItemPainterRequest;
1346 DrawValues.Remove (item);
1347+
1348+ DBusManager.Default.UnregisterItem (item);
1349 }
1350
1351 void ItemHoverTextChanged (object sender, EventArgs e)
1352@@ -1991,6 +2001,10 @@
1353
1354 // The big expensive paint happens right here!
1355 icon.ShowWithOptions (surface, center.Center, renderZoom, renderRotation, opacity);
1356+ if (ThreeDimensional) {
1357+ double offset = 2 * Math.Max (Math.Abs (val.Center.X - center.Center.X), Math.Abs (val.Center.Y - center.Center.Y));
1358+ icon.ShowAsReflection (surface, center.Center, renderZoom, renderRotation, opacity, offset, Position);
1359+ }
1360
1361 if (lighten > 0) {
1362 surface.Context.Operator = Operator.Add;
1363@@ -2009,7 +2023,7 @@
1364 surface.Context.Operator = Operator.Over;
1365 }
1366
1367- if ((item.State & ItemState.Active) == ItemState.Active) {
1368+ if ((item.State & ItemState.Active) == ItemState.Active && !ThreeDimensional) {
1369 Gdk.Rectangle area;
1370
1371 if (VerticalDock) {
1372@@ -2219,7 +2233,8 @@
1373 background.Dispose ();
1374 }
1375
1376- background_buffer.TileOntoSurface (surface, backgroundArea, 50, Position);
1377+ double tilt = ThreeDimensional ? .6 : 0;
1378+ background_buffer.TileOntoSurface (surface, backgroundArea, 50, tilt, Position);
1379 }
1380
1381 protected override void OnStyleSet (Style previous_style)
1382
1383=== modified file 'Docky/Docky/Interface/IDockPreferences.cs'
1384--- Docky/Docky/Interface/IDockPreferences.cs 2009-11-22 00:41:20 +0000
1385+++ Docky/Docky/Interface/IDockPreferences.cs 2009-12-14 04:44:13 +0000
1386@@ -61,6 +61,8 @@
1387
1388 bool IndicateMultipleWindows { get; set; }
1389
1390+ bool ThreeDimensional { get; set; }
1391+
1392 bool ZoomEnabled { get; set; }
1393
1394 double ZoomPercent { get; set; }
1395
1396=== modified file 'Docky/Docky/Items/DockyItem.cs'
1397--- Docky/Docky/Items/DockyItem.cs 2009-12-09 21:38:26 +0000
1398+++ Docky/Docky/Items/DockyItem.cs 2009-12-14 04:44:13 +0000
1399@@ -90,7 +90,7 @@
1400 MenuList list = new MenuList ();
1401 list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_Settings"), PrefsIcon, (o, a) => Docky.Config.Show ()));
1402 list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_About"), AboutIcon, (o, a) => Docky.ShowAbout ()));
1403- list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_Quit Docky"), CloseIcon, (o, a) => Gtk.Application.Quit ()));
1404+ list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_Quit Docky"), CloseIcon, (o, a) => Docky.Quit ()));
1405 return list;
1406 }
1407
1408
1409=== modified file 'Docky/Makefile.am'
1410--- Docky/Makefile.am 2009-12-11 09:59:30 +0000
1411+++ Docky/Makefile.am 2009-12-14 04:44:13 +0000
1412@@ -53,6 +53,7 @@
1413
1414 PROJECT_REFERENCES= \
1415 Docky.CairoHelper \
1416+ Docky.DBus \
1417 Docky.Items \
1418 Docky.Services \
1419 Docky.Windowing \
1420
1421=== modified file 'Docky/gtk-gui/gui.stetic'
1422--- Docky/gtk-gui/gui.stetic 2009-12-14 00:27:13 +0000
1423+++ Docky/gtk-gui/gui.stetic 2009-12-14 04:44:13 +0000
1424@@ -11,6 +11,7 @@
1425 <widget-library name="../../Docky.Services/bin/Debug/Docky.Services.dll" />
1426 <widget-library name="../../Docky.Items/bin/Debug/Docky.Items.dll" />
1427 <widget-library name="../../Docky.Windowing/bin/Debug/Docky.Windowing.dll" />
1428+ <widget-library name="../../Docky.DBus/bin/Debug/Docky.DBus.dll" />
1429 <widget-library name="../bin/Debug/Docky.exe" internal="true" />
1430 </import>
1431 <widget class="Gtk.Bin" id="Docky.Interface.DockPreferences" design-size="411 356">
1432@@ -126,12 +127,12 @@
1433 <child>
1434 <widget class="Gtk.Label" id="label1">
1435 <property name="MemberName" />
1436+ <property name="CanFocus">True</property>
1437 <property name="Xalign">1</property>
1438 <property name="Yalign">0</property>
1439 <property name="LabelProp" translatable="yes">_Icon Size:</property>
1440+ <property name="UseUnderline">True</property>
1441 <property name="MnemonicWidget">icon_scale</property>
1442- <property name="CanFocus">True</property>
1443- <property name="UseUnderline">True</property>
1444 </widget>
1445 <packing>
1446 <property name="TopAttach">2</property>
1447@@ -150,11 +151,11 @@
1448 <child>
1449 <widget class="Gtk.Label" id="label3">
1450 <property name="MemberName" />
1451+ <property name="CanFocus">True</property>
1452 <property name="Xalign">1</property>
1453 <property name="LabelProp" translatable="yes">_Hiding:</property>
1454+ <property name="UseUnderline">True</property>
1455 <property name="MnemonicWidget">autohide_box</property>
1456- <property name="CanFocus">True</property>
1457- <property name="UseUnderline">True</property>
1458 </widget>
1459 <packing>
1460 <property name="AutoSize">True</property>
1461@@ -739,4 +740,4 @@
1462 </widget>
1463 </child>
1464 </widget>
1465-</stetic-interface>
1466+</stetic-interface>
1467\ No newline at end of file
1468
1469=== modified file 'Makefile.am'
1470--- Makefile.am 2009-12-08 08:26:26 +0000
1471+++ Makefile.am 2009-12-14 04:44:13 +0000
1472@@ -5,6 +5,7 @@
1473 SUBDIRS = \
1474 . \
1475 data \
1476+ scripts \
1477 lib \
1478 po \
1479 Docky.CairoHelper \
1480@@ -13,6 +14,7 @@
1481 Docky.Zeitgeist \
1482 Docky.Windowing \
1483 Docky.Items \
1484+ Docky.DBus \
1485 StandardPlugins \
1486 Docky \
1487 m4
1488
1489=== modified file 'configure.ac'
1490--- configure.ac 2009-12-12 13:40:28 +0000
1491+++ configure.ac 2009-12-14 04:44:13 +0000
1492@@ -176,8 +176,10 @@
1493 lib/gio-sharp/Makefile
1494 lib/gio-sharp/generator/Makefile
1495 lib/gio-sharp/gio/Makefile
1496+scripts/Makefile
1497 Docky/Makefile
1498 Docky.CairoHelper/Makefile
1499+Docky.DBus/Makefile
1500 Docky.Items/Makefile
1501 Docky.Items/Resources/Docky.Items.addin.xml
1502 Docky.Widgets/Makefile
1503
1504=== added directory 'examples'
1505=== added file 'examples/docky_remote.py'
1506--- examples/docky_remote.py 1970-01-01 00:00:00 +0000
1507+++ examples/docky_remote.py 2009-12-14 04:44:13 +0000
1508@@ -0,0 +1,43 @@
1509+#!/usr/bin/env python
1510+
1511+import dbus
1512+import dbus.glib
1513+import gobject
1514+import glib
1515+
1516+array = []
1517+
1518+def menu_pressed_signal(id):
1519+ print 'Signal: Menu Pressed'
1520+
1521+def elapsed_timer():
1522+ for x in array:
1523+ banshee.ConfirmItem (x)
1524+ return True;
1525+
1526+bus = dbus.SessionBus ()
1527+
1528+dockypath = '/org/gnome/Docky'
1529+dockybus = 'org.gnome.Docky'
1530+dockyiface = 'org.gnome.Docky'
1531+itemiface = 'org.gnome.Docky.Item'
1532+
1533+obj = bus.get_object (dockybus, dockypath)
1534+docky = dbus.Interface (obj, dockyiface)
1535+
1536+bansheepath = docky.DockItemPathForDesktopID ("banshee-1")
1537+
1538+obj = bus.get_object (dockybus, bansheepath)
1539+banshee = dbus.Interface (obj, itemiface)
1540+
1541+play_id = banshee.AddMenuItem ("Play", "media-playback-start", "Banshee-Control")
1542+array.append (play_id)
1543+
1544+bus.add_signal_receiver (menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, bansheepath)
1545+
1546+glib.timeout_add (1000 * 60 * 2, elapsed_timer)
1547+
1548+gobject.threads_init()
1549+dbus.glib.init_threads()
1550+main_loop = gobject.MainLoop()
1551+main_loop.run()
1552
1553=== added directory 'scripts'
1554=== added file 'scripts/Makefile.am'
1555--- scripts/Makefile.am 1970-01-01 00:00:00 +0000
1556+++ scripts/Makefile.am 2009-12-14 04:44:13 +0000
1557@@ -0,0 +1,2 @@
1558+scriptdir = $(datadir)/docky/helpers
1559+dist_script_SCRIPTS = zeitgeist_docky.py
1560
1561=== added file 'scripts/zeitgeist_docky.py'
1562--- scripts/zeitgeist_docky.py 1970-01-01 00:00:00 +0000
1563+++ scripts/zeitgeist_docky.py 2009-12-14 04:44:13 +0000
1564@@ -0,0 +1,174 @@
1565+#!/usr/bin/env python
1566+
1567+import gobject
1568+import time
1569+import glib
1570+import dbus
1571+import dbus.glib
1572+import sys
1573+import urllib
1574+import os
1575+
1576+from zeitgeist.client import ZeitgeistClient
1577+from zeitgeist.datamodel import Event, Subject, Interpretation, Manifestation, StorageState
1578+
1579+dockypath = '/org/gnome/Docky'
1580+dockybus = 'org.gnome.Docky'
1581+dockyiface = 'org.gnome.Docky'
1582+itemiface = 'org.gnome.Docky.Item'
1583+
1584+try:
1585+ CLIENT = ZeitgeistClient()
1586+except RuntimeError, e:
1587+ print "Unable to connect to Zeitgeist, won't send events. Reason: '%s'" %e
1588+ CLIENT = None
1589+
1590+class MostUsedProvider():
1591+ def __init__(self):
1592+ self._zg = CLIENT
1593+
1594+ def get_path_most_used( self, path, handler, is_directoy=True):
1595+ today = time.time() * 1000
1596+ delta = (today - 14 * 86400000)
1597+
1598+ def exists(uri):
1599+ return not uri.startswith("file://") or os.path.exists(urllib.unquote(str(uri[7:])))
1600+
1601+ def _handle_find_events(ids):
1602+ self._zg.get_events(ids, _handle_get_events)
1603+
1604+ def _handle_get_events(events):
1605+ uris = []
1606+ counter = 0
1607+ for event in events:
1608+ if counter < 5:
1609+ for subject in event.subjects:
1610+ if counter < 7 and exists(subject.uri):
1611+ uris.append(subject)
1612+ counter+=1
1613+ elif counter >= 7:
1614+ break
1615+ else:
1616+ pass
1617+ #print "skipping", subject.uri
1618+ else:
1619+ break
1620+ handler( uris)
1621+
1622+ event = Event()
1623+ if is_directoy:
1624+ subject = Subject()
1625+ subject.set_origin(path)
1626+ event.set_subjects([subject])
1627+ self._zg.find_event_ids_for_templates([event],_handle_find_events, [delta, today], StorageState.Any, 0, 5)
1628+ else:
1629+ event.set_actor(path)
1630+ self._zg.find_event_ids_for_templates([event],_handle_find_events, [delta, today], StorageState.Any, 0, 5)
1631+
1632+class DockyItem():
1633+ def __init__(self, path):
1634+ self.path = path
1635+ self.bus = dbus.SessionBus ()
1636+ self.id_map = {}
1637+
1638+ obj = self.bus.get_object (dockybus, self.path)
1639+ self.iface = dbus.Interface (obj, itemiface)
1640+
1641+ self.bus.add_signal_receiver (self.menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, self.path)
1642+
1643+ self.mostusedprovider = MostUsedProvider ()
1644+
1645+ self.update_most_used ()
1646+ self.timer = glib.timeout_add (2 * 60 * 1000, self.handle_timeout)
1647+
1648+
1649+ def dispose(self):
1650+ for k, v in self.id_map.iteritems():
1651+ try:
1652+ self.iface.RemoveItem (k)
1653+ except:
1654+ break;
1655+ glib.source_remove (self.timer)
1656+
1657+ def handle_timeout(self):
1658+ for k, v in self.id_map.iteritems():
1659+ self.iface.ConfirmItem (k)
1660+ return True
1661+
1662+ def update_most_used(self):
1663+ uri = ""
1664+ if self.iface.GetOwnsUri ():
1665+ uri = self.iface.GetUri ();
1666+ elif self.iface.GetOwnsDesktopFile ():
1667+ uri = self.iface.GetDesktopFile()
1668+ else:
1669+ return
1670+
1671+ self.mostusedprovider.get_path_most_used (uri, self._handle_get_most_used, self.iface.GetOwnsUri ())
1672+
1673+ def _handle_get_most_used(self, uris):
1674+ for subject in uris:
1675+ menu_id = self.iface.AddMenuItem (subject.text, "gtk-file", "Most Used Items")
1676+ self.id_map[menu_id] = subject.uri
1677+
1678+ def menu_pressed_signal(self, menu_id):
1679+ os.spawnlp(os.P_NOWAIT, "gnome-open", "gnome-open", self.id_map[menu_id])
1680+
1681+class DockySink():
1682+ def __init__(self):
1683+ self.bus = dbus.SessionBus ()
1684+ self.items = {}
1685+ self.disposed = False;
1686+
1687+ obj = self.bus.get_object (dockybus, dockypath)
1688+ self._iface = dbus.Interface (obj, dockyiface)
1689+
1690+ paths = self._iface.DockItemPaths()
1691+
1692+ self.bus.add_signal_receiver (self.item_added, "ItemAdded", dockyiface, dockybus, dockypath)
1693+ self.bus.add_signal_receiver (self.item_removed, "ItemRemoved", dockyiface, dockybus, dockypath)
1694+ self.bus.add_signal_receiver (self.shut_down, "ShuttingDown", dockyiface, dockybus, dockypath)
1695+
1696+ for pathtoitem in paths:
1697+ obj = self.bus.get_object (dockybus, pathtoitem)
1698+ item = dbus.Interface (obj, itemiface)
1699+ if item.GetOwnsUri() or item.GetOwnsDesktopFile():
1700+ self.items[pathtoitem] = DockyItem (pathtoitem)
1701+
1702+ def item_added(self, path):
1703+ if self.disposed:
1704+ return;
1705+ obj = self.bus.get_object (dockybus, path)
1706+ item = dbus.Interface (obj, itemiface)
1707+ if item.GetOwnsUri() or item.GetOwnsDesktopFile ():
1708+ self.items[path] = DockyItem (path)
1709+
1710+ def item_removed(self, path):
1711+ if self.disposed:
1712+ return;
1713+ if path in self.items:
1714+ self.items[path].dispose ()
1715+ del self.items[path]
1716+
1717+ def shut_down(self):
1718+ self.dispose ()
1719+ gobject.idle_add (quit, 1)
1720+
1721+ def dispose(self):
1722+ self.disposed = True;
1723+ for path, item in self.items.iteritems ():
1724+ item.dispose ()
1725+
1726+
1727+if __name__ == "__main__":
1728+ dockysink = DockySink()
1729+ mainloop = gobject.MainLoop(is_running=True)
1730+
1731+ while mainloop.is_running():
1732+ print 'running'
1733+ try:
1734+ mainloop.run()
1735+ except KeyboardInterrupt:
1736+ dockysink.dispose ()
1737+ gobject.idle_add(quit, 1)
1738+ print 'done\n\n'

Subscribers

People subscribed via source and target branches

to status/vote changes: