~and471/+junk/do-with-docky

« back to all changes in this revision

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

  • Committer: rugby471 at gmail
  • Date: 2010-10-15 16:08:38 UTC
  • Revision ID: rugby471@gmail.com-20101015160838-z9m3utbf7bxzb5ty
reverted to before docky removal

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.Interface.Wink;
 
31
using Do.Platform;
 
32
using Do.Interface;
 
33
using Do.Universe;
 
34
 
 
35
using Docky.Interface.Menus;
 
36
using Docky.Utilities;
 
37
 
 
38
namespace Docky.Interface
 
39
{
 
40
        
 
41
        
 
42
        public class ApplicationDockItem : WnckDockItem, IRightClickable
 
43
        {
 
44
                public event EventHandler RemoveClicked;
 
45
                
 
46
                string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore");
 
47
                string MaximizeText = Catalog.GetString ("Maximize");
 
48
                string CloseText = Catalog.GetString ("Close All");
 
49
                
 
50
                const int MenuItemMaxCharacters = 50;
 
51
                
 
52
                string MaximizeIcon {
 
53
                        get { return "maximize.svg@" + GetType ().Assembly.FullName; }
 
54
                }
 
55
                
 
56
                string MinimizeIcon {
 
57
                        get { return "minimize.svg@" + GetType ().Assembly.FullName; }
 
58
                }
 
59
                
 
60
                string CloseIcon {
 
61
                        get { return "close.svg@" + GetType ().Assembly.FullName; }
 
62
                }
 
63
                
 
64
                string WindowIcon {
 
65
                        get {
 
66
                                if (Launcher == null)
 
67
                                        return "forward";
 
68
                                return Launcher.Icon;
 
69
                        }
 
70
                }
 
71
                
 
72
                int windowCount;
 
73
                
 
74
                IEnumerable<Wnck.Window> windows;
 
75
                
 
76
                IApplicationItem launcher;
 
77
                
 
78
                public IApplicationItem Launcher {
 
79
                        get {
 
80
                                if (launcher == null && Exec != null) {
 
81
                                        string command = WindowUtils.ProcessExecString (Exec);
 
82
                                        launcher = Services.UniverseFactory.MaybeApplicationItemFromCommand (command);
 
83
                                }
 
84
                                return launcher;
 
85
                        }
 
86
                }
 
87
                
 
88
                public override Item Item {
 
89
                        get {
 
90
                                return Launcher as Item;
 
91
                        }
 
92
                }
 
93
                
 
94
                string Exec {
 
95
                        get {
 
96
                                string exec;
 
97
 
 
98
                                foreach (Wnck.Window win in VisibleWindows) {
 
99
                                        exec = MaybeGetExecStringForPID (win.Pid);
 
100
                                        if (exec != null)
 
101
                                                return exec;
 
102
                                }
 
103
                                return null;
 
104
                        }
 
105
                }
 
106
                
 
107
                /// <summary>
 
108
                /// Returns a Pixbuf suitable for usage in the dock.
 
109
                /// </summary>
 
110
                /// <returns>
 
111
                /// A <see cref="Gdk.Pixbuf"/>
 
112
                /// </returns>
 
113
                protected override Gdk.Pixbuf GetSurfacePixbuf (int size)
 
114
                {
 
115
                        Gdk.Pixbuf pbuf = null;
 
116
                        
 
117
                        if (Launcher == null) {
 
118
                                foreach (string guess in GetIconGuesses ()) {
 
119
                                        bool found = IconProvider.PixbufFromIconName (guess, size, out pbuf);
 
120
                                        if (found && (pbuf.Width == size || pbuf.Height == size))
 
121
                                                break;
 
122
                                        
 
123
                                        pbuf.Dispose ();
 
124
                                        pbuf = null;
 
125
                                }
 
126
                        } else {
 
127
                                IconProvider.PixbufFromIconName (Launcher.Icon, size, out pbuf);
 
128
                        }
 
129
                        
 
130
                        // we failed to find an icon, lets use an uggggly one
 
131
                        if (pbuf == null)
 
132
                                pbuf = Windows.First ().Icon;
 
133
                        
 
134
                        if (pbuf.Height != size && pbuf.Width != size ) {
 
135
                                double scale = (double)size / Math.Max (pbuf.Width, pbuf.Height);
 
136
                                Gdk.Pixbuf temp = pbuf.ScaleSimple ((int) (pbuf.Width * scale), (int) (pbuf.Height * scale), Gdk.InterpType.Hyper);
 
137
                                pbuf.Dispose ();
 
138
                                pbuf = temp;
 
139
                        }
 
140
                        return pbuf;
 
141
                }
 
142
                
 
143
                string Name {
 
144
                        get {
 
145
                                if (!VisibleWindows.Any ())
 
146
                                        return "Unknown";
 
147
                                
 
148
                                if (NeedsAttention) {
 
149
                                        return VisibleWindows.Where (w => w.NeedsAttention ()).First ().Name;
 
150
                                }
 
151
                                if (VisibleWindows.Any () && VisibleWindows.Count () == 1) {
 
152
                                        return VisibleWindows.First ().Name;
 
153
                                }
 
154
                                
 
155
                                foreach (Wnck.Window window in VisibleWindows) {
 
156
                                        if (window.ClassGroup != null) {
 
157
                                                if (StringIsValidName (window.ClassGroup.ResClass))
 
158
                                                        return window.ClassGroup.ResClass;
 
159
                                        }
 
160
                                        if (StringIsValidName (window.IconName))
 
161
                                                return window.IconName;
 
162
                                        else if (StringIsValidName (window.Name))
 
163
                                                return window.Name;
 
164
                                }
 
165
                                return "Unknown";
 
166
                        }
 
167
                }
 
168
                
 
169
                public override int WindowCount {
 
170
                        get { return windowCount; }
 
171
                }
 
172
                
 
173
                public override IEnumerable<Wnck.Window> Windows { 
 
174
                        get { return windows; } 
 
175
                }
 
176
 
 
177
                public ApplicationDockItem (IEnumerable<Wnck.Window> windows) : base ()
 
178
                {
 
179
                        this.windows = windows;
 
180
                        windowCount = VisibleWindows.Count ();
 
181
                        
 
182
                        foreach (Wnck.Window w in VisibleWindows) {
 
183
                                w.StateChanged += HandleStateChanged;
 
184
                                w.NameChanged += HandleNameChanged;
 
185
                        }
 
186
 
 
187
                        base.SetText (Name);
 
188
                }
 
189
 
 
190
                void HandleNameChanged(object sender, EventArgs e)
 
191
                {
 
192
                        SetText (Name);
 
193
                }
 
194
 
 
195
                void HandleStateChanged(object o, Wnck.StateChangedArgs args)
 
196
                {
 
197
                        bool tmp = NeedsAttention;
 
198
                        NeedsAttention = DetermineUrgencyStatus ();
 
199
                        if (NeedsAttention != tmp) {
 
200
                                UpdateRequestType req = (NeedsAttention) ? UpdateRequestType.NeedsAttentionSet : UpdateRequestType.NeedsAttentionUnset;
 
201
                                if (NeedsAttention)
 
202
                                        AttentionRequestStartTime = DateTime.UtcNow;
 
203
                                OnUpdateNeeded (new UpdateRequestArgs (this, req));
 
204
                        }
 
205
                        if ((args.ChangedMask & Wnck.WindowState.SkipTasklist) == Wnck.WindowState.SkipTasklist) {
 
206
                                if (VisibleWindows.Count () == 0)
 
207
                                        Core.DockServices.ItemsService.ForceUpdate ();
 
208
                        }
 
209
                        
 
210
                        SetText (Name);
 
211
                }
 
212
                
 
213
                IEnumerable<string> GetIconGuesses ()
 
214
                {
 
215
                        List<string> guesses = new List<string> ();
 
216
                        
 
217
                        // open office hack...
 
218
                        if (VisibleWindows.Any () &&
 
219
                            VisibleWindows.First ().ClassGroup != null &&
 
220
                            VisibleWindows.First ().ClassGroup.ResClass.ToLower ().Contains ("openoffice")) {
 
221
                                yield return "openoffice";
 
222
                                yield break;
 
223
                        }
 
224
                        
 
225
                        string exec = Exec;
 
226
                        if (!string.IsNullOrEmpty (exec)) {
 
227
                                yield return exec;
 
228
                                yield return exec.Split ('-')[0];
 
229
                                yield return WindowUtils.ProcessExecString (exec);
 
230
                        }
 
231
 
 
232
                        foreach (Wnck.Window win in VisibleWindows) {
 
233
                                if (!guesses.Contains (PrepName (win.Name)))
 
234
                                        guesses.Add (PrepName (win.Name));
 
235
                                
 
236
                                if (!guesses.Contains (PrepName (win.IconName)))
 
237
                                        guesses.Add (PrepName (win.IconName));
 
238
                                
 
239
                                if (win.ClassGroup == null)
 
240
                                        continue;
 
241
                                
 
242
                                if (!guesses.Contains (PrepName (win.ClassGroup.ResClass)))
 
243
                                        guesses.Add (PrepName (win.ClassGroup.ResClass));
 
244
                                
 
245
                                if (!guesses.Contains (PrepName (win.ClassGroup.Name)))
 
246
                                        guesses.Add (PrepName (win.ClassGroup.Name));
 
247
                        }
 
248
                        
 
249
                        foreach (string s in guesses) {
 
250
                                yield return s;
 
251
                        }
 
252
                }
 
253
 
 
254
                string PrepName (string s)
 
255
                {
 
256
                        return s.ToLower ().Replace (' ', '-');
 
257
                }
 
258
                
 
259
                string MaybeGetExecStringForPID (int pid)
 
260
                {
 
261
                        string exec = null;
 
262
                        
 
263
                        try {
 
264
                                exec = WindowUtils.ProcessExecString (WindowUtils.CmdLineForPid (pid));
 
265
                        } catch { }
 
266
                
 
267
                        if (exec == "")
 
268
                                exec = null;
 
269
                        
 
270
                        return exec;
 
271
                }
 
272
                
 
273
                bool StringIsValidName (string s)
 
274
                {
 
275
                        s = s.Trim ();
 
276
                        if (string.IsNullOrEmpty (s) || s == "<unknown>")
 
277
                                return false;
 
278
                        
 
279
                        foreach (System.Text.RegularExpressions.Regex prefix in WindowUtils.BadPrefixes) {
 
280
                                if (prefix.IsMatch (s))
 
281
                                        return false;
 
282
                        }
 
283
                        
 
284
                        return true;
 
285
                }
 
286
 
 
287
                public override bool Equals (AbstractDockItem other)
 
288
                {
 
289
                        if (!(other is ApplicationDockItem))
 
290
                                return false;
 
291
 
 
292
                        return Windows.Any (w => (other as ApplicationDockItem).Windows.Contains (w));
 
293
                }
 
294
                
 
295
                public IEnumerable<AbstractMenuArgs> GetMenuItems ()
 
296
                {
 
297
                        yield return new SeparatorMenuButtonArgs ();
 
298
                        
 
299
                        Item item = Launcher as Item;
 
300
                        if (item == null) {
 
301
                                yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows), 
 
302
                                                                       MinimizeRestoreText, MinimizeIcon).AsDark ();
 
303
                                
 
304
                                yield return new SimpleMenuButtonArgs (() => WindowControl.MaximizeWindow (VisibleWindows.First ()), 
 
305
                                                                       MaximizeText, MaximizeIcon).AsDark ();
 
306
                                
 
307
                                yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows), 
 
308
                                                                       CloseText, CloseIcon).AsDark ();
 
309
                        } else {
 
310
                                foreach (Act act in ActionsForItem (item))
 
311
                                        yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark ();
 
312
                        }
 
313
                        
 
314
                        foreach (Wnck.Window window in VisibleWindows) {
 
315
                                yield return new SeparatorMenuButtonArgs ();
 
316
                                yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon);
 
317
                        }
 
318
                }
 
319
                
 
320
                protected override void Launch ()
 
321
                {
 
322
                        if (Launcher != null)
 
323
                                Launcher.Run ();
 
324
                }
 
325
 
 
326
                public override void Dispose ()
 
327
                {
 
328
                        foreach (Wnck.Window w in VisibleWindows) {
 
329
                                w.StateChanged -= HandleStateChanged;
 
330
                                w.NameChanged -= HandleNameChanged;
 
331
                        }
 
332
                        
 
333
                        base.Dispose ();
 
334
                }
 
335
 
 
336
        }
 
337
}