1
// ApplicationDockItem.cs
3
// Copyright (C) 2008 GNOME Do
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.
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.
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/>.
20
using System.Collections.Generic;
29
using Do.Interface.CairoUtils;
30
using Do.Interface.Wink;
35
using Docky.Interface.Menus;
36
using Docky.Utilities;
38
namespace Docky.Interface
42
public class ApplicationDockItem : WnckDockItem, IRightClickable
44
public event EventHandler RemoveClicked;
46
string MinimizeRestoreText = Catalog.GetString ("Minimize") + "/" + Catalog.GetString ("Restore");
47
string MaximizeText = Catalog.GetString ("Maximize");
48
string CloseText = Catalog.GetString ("Close All");
50
const int MenuItemMaxCharacters = 50;
53
get { return "maximize.svg@" + GetType ().Assembly.FullName; }
57
get { return "minimize.svg@" + GetType ().Assembly.FullName; }
61
get { return "close.svg@" + GetType ().Assembly.FullName; }
74
IEnumerable<Wnck.Window> windows;
76
IApplicationItem launcher;
78
public IApplicationItem Launcher {
80
if (launcher == null && Exec != null) {
81
string command = WindowUtils.ProcessExecString (Exec);
82
launcher = Services.UniverseFactory.MaybeApplicationItemFromCommand (command);
88
public override Item Item {
90
return Launcher as Item;
98
foreach (Wnck.Window win in VisibleWindows) {
99
exec = MaybeGetExecStringForPID (win.Pid);
108
/// Returns a Pixbuf suitable for usage in the dock.
111
/// A <see cref="Gdk.Pixbuf"/>
113
protected override Gdk.Pixbuf GetSurfacePixbuf (int size)
115
Gdk.Pixbuf pbuf = null;
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))
127
IconProvider.PixbufFromIconName (Launcher.Icon, size, out pbuf);
130
// we failed to find an icon, lets use an uggggly one
132
pbuf = Windows.First ().Icon;
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);
145
if (!VisibleWindows.Any ())
148
if (NeedsAttention) {
149
return VisibleWindows.Where (w => w.NeedsAttention ()).First ().Name;
151
if (VisibleWindows.Any () && VisibleWindows.Count () == 1) {
152
return VisibleWindows.First ().Name;
155
foreach (Wnck.Window window in VisibleWindows) {
156
if (window.ClassGroup != null) {
157
if (StringIsValidName (window.ClassGroup.ResClass))
158
return window.ClassGroup.ResClass;
160
if (StringIsValidName (window.IconName))
161
return window.IconName;
162
else if (StringIsValidName (window.Name))
169
public override int WindowCount {
170
get { return windowCount; }
173
public override IEnumerable<Wnck.Window> Windows {
174
get { return windows; }
177
public ApplicationDockItem (IEnumerable<Wnck.Window> windows) : base ()
179
this.windows = windows;
180
windowCount = VisibleWindows.Count ();
182
foreach (Wnck.Window w in VisibleWindows) {
183
w.StateChanged += HandleStateChanged;
184
w.NameChanged += HandleNameChanged;
190
void HandleNameChanged(object sender, EventArgs e)
195
void HandleStateChanged(object o, Wnck.StateChangedArgs args)
197
bool tmp = NeedsAttention;
198
NeedsAttention = DetermineUrgencyStatus ();
199
if (NeedsAttention != tmp) {
200
UpdateRequestType req = (NeedsAttention) ? UpdateRequestType.NeedsAttentionSet : UpdateRequestType.NeedsAttentionUnset;
202
AttentionRequestStartTime = DateTime.UtcNow;
203
OnUpdateNeeded (new UpdateRequestArgs (this, req));
205
if ((args.ChangedMask & Wnck.WindowState.SkipTasklist) == Wnck.WindowState.SkipTasklist) {
206
if (VisibleWindows.Count () == 0)
207
Core.DockServices.ItemsService.ForceUpdate ();
213
IEnumerable<string> GetIconGuesses ()
215
List<string> guesses = new List<string> ();
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";
226
if (!string.IsNullOrEmpty (exec)) {
228
yield return exec.Split ('-')[0];
229
yield return WindowUtils.ProcessExecString (exec);
232
foreach (Wnck.Window win in VisibleWindows) {
233
if (!guesses.Contains (PrepName (win.Name)))
234
guesses.Add (PrepName (win.Name));
236
if (!guesses.Contains (PrepName (win.IconName)))
237
guesses.Add (PrepName (win.IconName));
239
if (win.ClassGroup == null)
242
if (!guesses.Contains (PrepName (win.ClassGroup.ResClass)))
243
guesses.Add (PrepName (win.ClassGroup.ResClass));
245
if (!guesses.Contains (PrepName (win.ClassGroup.Name)))
246
guesses.Add (PrepName (win.ClassGroup.Name));
249
foreach (string s in guesses) {
254
string PrepName (string s)
256
return s.ToLower ().Replace (' ', '-');
259
string MaybeGetExecStringForPID (int pid)
264
exec = WindowUtils.ProcessExecString (WindowUtils.CmdLineForPid (pid));
273
bool StringIsValidName (string s)
276
if (string.IsNullOrEmpty (s) || s == "<unknown>")
279
foreach (System.Text.RegularExpressions.Regex prefix in WindowUtils.BadPrefixes) {
280
if (prefix.IsMatch (s))
287
public override bool Equals (AbstractDockItem other)
289
if (!(other is ApplicationDockItem))
292
return Windows.Any (w => (other as ApplicationDockItem).Windows.Contains (w));
295
public IEnumerable<AbstractMenuArgs> GetMenuItems ()
297
yield return new SeparatorMenuButtonArgs ();
299
Item item = Launcher as Item;
301
yield return new SimpleMenuButtonArgs (() => WindowControl.MinimizeRestoreWindows (VisibleWindows),
302
MinimizeRestoreText, MinimizeIcon).AsDark ();
304
yield return new SimpleMenuButtonArgs (() => WindowControl.MaximizeWindow (VisibleWindows.First ()),
305
MaximizeText, MaximizeIcon).AsDark ();
307
yield return new SimpleMenuButtonArgs (() => WindowControl.CloseWindows (VisibleWindows),
308
CloseText, CloseIcon).AsDark ();
310
foreach (Act act in ActionsForItem (item))
311
yield return new LaunchMenuButtonArgs (act, item, act.Name, act.Icon).AsDark ();
314
foreach (Wnck.Window window in VisibleWindows) {
315
yield return new SeparatorMenuButtonArgs ();
316
yield return new WindowMenuButtonArgs (window, window.Name, WindowIcon);
320
protected override void Launch ()
322
if (Launcher != null)
326
public override void Dispose ()
328
foreach (Wnck.Window w in VisibleWindows) {
329
w.StateChanged -= HandleStateChanged;
330
w.NameChanged -= HandleNameChanged;