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

« back to all changes in this revision

Viewing changes to Do.Interface.Linux.Docky/src/Docky.Utilities/WindowUtils.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:
18
18
 
19
19
using System;
20
20
using System.Collections.Generic;
 
21
using System.Diagnostics;
21
22
using System.IO;
22
23
using System.Linq;
 
24
using System.Text.RegularExpressions;
23
25
 
24
26
using Do.Interface;
25
27
using Do.Universe;
35
37
        
36
38
        public static class WindowUtils
37
39
        {
38
 
                static IEnumerable<string> BadPrefixes {
 
40
                static string RemapFile {
 
41
                        get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); }
 
42
                }
 
43
                
 
44
                public static IEnumerable<string> BadPrefixes {
39
45
                        get {
40
 
                                yield return "gksu ";
41
 
                                yield return "sudo ";
42
 
                                yield return "python ";
 
46
                                yield return "gksu";
 
47
                                yield return "sudo";
 
48
                                yield return "java";
 
49
                                yield return "mono";
 
50
                                yield return "ruby";
 
51
                                yield return "padsp";
 
52
                                yield return "aoss";
 
53
                                yield return "python(\\d.\\d)?";
43
54
                        }
44
55
                }
45
56
                
 
57
                static Dictionary<string, string> RemapDictionary { get; set; }
 
58
                
46
59
                static List<Application> application_list;
47
60
                static bool application_list_update_needed;
48
61
                
 
62
                static Dictionary<int, string> exec_lines = new Dictionary<int, string> ();
 
63
                static DateTime last_update = new DateTime (0);
 
64
                
49
65
                static WindowUtils ()
50
66
                {
51
67
                        Wnck.Screen.Default.WindowClosed += delegate {
63
79
                        Wnck.Screen.Default.ApplicationClosed += delegate {
64
80
                                application_list_update_needed = true;
65
81
                        };
 
82
                        
 
83
                        BuildRemapDictionary ();
 
84
                }
 
85
                
 
86
                static void BuildRemapDictionary ()
 
87
                {
 
88
                        if (!File.Exists (RemapFile)) {
 
89
                                RemapDictionary = BuildDefaultRemapDictionary ();
 
90
                                
 
91
                                StreamWriter writer = null;
 
92
                                try {
 
93
                                        writer = new StreamWriter (RemapFile);
 
94
                                        writer.WriteLine ("# Docky Remap File");
 
95
                                        writer.WriteLine ("# Add key value pairs following dictionary syntax");
 
96
                                        writer.WriteLine ("# key, value");
 
97
                                        writer.WriteLine ("# key, altKey, value");
 
98
                                        writer.WriteLine ("# Lines starting with # are comments, otherwise # is a valid character");
 
99
                                        
 
100
                                        foreach (KeyValuePair<string, string> kvp in RemapDictionary) {
 
101
                                                writer.WriteLine ("{0}, {1}", kvp.Key, kvp.Value);
 
102
                                        }
 
103
                                        writer.Close ();
 
104
                                } finally {
 
105
                                        if (writer != null)
 
106
                                                writer.Dispose ();
 
107
                                }
 
108
                        } else {
 
109
                                RemapDictionary = new Dictionary<string, string> ();
 
110
                                
 
111
                                StreamReader reader = null;
 
112
                                try {
 
113
                                        reader = new StreamReader (RemapFile);
 
114
                                        
 
115
                                        string line;
 
116
                                        while (!reader.EndOfStream) {
 
117
                                                line = reader.ReadLine ();
 
118
                                                if (line.StartsWith ("#") || !line.Contains (","))
 
119
                                                        continue;
 
120
                                                string [] array = line.Split (',');
 
121
                                                if (array.Length < 2 || array [0].Length == 0)
 
122
                                                        continue;
 
123
                                                
 
124
                                                string val = array [array.Length - 1].Trim ().ToLower ();
 
125
                                                if (string.IsNullOrEmpty (val))
 
126
                                                        continue;
 
127
                                                
 
128
                                                for (int i=0; i < array.Length - 1; i++) {
 
129
                                                        string key = array [i].Trim ().ToLower ();
 
130
                                                        if (string.IsNullOrEmpty (key))
 
131
                                                                continue;
 
132
                                                        RemapDictionary [key] = val;
 
133
                                                }
 
134
                                        }
 
135
                                        
 
136
                                        reader.Close ();
 
137
                                } catch {
 
138
                                        Log.Error ("Could not read remap file");
 
139
                                        RemapDictionary = BuildDefaultRemapDictionary ();
 
140
                                } finally {
 
141
                                        if (reader != null)
 
142
                                                reader.Dispose ();
 
143
                                }
 
144
                        }
 
145
                }
 
146
                
 
147
                static Dictionary<string, string> BuildDefaultRemapDictionary ()
 
148
                {
 
149
                        Dictionary<string, string> remapDict = new Dictionary<string, string> ();
 
150
                        remapDict ["banshee.exe"] = "banshee";
 
151
                        remapDict ["banshee-1"] = "banshee";
 
152
                        remapDict ["azureus"] = "vuze";
 
153
                        remapDict ["thunderbird-3.0"] = "thunderbird";
 
154
                        remapDict ["thunderbird-bin"] = "thunderbird";
 
155
                        
 
156
                        return remapDict;
66
157
                }
67
158
                
68
159
                /// <summary>
95
186
                public static string CmdLineForPid (int pid)
96
187
                {
97
188
                        StreamReader reader;
98
 
                        string cmdline;
 
189
                        string cmdline = null;
 
190
                        
99
191
                        try {
100
192
                                string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine);
101
193
                                reader = new StreamReader (procPath);
102
 
                                cmdline = reader.ReadLine ();
 
194
                                cmdline = reader.ReadLine ().Replace (Convert.ToChar (0x0), ' ');
103
195
                                reader.Close ();
104
196
                                reader.Dispose ();
105
 
                        } catch { return null; }
 
197
                        } catch { }
106
198
                        
107
199
                        return cmdline;
108
200
                }
122
214
                        if (string.IsNullOrEmpty (exec))
123
215
                                return apps;
124
216
                        
125
 
                        foreach (string s in BadPrefixes) {
126
 
                                if (exec.StartsWith (s)) {
127
 
                                        exec = exec.Substring (s.Length);
128
 
                                        break;
 
217
                        exec = ProcessExecString (exec);
 
218
                        if (string.IsNullOrEmpty (exec))
 
219
                                return apps;
 
220
                        
 
221
                        UpdateExecList ();
 
222
 
 
223
                        foreach (KeyValuePair<int, string> kvp in exec_lines) {
 
224
                                if (kvp.Value != null && kvp.Value.Contains (exec)) {
 
225
                                        foreach (Application app in GetApplications ()) {
 
226
                                                if (app == null)
 
227
                                                        continue;
 
228
                                                
 
229
                                                if (app.Pid == kvp.Key || app.Windows.Any (w => w.Pid == kvp.Key)) {
 
230
                                                        if (app.Windows.Any (win => !win.IsSkipTasklist))
 
231
                                                                apps.Add (app);
 
232
                                                        break;
 
233
                                                }
 
234
                                        }
129
235
                                }
130
236
                        }
131
 
                        exec = exec.Split (' ')[0];
132
 
                        
133
 
                        Application out_app = null;
 
237
                        return apps;
 
238
                }
 
239
                
 
240
                static void UpdateExecList ()
 
241
                {
 
242
                        if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return;
 
243
                        
 
244
                        exec_lines.Clear ();
 
245
                        
134
246
                        foreach (string dir in Directory.GetDirectories ("/proc")) {
135
247
                                int pid;
136
 
                                out_app = null;
137
248
                                try { pid = Convert.ToInt32 (Path.GetFileName (dir)); } 
138
249
                                catch { continue; }
139
250
                                
141
252
                                if (string.IsNullOrEmpty (exec_line))
142
253
                                        continue;
143
254
                                
144
 
                                if (exec_line.Contains (exec)) {
 
255
                                if (exec_line.Contains ("java") && exec_line.Contains ("jar")) {
145
256
                                        foreach (Application app in GetApplications ()) {
146
257
                                                if (app == null)
147
258
                                                        continue;
148
259
                                                
149
 
                                                if (app.Pid == pid) {
150
 
                                                        if (app.Windows.Select (win => !win.IsSkipTasklist).Any ())
151
 
                                                                out_app = app;
152
 
                                                        break;
 
260
                                                if (app.Pid == pid || app.Windows.Any (w => w.Pid == pid)) {
 
261
                                                        foreach (Wnck.Window window in app.Windows.Where (win => !win.IsSkipTasklist)) {
 
262
                                                                exec_line = window.ClassGroup.ResClass;
 
263
                                                                
 
264
                                                                // Vuze is retarded
 
265
                                                                if (exec_line == "SWT")
 
266
                                                                        exec_line = window.Name;
 
267
                                                                Console.WriteLine (exec_line);
 
268
                                                                break;
 
269
                                                        }
153
270
                                                }
154
271
                                        }
155
 
                                }
156
 
                                
157
 
                                if (out_app != null)
158
 
                                        apps.Add (out_app);
159
 
                        }
160
 
                        return apps;
 
272
                                }       
 
273
                                
 
274
                                exec_line = ProcessExecString (exec_line);
 
275
                                        
 
276
                                exec_lines [pid] = exec_line;
 
277
                        }
 
278
                        
 
279
                        last_update = DateTime.UtcNow;
 
280
                }
 
281
 
 
282
                public static string ProcessExecString (string exec)
 
283
                {
 
284
                        exec = exec.ToLower ().Trim ();
 
285
                        
 
286
                        if (RemapDictionary.ContainsKey (exec))
 
287
                                return RemapDictionary [exec];
 
288
                        
 
289
                        if (exec.StartsWith ("/")) {
 
290
                                string first_part = exec.Split (' ') [0];
 
291
                                int length = first_part.Length;
 
292
                                first_part = first_part.Split ('/').Last ();
 
293
                                
 
294
                                if (length < exec.Length)
 
295
                                         first_part = first_part + " " + exec.Substring (length + 1);
 
296
                                                
 
297
                                if (RemapDictionary.ContainsKey (first_part)) {
 
298
                                        return RemapDictionary [first_part];
 
299
                                }
 
300
                        }
 
301
                        
 
302
                        string [] parts = exec.Split (' ');
 
303
                        for (int i = 0; i < parts.Length; i++) {
 
304
                                if (parts [i].StartsWith ("-"))
 
305
                                        continue;
 
306
                                
 
307
                                if (parts [i].Contains ("/"))
 
308
                                        parts [i] = parts [i].Split ('/').Last ();
 
309
                                
 
310
                                Regex regex;
 
311
                                foreach (string prefix in BadPrefixes) {
 
312
                                        regex = new Regex (string.Format ("^{0}$", prefix), RegexOptions.IgnoreCase);
 
313
                                        if (regex.IsMatch (parts [i])) {
 
314
                                                parts [i] = null;
 
315
                                                break;
 
316
                                        }
 
317
                                }
 
318
                                
 
319
                                if (!string.IsNullOrEmpty (parts [i])) {
 
320
                                        string out_val = parts [i];
 
321
                                        if (RemapDictionary.ContainsKey (out_val))
 
322
                                                out_val = RemapDictionary [out_val];
 
323
                                        return out_val;
 
324
                                }
 
325
                        }
 
326
                        return null;
161
327
                }
162
328
                
163
329
                /// <summary>
168
334
                /// </param>
169
335
                public static void PerformLogicalClick (IEnumerable<Application> apps)
170
336
                {
171
 
                        bool not_in_viewport = !apps.Any (app => app.Windows
172
 
                                                          .Any (w => !w.IsSkipTasklist && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)));
173
 
                        bool urgent = apps.Any (app => app.Windows.Any (w => w.NeedsAttention ()));
 
337
                        List<Window> stack = new List<Window> (Wnck.Screen.Default.WindowsStacked);
 
338
                        IEnumerable<Window> windows = apps
 
339
                                .SelectMany (app => app.Windows)
 
340
                                .OrderByDescending (w => stack.IndexOf (w));
 
341
                        
 
342
                        bool not_in_viewport = !windows.Any (w => !w.IsSkipTasklist && w.IsInViewport (w.Screen.ActiveWorkspace));
 
343
                        bool urgent = windows.Any (w => w.NeedsAttention ());
174
344
                        
175
345
                        if (not_in_viewport || urgent) {
176
 
                                foreach (Wnck.Application application in apps) {
177
 
                                        foreach (Wnck.Window window in application.Windows) {
178
 
                                                if (urgent && !window.NeedsAttention ())
179
 
                                                                continue;
180
 
                                                if (!window.IsSkipTasklist) {
181
 
                                                        window.CenterAndFocusWindow ();
182
 
                                                        return;
183
 
                                                }
 
346
                                foreach (Wnck.Window window in windows) {
 
347
                                        if (urgent && !window.NeedsAttention ())
 
348
                                                continue;
 
349
                                        if (!window.IsSkipTasklist) {
 
350
                                                WindowControl.IntelligentFocusOffViewportWindow (window, windows);
 
351
                                                return;
184
352
                                        }
185
353
                                }
186
354
                        }
187
355
                        
188
 
                        List<Window> windows = new List<Window> ();
189
 
                        foreach (Wnck.Application app in apps)
190
 
                                windows.AddRange (app.Windows);
191
 
                        
192
356
                        switch (GetClickAction (apps)) {
193
357
                        case ClickAction.Focus:
194
358
                                WindowControl.FocusWindows (windows);