2
// Copyright (C) 2009 GNOME Do
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
using System.Collections.Generic;
29
using Do.Interface.Wink;
30
using Do.Universe.Common;
32
using Do.Interface.CairoUtils;
35
using Docky.Interface.Menus;
36
using Docky.Utilities;
40
namespace Docky.Interface
44
public abstract class WnckDockItem : AbstractDockItem
46
const string ErrorMessage = "Docky could not move the file to the requested Directory. " +
47
"Please check file name and permissions and try again";
49
// a bad hack, but it works
50
static string [] blacklist = new [] {
51
"CopyToClipboardAction",
56
bool? accepting_drops;
57
Gdk.Rectangle icon_region;
59
DateTime last_scroll = new DateTime (0);
60
TimeSpan scroll_rate = new TimeSpan (0, 0, 0, 0, 200);
62
public abstract IEnumerable<Wnck.Window> Windows { get; }
64
public abstract Item Item { get; }
66
protected IEnumerable<Wnck.Window> VisibleWindows {
67
get { return Windows.Where (w => !w.IsSkipTasklist); }
70
protected bool HasVisibleApps {
74
return VisibleWindows.Any ();
78
public override bool ContainsFocusedWindow {
80
return Windows.Any (w => w.IsActive && (!w.IsSkipTasklist || w.WindowType != Wnck.WindowType.Desktop));
84
public override bool ContainsMinimizedWindow {
86
return Windows.Any (w => w.IsMinimized && (!w.IsSkipTasklist));
91
public override bool IsAcceptingDrops {
93
if (!accepting_drops.HasValue) {
94
accepting_drops = (Item is IFileItem && Directory.Exists ((Item as IFileItem).Path)) || (Item is IApplicationItem);
96
return accepting_drops.Value;
100
public WnckDockItem() : base ()
106
void RegisterEvents ()
108
DockServices.PainterService.PainterShowRequest += HandleShowRequest;
109
DockServices.PainterService.PainterHideRequest += HandleHideRequest;
112
void UnregisterEvents ()
114
DockServices.PainterService.PainterShowRequest -= HandleShowRequest;
115
DockServices.PainterService.PainterHideRequest -= HandleHideRequest;
118
public override void SetIconRegion (Gdk.Rectangle region)
120
if (icon_region == region) return;
121
icon_region = region;
122
SetIconRegionFromCache ();
125
protected void SetIconRegionFromCache ()
127
VisibleWindows.ForEach (w => w.SetIconGeometry (icon_region.X, icon_region.Y, icon_region.Width, icon_region.Height));
130
protected IEnumerable<Act> ActionsForItem (Item item)
132
return Services.Core.GetActionsForItemOrderedByRelevance (item, false)
133
.Where (act => !blacklist.Contains (act.GetType ().Name))
134
.OrderByDescending (act => act.GetType ().Name != "WindowCloseAction")
135
.ThenByDescending (act => act.GetType ().Name != "WindowMaximizeAction")
136
.ThenByDescending (act => act.GetType ().Name != "WindowMinimizeAction")
137
.ThenBy (act => act.Name.Length)
138
.ThenBy (act => act.Name);
141
protected abstract void Launch ();
143
public override void Scrolled (Gdk.ScrollDirection direction)
145
if (WindowCount < 1 || (DateTime.UtcNow - last_scroll) < scroll_rate) return;
147
last_scroll = DateTime.UtcNow;
149
// This block will make sure that if we're scrolling on an app that is already active
150
// that when we scroll we move on the next window instead of appearing to do nothing
151
Wnck.Window focused = VisibleWindows.Where (w => w.IsActive).FirstOrDefault ();
152
if (focused != null) {
153
for (; last_raised < WindowCount - 1; last_raised++) {
154
if (VisibleWindows.ElementAt (last_raised).Pid == focused.Pid)
160
case ScrollDirection.Up:
161
case ScrollDirection.Right:
164
case ScrollDirection.Down:
165
case ScrollDirection.Left:
170
KeepLastRaiseInBounds ();
171
VisibleWindows.ElementAt (last_raised).CenterAndFocusWindow ();
174
public override void Clicked (uint button, Gdk.ModifierType state, PointD position)
176
if (!Windows.Any () || !HasVisibleApps || button == 2) {
177
AnimationType = ClickAnimationType.Bounce;
179
} else if (button == 1) {
180
AnimationType = ClickAnimationType.Darken;
181
WindowUtils.PerformLogicalClick (Windows);
183
AnimationType = ClickAnimationType.None;
186
base.Clicked (button, state, position);
189
public void HandleShowRequest (object sender, EventArgs e)
191
VisibleWindows.ForEach (w => w.SetIconGeometry (0, 0, 0, 0));
194
public void HandleHideRequest (object sender, EventArgs e)
196
SetIconRegionFromCache ();
199
protected bool DetermineUrgencyStatus ()
201
return VisibleWindows.Any (w => !w.IsSkipTasklist && w.NeedsAttention ());
204
void KeepLastRaiseInBounds ()
206
if (WindowCount <= last_raised)
208
else if (last_raised < 0)
209
last_raised = WindowCount - 1;
212
public override bool ReceiveItem (string item)
215
if (!IsAcceptingDrops)
218
if (item.StartsWith ("file://"))
219
item = item.Substring ("file://".Length);
221
if (File.Exists (item)) {
222
if (Item is IApplicationItem) {
224
(Item as IApplicationItem).LaunchWithFiles (Do.Platform.Services.UniverseFactory.NewFileItem (item).Cons (null));
226
AnimationType = ClickAnimationType.Bounce;
229
Services.Notifications.Notify ("Docky Error", "Docky could not launch application");
233
File.Move (item, System.IO.Path.Combine ((Item as IFileItem).Path, System.IO.Path.GetFileName (item)));
236
Services.Notifications.Notify ("Docky Error", ErrorMessage);
239
} else if (Directory.Exists (item)) {
241
Directory.Move (item, System.IO.Path.Combine ((Item as IFileItem).Path, System.IO.Path.GetFileName (item)));
244
Services.Notifications.Notify ("Docky Error", ErrorMessage);
250
public override void Dispose ()