~ubuntu-branches/ubuntu/trusty/gnome-do/trusty-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2009-03-13 18:00:35 UTC
  • mfrom: (1.1.6 upstream) (0.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090313180035-08lo8130dasdg7n8
Tags: 0.8.1.3-0ubuntu1
* 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)
* Build against gtk, gnome mono packages from Experimental.
* debian/control:
  + Bump versioned dep on libgtk2.0-cil to ensure
    Gdk.Screen.IsComposited exists
  + Add libwnck2.20-cil build-dep
  + Add librsvg2-2.18-cil build-dep
  + gnome-sharp2 transition.
* debian/patches/03_show_in_all_DEs
  + Drop; fixed in new upstream
* debian/gnome-do.1
  + Update for new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// DockItem.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 Gdk;
25
 
using Cairo;
26
 
using Mono.Unix;
27
 
 
28
 
using Do.Interface;
29
 
using Do.Platform;
30
 
using Do.Universe;
31
 
using Do.Universe.Common;
32
 
using Do.Interface.CairoUtils;
33
 
 
34
 
using Docky.Utilities;
35
 
 
36
 
using Wnck;
37
 
 
38
 
namespace Docky.Interface
39
 
{
40
 
        
41
 
        
42
 
        public class DockItem : BaseDockItem, IRightClickable, IDockAppItem
43
 
        {
44
 
                Item element;
45
 
                List<Wnck.Application> apps;
46
 
                Gdk.Rectangle icon_region;
47
 
                Gdk.Pixbuf drag_pixbuf;
48
 
                bool needs_attention, accepting_drops;
49
 
                uint handle_timer;
50
 
                int window_count;
51
 
                
52
 
                public event EventHandler RemoveClicked;
53
 
                
54
 
                public event UpdateRequestHandler UpdateNeeded;
55
 
                
56
 
                public DateTime AttentionRequestStartTime { get; private set; }
57
 
                
58
 
                public int Position { get; set; }
59
 
                
60
 
                public override bool IsAcceptingDrops { 
61
 
                        get { return accepting_drops; } 
62
 
                }
63
 
                
64
 
                public string Icon { 
65
 
                        get { return element.Icon; } 
66
 
                }
67
 
                
68
 
                public override string Description { 
69
 
                        get { return element.Name; } 
70
 
                }
71
 
                
72
 
                public Item Element { 
73
 
                        get { return element; } 
74
 
                }
75
 
                
76
 
                public Wnck.Application [] Applications { 
77
 
                        get { return apps.ToArray (); } 
78
 
                }
79
 
                
80
 
                public IEnumerable<int> Pids { 
81
 
                        get { return apps.Select (win => win.Pid).ToArray (); } 
82
 
                }
83
 
                
84
 
                public override int WindowCount {
85
 
                        get { return window_count; }
86
 
                }
87
 
                
88
 
                public bool NeedsAttention { 
89
 
                        get { 
90
 
                                return needs_attention; 
91
 
                        } 
92
 
                        
93
 
                        private set {
94
 
                                if (needs_attention == value)
95
 
                                        return;
96
 
                                needs_attention = value;
97
 
                                AttentionRequestStartTime = DateTime.UtcNow;
98
 
                        }
99
 
                }
100
 
                
101
 
                public IEnumerable<Act> ActionsForItem {
102
 
                        get {
103
 
                                IEnumerable<Act> actions = Services.Core.GetActionsForItemOrderedByRelevance (element, false);
104
 
                                // we want to keep the window operations stable, so we are going to special case them out now.
105
 
                                // This has a degree of an abstraction break to it however, but it is important to get right
106
 
                                // until a better solution is found.
107
 
                                foreach (Act act in actions
108
 
                                         .OrderByDescending (act => act.GetType ().Name != "WindowCloseAction")
109
 
                                         .ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction")
110
 
                                         .ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction")
111
 
                                         .ThenByDescending (act => act.Relevance))
112
 
                                        yield return act;
113
 
                        }
114
 
                }
115
 
                        
116
 
                
117
 
                bool HasVisibleApps {
118
 
                        get {
119
 
                                if (apps == null)
120
 
                                        return false;
121
 
                                return apps.SelectMany (app => app.Windows).Any (win => !win.IsSkipTasklist);
122
 
                        }
123
 
                }       
124
 
                
125
 
                public DockItem (Item element) : base ()
126
 
                {
127
 
                        Position = -1;
128
 
                        apps =  new List<Wnck.Application> ();
129
 
                        this.element = element;
130
 
 
131
 
                        AttentionRequestStartTime = DateTime.UtcNow;
132
 
                        UpdateApplication ();
133
 
                        NeedsAttention = DetermineAttentionStatus ();
134
 
                        
135
 
                        if (element is IFileItem && System.IO.Directory.Exists ((element as IFileItem).Path))
136
 
                                accepting_drops = true;
137
 
                        else
138
 
                                accepting_drops = false;
139
 
                }
140
 
                
141
 
                public override bool ReceiveItem (string item)
142
 
                {
143
 
                        if (!IsAcceptingDrops)
144
 
                                return false;
145
 
                        
146
 
                        if (item.StartsWith ("file://"))
147
 
                                item = item.Substring ("file://".Length);
148
 
                        
149
 
                        if (File.Exists (item)) {
150
 
                                try {
151
 
                                        File.Move (item, System.IO.Path.Combine ((Element as IFileItem).Path, System.IO.Path.GetFileName (item)));
152
 
                                } catch { return false; }
153
 
                                return true;
154
 
                        } else if (Directory.Exists (item)) {
155
 
                                try {
156
 
                                        Directory.Move (item, System.IO.Path.Combine ((Element as IFileItem).Path, System.IO.Path.GetFileName (item)));
157
 
                                } catch { return false; }
158
 
                                return true;
159
 
                        }
160
 
                        return false;
161
 
                }
162
 
                
163
 
                public void UpdateApplication ()
164
 
                {
165
 
                        UnregisterStateChangeEvents ();
166
 
                        
167
 
                        if (element is IApplicationItem) {
168
 
                                apps = WindowUtils.GetApplicationList ((element as IApplicationItem).Exec);
169
 
                                window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();
170
 
                        }
171
 
                        
172
 
                        RegisterStateChangeEvents ();
173
 
                }
174
 
                
175
 
                void RegisterStateChangeEvents ()
176
 
                {
177
 
                        foreach (Application app in Applications) {
178
 
                                foreach (Wnck.Window w in app.Windows) {
179
 
                                        if (!w.IsSkipTasklist)
180
 
                                                w.StateChanged += OnWindowStateChanged;
181
 
                                }
182
 
                        }
183
 
                }
184
 
                
185
 
                void UnregisterStateChangeEvents ()
186
 
                {
187
 
                        foreach (Application app in Applications) {
188
 
                                foreach (Wnck.Window w in app.Windows) {
189
 
                                        try {
190
 
                                                w.StateChanged -= OnWindowStateChanged;
191
 
                                        } catch {}
192
 
                                }
193
 
                        }
194
 
                }
195
 
                
196
 
                void OnWindowStateChanged (object o, StateChangedArgs args)
197
 
                {
198
 
                        if (handle_timer > 0)
199
 
                                return;
200
 
                        // we do this delayed so that we dont get a flood of these events.  Certain windows behave badly.
201
 
                        handle_timer = GLib.Timeout.Add (100, HandleUpdate);
202
 
                        window_count = Applications.SelectMany (a => a.Windows).Where (w => !w.IsSkipTasklist).Count ();
203
 
                        SetIconRegionFromCache ();
204
 
                }
205
 
                
206
 
                bool HandleUpdate ()
207
 
                {
208
 
                        bool needed_attention = NeedsAttention;
209
 
                        NeedsAttention = DetermineAttentionStatus ();
210
 
                        
211
 
                        if (NeedsAttention != needed_attention) {
212
 
                                UpdateRequestType req;
213
 
                                if (NeedsAttention) 
214
 
                                        req = UpdateRequestType.NeedsAttentionSet;
215
 
                                else
216
 
                                        req = UpdateRequestType.NeedsAttentionUnset;
217
 
                                if (UpdateNeeded != null)
218
 
                                        UpdateNeeded (this, new UpdateRequestArgs (this, req));
219
 
                        }
220
 
                        
221
 
                        handle_timer = 0;
222
 
                        return false;
223
 
                }
224
 
                
225
 
                bool DetermineAttentionStatus  ()
226
 
                {
227
 
                        foreach (Application app in Applications) {
228
 
                                if (app.Windows.Any (w => !w.IsSkipTasklist && w.NeedsAttention ()))
229
 
                                        return true;
230
 
                        }
231
 
                        return false;
232
 
                }
233
 
                
234
 
                protected override Gdk.Pixbuf GetSurfacePixbuf ()
235
 
                {
236
 
                        Gdk.Pixbuf pbuf = IconProvider.PixbufFromIconName (Icon, DockPreferences.FullIconSize);
237
 
                        if (pbuf.Height != DockPreferences.FullIconSize && pbuf.Width != DockPreferences.FullIconSize) {
238
 
                                double scale = (double)DockPreferences.FullIconSize / Math.Max (pbuf.Width, pbuf.Height);
239
 
                                Gdk.Pixbuf temp = pbuf.ScaleSimple ((int) (pbuf.Width * scale), (int) (pbuf.Height * scale), InterpType.Bilinear);
240
 
                                pbuf.Dispose ();
241
 
                                pbuf = temp;
242
 
                        }
243
 
                        
244
 
                        return pbuf;
245
 
                }
246
 
                
247
 
                public override Pixbuf GetDragPixbuf ()
248
 
                {
249
 
                        if (drag_pixbuf == null)
250
 
                                drag_pixbuf = IconProvider.PixbufFromIconName (Icon, DockPreferences.FullIconSize);
251
 
                        return drag_pixbuf;
252
 
                }
253
 
                
254
 
                public override void Clicked (uint button)
255
 
                {
256
 
                        if (!apps.Any () || !HasVisibleApps || button == 2) {
257
 
                                AnimationType = ClickAnimationType.Bounce;
258
 
                                Launch ();
259
 
                        } else if (button == 1) {
260
 
                                AnimationType = ClickAnimationType.Darken;
261
 
                                WindowUtils.PerformLogicalClick (apps);
262
 
                        }
263
 
                        
264
 
                        base.Clicked (button);
265
 
                }
266
 
                
267
 
                void Launch ()
268
 
                {
269
 
                        if (Element is IFileItem)
270
 
                                Services.Core.PerformDefaultAction (Element as Item, new [] { typeof (OpenAction), });
271
 
                        else
272
 
                                Services.Core.PerformDefaultAction (Element as Item, Type.EmptyTypes);
273
 
                }
274
 
                
275
 
                public override void SetIconRegion (Gdk.Rectangle region)
276
 
                {
277
 
                        if (icon_region == region)
278
 
                                return;
279
 
                        icon_region = region;
280
 
                        
281
 
                        SetIconRegionFromCache ();
282
 
                }
283
 
                
284
 
                void SetIconRegionFromCache ()
285
 
                {
286
 
                        Applications.ForEach (app => app.Windows.Where (w => !w.IsSkipTasklist)
287
 
                                              .ForEach (w => w.SetIconGeometry (icon_region.X, icon_region.Y, icon_region.Width, icon_region.Height)));
288
 
                }
289
 
                
290
 
                public override bool Equals (BaseDockItem other)
291
 
                {
292
 
                        DockItem di = other as DockItem;
293
 
                        return di != null && di.Element.UniqueId == Element.UniqueId;
294
 
                }
295
 
 
296
 
                #region IDisposable implementation 
297
 
                
298
 
                public override void Dispose ()
299
 
                {
300
 
                        UnregisterStateChangeEvents ();
301
 
                        element = null;
302
 
                        apps.Clear ();
303
 
                        
304
 
                        if (drag_pixbuf != null)
305
 
                                drag_pixbuf.Dispose ();
306
 
                        
307
 
                        base.Dispose ();
308
 
                }
309
 
                
310
 
                #region IRightClickable implementation 
311
 
                
312
 
                public IEnumerable<AbstractMenuButtonArgs> GetMenuItems ()
313
 
                {
314
 
                        bool hasApps = HasVisibleApps;
315
 
                        
316
 
                        if (hasApps) {
317
 
                                foreach (Wnck.Window window in Applications.SelectMany (app => app.Windows).Where (w => !w.IsSkipTasklist))
318
 
                                                yield return new WindowMenuButtonArgs (window, window.Name, Icon);
319
 
                                yield return new SeparatorMenuButtonArgs ();
320
 
                        }
321
 
                        
322
 
                        foreach (Act act in ActionsForItem)
323
 
                                yield return new LaunchMenuButtonArgs (act, element, act.Name, act.Icon);
324
 
 
325
 
                        yield return new SimpleMenuButtonArgs (OnRemoveClicked, Catalog.GetString ("Remove from Dock"), Gtk.Stock.Remove);
326
 
                }
327
 
                
328
 
                #endregion 
329
 
                #endregion
330
 
                
331
 
                void OnRemoveClicked ()
332
 
                {
333
 
                        if (RemoveClicked != null)
334
 
                                RemoveClicked (this, new EventArgs ());
335
 
                }
336
 
        }
337
 
}