~ubuntu-branches/ubuntu/natty/gnome-do/natty

« back to all changes in this revision

Viewing changes to Do.Interface.Linux.Docky/src/Docky.Interface/ApplicationDockItem.cs

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane, Daniel T Chen, Iain Lane, Mirco Bauer
  • Date: 2009-03-22 22:44:39 UTC
  • mfrom: (0.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20090322224439-0dndhbvyqz1u2iu2
[ Daniel T Chen ]
* New upstream release (LP: #344578).
  + Gnome Do causes keyboard keys to be remapped (LP: #308143)
  + Docky window too small when summoned (LP: #317381)
  + Minimize/Maximize does not work on all windows (LP: #317908)
  + Docky blocks drag and drop over large areas of the screen
    (LP: #318471)
  + Docky fails to autohide properly when changing themes
    (LP: #318672)
  + Paste via ctrl+v does not work in 1st pane (LP: #318922)
  + Autostart is in wrong assembly (LP: #319114)
  + Docky has no results list (LP: #319797)
  + Docky trash applet does not reflect current state
    (LP: #320621)
  + Docky panels splits into two when over filled (LP: #324648)
  + Docky ui division is inconsistent and confusing
    (LP: #324718)
  + poor performance with two screens (LP: #323294)
  + Docky trash applet doesn't check if trash exists
    (LP: #323453)
  + docky panel splits into two when overfilled (LP: #324648)
  + Docky's UI division is inconsistent and confusing
    (LP: #324718)
  + Do crashes when using a pastebin launcher with docky
    (LP: #325178)
  + Make docky aware of icon theme switch (LP: #328721)
  + Docky doesn't update icon status for some apps that minimize
    to system tray. (LP: #329120)
  + Docky does not work properly with pull-down window
    (LP: #334663)
  + sensitivity of zooming the icons in the dock isn't
    configurable (LP: #336214)
  + Regression: In 0.8.1, "Request attention" is no longer
    indicated (LP: #337594)
  + Clock's Calendar mode auto-hides when leaving the bounds of
    the original dock (LP: #337783)
  + gnome-do does not notice change of icon theme (LP: #204368)
  + Thumbnails are never displayed when files have spaces in
    their names (LP: #311551)
  + Open improperly escapes URLs. (LP: #317416)
  + Docky: Right-click dialog appears on wrong monitor
    (LP: #319062)
  + Dragging items off Docky possible in summon mode
    (LP: #319452)
  + Docky shows icon according to the filename (LP: #320892)
  + Mouse click inactive when Do(cky) is summoned (LP: #324937)
  + Docky trash don't have a right-click menu (LP: #317947)
  + Polish docky's window name labels (LP: #318487)
  + Docky: Scroll on window icon should switch between windows
    of that app (LP: #319805)
  + Docky does not preserve window stack (z?) order when
    switching apps by clicking on app icon (LP: #326661)
  + Docky window switching should be easier. (LP: #327079)
  + Color of indicators on Docky cannot be changed
    (LP: #332936)
  + Do's ResultWindow is using wrong text color (LP: #288771)
  + Docky won't unhide after rev 1053 (LP: #337113)
  + Do's icon label in Docky should be "GNOME Do" instead of
    "Summon GNOME Do" (LP: #338496)
* debian/control:
  + Add librsvg2-2.18-cil build-dep
* debian/patches/03_show_in_all_DEs
  + Drop; fixed in new upstream
* debian/gnome-do.1
  + Update for new version. 

[ Iain Lane ]
* Merge changes with Ubuntu Jaunty
* Autostart behaviour has been fixed upstream (Closes: #513741, #516194).
* debian/patches/10_application_search_path.dpatch: Add. Fix search path so
  that applications are properly indexed. Patch backported from upstream.
* debian/control: Add myself to Uploaders. 
* Really bump versioned dep on libgtk2.0-cil
* debian/control, debian/rules, debian/watch,
  debian/patches/00_remove_bundledlibs.dpatch, debian/README.source:
  Upstream source needs repackaging due to shipped copy of gmcs.exe

[ Mirco Bauer ]
* debian/rules:
  + Made get-orig-source target policy conform.
  + Use dh override targets instead of sequence injection.
* debian/control:
  + Bumped debhelper build-dep to >= 7.0.50
  + Bumped Standards-Version to 3.8.1 (no changes needed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ApplicationDockItem.cs
2
 
// 
3
 
// Copyright (C) 2008 GNOME Do
4
 
//
5
 
// This program is free software: you can redistribute it and/or modify
6
 
// it under the terms of the GNU General Public License as published by
7
 
// the Free Software Foundation, either version 3 of the License, or
8
 
// (at your option) any later version.
9
 
//
10
 
// This program is distributed in the hope that it will be useful,
11
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
// GNU General Public License for more details.
14
 
//
15
 
// You should have received a copy of the GNU General Public License
16
 
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
//
18
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
using System.IO;
22
 
using System.Linq;
23
 
 
24
 
using Cairo;
25
 
using Gdk;
26
 
 
27
 
using Mono.Unix;
28
 
 
29
 
using Do.Interface.CairoUtils;
30
 
using Do.Platform;
31
 
using Do.Interface;
32
 
using Do.Universe;
33
 
 
34
 
using Docky.Utilities;
35
 
 
36
 
namespace Docky.Interface
37
 
{
38
 
        
39
 
        
40
 
        public class ApplicationDockItem : BaseDockItem, IRightClickable, IDockAppItem
41
 
        {
42
 
                public event EventHandler RemoveClicked;
43
 
                
44
 
                static IEnumerable<String> DesktopFilesDirectories {
45
 
                        get {
46
 
                                return new string[] {
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
 
                }
57
 
                
58
 
                string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore");
59
 
                string CloseText = Catalog.GetString ("Close All");
60
 
                
61
 
                const int MenuItemMaxCharacters = 50;
62
 
                const string WindowIcon = "forward";
63
 
                const string MinimizeIcon = "down";
64
 
                
65
 
                int windowCount;
66
 
                bool urgent;
67
 
                
68
 
                Gdk.Rectangle icon_region;
69
 
                Gdk.Pixbuf drag_pixbuf;
70
 
                
71
 
                string Exec {
72
 
                        get {
73
 
                                string exec;
74
 
                                foreach (Wnck.Application app in Applications) {
75
 
                                        exec = MaybeGetExecStringForPID (app.Pid);
76
 
                                        if (exec != null)
77
 
                                                return exec;
78
 
                                }
79
 
 
80
 
                                foreach (Wnck.Window win in VisibleWindows) {
81
 
                                        exec = MaybeGetExecStringForPID (win.Pid);
82
 
                                        if (exec != null)
83
 
                                                return exec;
84
 
                                }
85
 
                                return null;
86
 
                        }
87
 
                }
88
 
                
89
 
                #region IDockItem implementation 
90
 
                
91
 
                public override Pixbuf GetDragPixbuf ()
92
 
                {
93
 
                        if (drag_pixbuf == null)
94
 
                                drag_pixbuf = GetSurfacePixbuf ();
95
 
                        return drag_pixbuf;
96
 
                }
97
 
                
98
 
                /// <summary>
99
 
                /// Returns a Pixbuf suitable for usage in the dock.
100
 
                /// </summary>
101
 
                /// <returns>
102
 
                /// A <see cref="Gdk.Pixbuf"/>
103
 
                /// </returns>
104
 
                protected override Gdk.Pixbuf GetSurfacePixbuf ()
105
 
                {
106
 
                        Gdk.Pixbuf pbuf = null;
107
 
                        foreach (string guess in GetIconGuesses ()) {
108
 
                                if (pbuf != null) {
109
 
                                        pbuf.Dispose ();
110
 
                                        pbuf = null;
111
 
                                }
112
 
                                
113
 
                                bool found = IconProvider.PixbufFromIconName (guess, DockPreferences.FullIconSize, out pbuf);
114
 
                                if (found && (pbuf.Width == DockPreferences.FullIconSize || pbuf.Height == DockPreferences.FullIconSize))
115
 
                                        break;
116
 
                                
117
 
                                pbuf.Dispose ();
118
 
                                pbuf = null;
119
 
                        
120
 
                                string desktopPath = GetDesktopFile (guess);
121
 
                                if (!string.IsNullOrEmpty (desktopPath)) {
122
 
                                        try {
123
 
                                                string icon = Services.UniverseFactory.NewApplicationItem (desktopPath).Icon;
124
 
                                                pbuf = IconProvider.PixbufFromIconName (icon, DockPreferences.FullIconSize);
125
 
                                                break;
126
 
                                        } catch {
127
 
                                                continue;
128
 
                                        }
129
 
                                }
130
 
                        }
131
 
                        
132
 
                        // we failed to find an icon, lets use an uggggly one
133
 
                        if (pbuf == null)
134
 
                                pbuf = Applications.First ().Icon;
135
 
                        
136
 
                        if (pbuf.Height != DockPreferences.FullIconSize && pbuf.Width != DockPreferences.FullIconSize) {
137
 
                                double scale = (double)DockPreferences.FullIconSize / Math.Max (pbuf.Width, pbuf.Height);
138
 
                                Gdk.Pixbuf temp = pbuf.ScaleSimple ((int) (pbuf.Width * scale), (int) (pbuf.Height * scale), Gdk.InterpType.Hyper);
139
 
                                pbuf.Dispose ();
140
 
                                pbuf = temp;
141
 
                        }
142
 
                        return pbuf;
143
 
                }
144
 
                
145
 
                public override string Description {
146
 
                        get {
147
 
                                foreach (Wnck.Application application in Applications) {
148
 
                                        if (StringIsValidName (application.IconName))
149
 
                                                return application.IconName;
150
 
                                        else if (StringIsValidName (application.Name))
151
 
                                                return application.Name;
152
 
                                }
153
 
 
154
 
                                foreach (Wnck.Window window in VisibleWindows) {
155
 
                                        if (StringIsValidName (window.IconName))
156
 
                                                return window.IconName;
157
 
                                        else if (StringIsValidName (window.Name))
158
 
                                                return window.Name;
159
 
                                }
160
 
                                return "Unknown";
161
 
                        }
162
 
                }
163
 
                
164
 
                public override int WindowCount {
165
 
                        get { return windowCount; }
166
 
                }
167
 
                
168
 
                IEnumerable<Wnck.Application> Applications { get; set; }
169
 
 
170
 
                IEnumerable<Wnck.Window> VisibleWindows {
171
 
                        get { return Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist); }
172
 
                }
173
 
                
174
 
                #endregion 
175
 
                
176
 
                public ApplicationDockItem (IEnumerable<Wnck.Application> applications) : base ()
177
 
                {
178
 
                        Applications = applications;
179
 
                        windowCount = VisibleWindows.Count ();
180
 
                        AttentionRequestStartTime = DateTime.UtcNow - new TimeSpan (0, 10, 0);
181
 
                        
182
 
                        foreach (Wnck.Window w in VisibleWindows) {
183
 
                                w.StateChanged += HandleStateChanged;
184
 
                        }
185
 
                }
186
 
 
187
 
                void HandleStateChanged(object o, Wnck.StateChangedArgs args)
188
 
                {
189
 
                        bool tmp = urgent;
190
 
                        urgent = DetermineUrgencyStatus ();
191
 
                        if (urgent != tmp) {
192
 
                                UpdateRequestType req = (urgent) ? UpdateRequestType.NeedsAttentionSet : UpdateRequestType.NeedsAttentionUnset;
193
 
                                if (urgent)
194
 
                                        AttentionRequestStartTime = DateTime.UtcNow;
195
 
                                if (UpdateNeeded != null)
196
 
                                        UpdateNeeded (this, new UpdateRequestArgs (this, req));
197
 
                        }
198
 
                }
199
 
                
200
 
                IEnumerable<string> GetIconGuesses ()
201
 
                {
202
 
                        List<string> guesses = new List<string> ();
203
 
                        foreach (Wnck.Application app in Applications) {
204
 
                                if (!guesses.Contains (PrepName (app.Name)))
205
 
                                        guesses.Add (PrepName (app.Name));
206
 
                                if (!guesses.Contains (PrepName (app.IconName)))
207
 
                                        guesses.Add (PrepName (app.IconName));
208
 
                        }
209
 
 
210
 
                        foreach (Wnck.Window win in VisibleWindows) {
211
 
                                if (!guesses.Contains (PrepName (win.Name)))
212
 
                                        guesses.Add (PrepName (win.Name));
213
 
                                if (!guesses.Contains (PrepName (win.IconName)))
214
 
                                        guesses.Add (PrepName (win.IconName));
215
 
                                if (!guesses.Contains (PrepName (win.ClassGroup.ResClass)))
216
 
                                        guesses.Add (PrepName (win.ClassGroup.ResClass));
217
 
                        }
218
 
                        
219
 
                        foreach (string s in guesses)
220
 
                                yield return s;
221
 
                        
222
 
                        foreach (string s in guesses)
223
 
                                yield return "gnome-" + s;
224
 
                        
225
 
                        if (Description.Length > 4 && Description.Contains (" "))
226
 
                                yield return Description.Split (' ') [0].ToLower ();
227
 
                        
228
 
                        if (!string.IsNullOrEmpty (Exec)) {
229
 
                                yield return Exec;
230
 
                                yield return Exec.Split ('-')[0];
231
 
                        }
232
 
                }
233
 
 
234
 
                string PrepName (string s)
235
 
                {
236
 
                        return s.ToLower ().Replace (' ', '-');
237
 
                }
238
 
                
239
 
                string MaybeGetExecStringForPID (int pid)
240
 
                {
241
 
                        string exec;
242
 
                        try {
243
 
                                // this fails on mono pre 2.0
244
 
                                exec = System.Diagnostics.Process.GetProcessById (pid).ProcessName.Split (' ')[0];
245
 
                        } catch { exec = null; }
246
 
                        
247
 
                        if (string.IsNullOrEmpty (exec)) {
248
 
                                try {
249
 
                                        // this works on all versions of mono but is less reliable (because I wrote it)
250
 
                                        exec = WindowUtils.CmdLineForPid (pid).Split (' ')[0];
251
 
                                } catch { }
252
 
                        }
253
 
                        if (exec == "")
254
 
                                exec = null;
255
 
                        
256
 
                        return exec;
257
 
                }
258
 
                
259
 
                string GetDesktopFile (string base_name)
260
 
                {
261
 
                        foreach (string dir in DesktopFilesDirectories) {
262
 
                                try {
263
 
                                        if (File.Exists (System.IO.Path.Combine (dir, base_name+".desktop")))
264
 
                                                return System.IO.Path.Combine (dir, base_name+".desktop");
265
 
                                        if (File.Exists (System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop")))
266
 
                                                return System.IO.Path.Combine (dir, "gnome-"+base_name+".desktop");
267
 
                                } catch { return null; }
268
 
                        }
269
 
                        return null;
270
 
                }
271
 
                
272
 
                bool StringIsValidName (string s)
273
 
                {
274
 
                        return (!string.IsNullOrEmpty (s.Trim ()) && s != "<unknown>");
275
 
                }
276
 
                
277
 
                public override void Clicked (uint button)
278
 
                {
279
 
                        if (button == 1) {
280
 
                                WindowUtils.PerformLogicalClick (Applications);
281
 
                                AnimationType = ClickAnimationType.Darken;
282
 
                        } else {
283
 
                                AnimationType = ClickAnimationType.None;
284
 
                        }
285
 
                        
286
 
                        base.Clicked (button);
287
 
                }
288
 
 
289
 
                public override void SetIconRegion (Gdk.Rectangle region)
290
 
                {
291
 
                        if (icon_region == region)
292
 
                                return;
293
 
                        icon_region = region;
294
 
 
295
 
                        VisibleWindows.ForEach (w => w.SetIconGeometry (region.X, region.Y, region.Width, region.Height));
296
 
                }
297
 
                
298
 
                public override bool Equals (BaseDockItem other)
299
 
                {
300
 
                        if (!(other is ApplicationDockItem))
301
 
                                return false;
302
 
 
303
 
                        return Applications.Any (app => (other as ApplicationDockItem).Applications.Contains (app));
304
 
                }
305
 
                
306
 
                public IEnumerable<AbstractMenuButtonArgs> GetMenuItems ()
307
 
                {
308
 
                        foreach (Wnck.Window window in VisibleWindows)
309
 
                                yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon);
310
 
                        
311
 
                        yield return new SeparatorMenuButtonArgs ();
312
 
                        
313
 
                        yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows), 
314
 
                                                               MinimizeRestoreText, MinimizeIcon);
315
 
                        
316
 
                        yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows), 
317
 
                                                               CloseText, Gtk.Stock.Quit);
318
 
                }
319
 
 
320
 
                #region IDockAppItem implementation 
321
 
                
322
 
                public event UpdateRequestHandler UpdateNeeded;
323
 
                
324
 
                public bool NeedsAttention {
325
 
                        get { return urgent; }
326
 
                }
327
 
                
328
 
                public DateTime AttentionRequestStartTime {
329
 
                        get; private set;
330
 
                }
331
 
                
332
 
                #endregion 
333
 
                
334
 
                bool DetermineUrgencyStatus ()
335
 
                {
336
 
                        return VisibleWindows.Any (w => !w.IsSkipTasklist && w.NeedsAttention ());
337
 
                }
338
 
 
339
 
                public override void Dispose ()
340
 
                {
341
 
                        foreach (Wnck.Window w in VisibleWindows)
342
 
                                w.StateChanged -= HandleStateChanged;
343
 
                        
344
 
                        base.Dispose ();
345
 
                }
346
 
 
347
 
        }
348
 
}