~and471/+junk/do-with-docky

« back to all changes in this revision

Viewing changes to Do.Interface.Linux.Docky/src/Docky.Interface/AutohideTracker.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
//  
 
2
//  Copyright (C) 2009 GNOME Do
 
3
// 
 
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.
 
8
// 
 
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.
 
13
// 
 
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/>.
 
16
// 
 
17
 
 
18
using System;
 
19
using System.Collections.Generic;
 
20
using System.Linq;
 
21
 
 
22
using Gdk;
 
23
using Wnck;
 
24
 
 
25
using Do.Interface;
 
26
using Do.Interface.Wink;
 
27
using Docky.Utilities;
 
28
 
 
29
namespace Docky.Interface
 
30
{
 
31
        
 
32
        
 
33
        public class AutohideTracker : IDisposable
 
34
        {
 
35
                DockArea parent;
 
36
                bool window_intersecting_other;
 
37
                
 
38
                Gdk.Rectangle last_known_geo;
 
39
                
 
40
                public event EventHandler IntersectionChanged;
 
41
                
 
42
                public bool WindowIntersectingOther {
 
43
                        get {
 
44
                                return window_intersecting_other;
 
45
                        }
 
46
                        set {
 
47
                                if (window_intersecting_other == value)
 
48
                                        return;
 
49
                                
 
50
                                window_intersecting_other = value;
 
51
                                if (IntersectionChanged != null)
 
52
                                        IntersectionChanged (this, EventArgs.Empty);
 
53
                        }
 
54
                }
 
55
                
 
56
                internal AutohideTracker (DockArea parent)
 
57
                {
 
58
                        this.parent = parent;
 
59
                        DockPreferences.IconSizeChanged         += HandleIconSizeChanged;
 
60
                        Wnck.Screen.Default.ActiveWindowChanged += HandleActiveWindowChanged;
 
61
                        Wnck.Screen.Default.WindowClosed        += WnckScreenDefaultWindowClosed;
 
62
                        Wnck.Screen.Default.WindowOpened        += WnckScreenDefaultWindowOpened;
 
63
                        Wnck.Screen.Default.ViewportsChanged    += HandleViewportsChanged; 
 
64
                }
 
65
 
 
66
                void HandleViewportsChanged (object sender, EventArgs e)
 
67
                {
 
68
                        // only update if the active window is on the current viewport. If it is not this is going to result
 
69
                        // in a hiccup when that active window is updated
 
70
                        if (Wnck.Screen.Default.ActiveWindow != null)
 
71
                                if (Wnck.Screen.Default.ActiveWindow.IsInViewport (Wnck.Screen.Default.ActiveWorkspace) || !ScreenUtils.ActiveViewport.Windows ().Any ())
 
72
                                        UpdateWindowIntersect ();
 
73
                }
 
74
 
 
75
                void HandleIconSizeChanged ()
 
76
                {
 
77
                        UpdateWindowIntersect ();
 
78
                }
 
79
 
 
80
                void WnckScreenDefaultWindowOpened (object o, WindowOpenedArgs args)
 
81
                {
 
82
                        UpdateWindowIntersect ();
 
83
                }
 
84
 
 
85
                void WnckScreenDefaultWindowClosed (object o, WindowClosedArgs args)
 
86
                {
 
87
                        UpdateWindowIntersect ();
 
88
                }
 
89
 
 
90
                void HandleGeometryChanged (object sender, EventArgs e)
 
91
                {
 
92
                        Wnck.Window window = sender as Wnck.Window;
 
93
                        
 
94
                        Gdk.Rectangle monitor = LayoutUtils.MonitorGeometry ();
 
95
                        Gdk.Rectangle geo = window.EasyGeometry ();
 
96
                        
 
97
                        geo.X = ((geo.X % monitor.Width) + monitor.Width) % monitor.Width;
 
98
                        geo.Y = ((geo.Y % monitor.Height) + monitor.Height) % monitor.Height;
 
99
                        
 
100
                        if (geo == last_known_geo)
 
101
                                return;
 
102
                        
 
103
                        last_known_geo = geo;
 
104
                        UpdateWindowIntersect ();
 
105
                }
 
106
 
 
107
                void HandleActiveWindowChanged (object o, ActiveWindowChangedArgs args)
 
108
                {
 
109
                        if (args.PreviousWindow != null)
 
110
                                args.PreviousWindow.GeometryChanged -= HandleGeometryChanged;
 
111
                        
 
112
                        SetupActiveWindow ();
 
113
                        UpdateWindowIntersect ();
 
114
                }
 
115
                
 
116
                void SetupActiveWindow ()
 
117
                {
 
118
                        Wnck.Window active = Wnck.Screen.Default.ActiveWindow;
 
119
                        if (active != null) {
 
120
                                active.GeometryChanged += HandleGeometryChanged; 
 
121
                                Gdk.Rectangle geo = active.EasyGeometry ();
 
122
                                Gdk.Rectangle monitor = LayoutUtils.MonitorGeometry ();
 
123
                                geo.X = geo.X % monitor.Width;
 
124
                                geo.Y = geo.Y % monitor.Height;
 
125
                                last_known_geo = geo;
 
126
                        }
 
127
                }
 
128
 
 
129
                public void UpdateWindowIntersect ()
 
130
                {
 
131
                        Gdk.Rectangle adjustedDockArea = parent.MinimumDockArea;
 
132
                        Gdk.Rectangle geo = LayoutUtils.MonitorGeometry ();
 
133
                        
 
134
                        adjustedDockArea.X = geo.X + (geo.Width - adjustedDockArea.Width) / 2;
 
135
                        switch (DockPreferences.Orientation) {
 
136
                        case DockOrientation.Bottom:
 
137
                                adjustedDockArea.Y = geo.Y + geo.Height - adjustedDockArea.Height;
 
138
                                break;
 
139
                        case DockOrientation.Top:
 
140
                                adjustedDockArea.Y = geo.Y;
 
141
                                break;
 
142
                        }
 
143
                                adjustedDockArea.Inflate (-2, -2);
 
144
                        
 
145
                        bool intersect = false;
 
146
                        try {
 
147
                                IEnumerable<Wnck.Window> rawWindows = ScreenUtils.ActiveViewport.UnprocessedWindows ();
 
148
                                
 
149
                                Wnck.Window activeWindow = rawWindows
 
150
                                        .Where (w => w.IsActive && w.WindowType != Wnck.WindowType.Desktop)
 
151
                                        .First ();
 
152
                                
 
153
                                intersect = rawWindows.Any (w => !w.IsMinimized && w.WindowType != Wnck.WindowType.Desktop && 
 
154
                                                            activeWindow.Pid == w.Pid &&
 
155
                                                            w.EasyGeometry ().IntersectsWith (adjustedDockArea));
 
156
                        } catch {
 
157
                        }
 
158
                        
 
159
                        WindowIntersectingOther = intersect;
 
160
                }
 
161
 
 
162
                #region IDisposable implementation
 
163
                public void Dispose ()
 
164
                {
 
165
                        DockPreferences.IconSizeChanged -= HandleIconSizeChanged;
 
166
                        if (Wnck.Screen.Default != null) {
 
167
                                Wnck.Screen.Default.ActiveWindowChanged -= HandleActiveWindowChanged;
 
168
                                Wnck.Screen.Default.WindowClosed -= WnckScreenDefaultWindowClosed;
 
169
                                Wnck.Screen.Default.WindowOpened -= WnckScreenDefaultWindowOpened;
 
170
                                Wnck.Screen.Default.ActiveWindow.GeometryChanged -= HandleGeometryChanged;
 
171
                                Wnck.Screen.Default.ViewportsChanged -= HandleViewportsChanged; 
 
172
                        }
 
173
                }
 
174
                #endregion
 
175
 
 
176
        }
 
177
}