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;
25
namespace Do.Interface.Wink
29
public static class WindowControl
32
const int SleepTime = 10;
35
/// Handles intelligent minimize/restoring of windows. If one or more windows is minimized, it restores
36
/// all windows. If more all are visible, it minimizes. This operation only takes into account windows
37
/// on the current workspace (by design).
39
/// <param name="windows">
40
/// A <see cref="IEnumerable"/>
42
public static void MinimizeRestoreWindows (IEnumerable<Window> windows)
45
foreach (Window w in windows) {
52
RestoreWindows (windows);
54
MinimizeWindows (windows);
58
/// Minimizes every window in the list if it is not minimized
60
/// <param name="windows">
61
/// A <see cref="IEnumerable"/>
63
public static void MinimizeWindows (IEnumerable<Window> windows)
65
foreach (Window window in windows) {
66
if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
68
System.Threading.Thread.Sleep (SleepTime);
74
/// Restores every window in the list that is minimized
76
/// <param name="windows">
77
/// A <see cref="IEnumerable"/>
79
public static void RestoreWindows (IEnumerable<Window> windows)
81
foreach (Window window in windows.Reverse ()) {
82
if (window.IsInViewport (window.Screen.ActiveWorkspace) && window.IsMinimized) {
83
window.Unminimize (Gtk.Global.CurrentEventTime);
84
System.Threading.Thread.Sleep (SleepTime);
89
public static void FocusWindows (IEnumerable<Window> windows)
91
foreach (Window window in windows.Reverse ()) {
92
if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
93
window.CenterAndFocusWindow ();
94
System.Threading.Thread.Sleep (SleepTime);
98
if (windows.Count () <= 1)
101
// we do this to make sure our active window is also at the front... Its a tricky thing to do.
102
// sometimes compiz plays badly. This hacks around it
103
uint time = Gtk.Global.CurrentEventTime + 200;
104
GLib.Timeout.Add (200, delegate {
105
windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time);
110
public static void FocusWindows (Window window)
112
FocusWindows (new [] {window});
115
public static void IntelligentFocusOffViewportWindow (Window targetWindow, IEnumerable<Window> additionalWindows)
117
foreach (Window window in additionalWindows.Reverse ()) {
118
if (!window.IsMinimized && WindowsShareViewport (targetWindow, window)) {
119
window.CenterAndFocusWindow ();
120
System.Threading.Thread.Sleep (SleepTime);
124
targetWindow.CenterAndFocusWindow ();
126
if (additionalWindows.Count () <= 1)
129
// we do this to make sure our active window is also at the front... Its a tricky thing to do.
130
// sometimes compiz plays badly. This hacks around it
131
uint time = Gtk.Global.CurrentEventTime + 200;
132
GLib.Timeout.Add (200, delegate {
133
targetWindow.Activate (time);
138
static bool WindowsShareViewport (Wnck.Window first, Wnck.Window second)
140
if (first == null || second == null) return false;
142
Wnck.Workspace wksp = first.Workspace ?? second.Workspace;
143
if (wksp == null) return false;
145
Gdk.Rectangle firstGeo, secondGeo;
147
first.GetGeometry (out firstGeo.X, out firstGeo.Y, out firstGeo.Width, out firstGeo.Height);
148
second.GetGeometry (out secondGeo.X, out secondGeo.Y, out secondGeo.Width, out secondGeo.Height);
150
firstGeo.X += wksp.ViewportX;
151
firstGeo.Y += wksp.ViewportY;
153
secondGeo.X += wksp.ViewportX;
154
secondGeo.Y += wksp.ViewportY;
156
int viewportWidth, viewportHeight;
157
viewportWidth = first.Screen.Width;
158
viewportHeight = first.Screen.Height;
160
int firstViewportX = ((firstGeo.X + firstGeo.Width / 2) / viewportWidth) * viewportWidth;
161
int firstViewportY = ((firstGeo.Y + firstGeo.Height / 2) / viewportHeight) * viewportHeight;
163
Gdk.Rectangle viewpRect = new Gdk.Rectangle (firstViewportX, firstViewportY,
164
viewportWidth, viewportHeight);
166
return viewpRect.IntersectsWith (secondGeo);
169
public static void CloseWindows (IEnumerable<Window> windows)
171
foreach (Window window in windows.Where (w => !w.IsSkipTasklist))
172
window.Close (Gtk.Global.CurrentEventTime);
175
public static void CloseWindows (Window window)
177
CloseWindows (new [] {window});
180
public static void MinimizeRestoreWindows (Window window)
182
MinimizeRestoreWindows (new [] {window});
185
public static void MaximizeWindow (Window window)
191
/// Moves the current viewport to the selected window and then raises it
194
/// A <see cref="Window"/>
196
public static void CenterAndFocusWindow (this Window w)
201
if (!w.IsInViewport (w.Screen.ActiveWorkspace)) {
202
int viewX, viewY, viewW, viewH;
204
Screen scrn = w.Screen;
205
Workspace wsp = scrn.ActiveWorkspace;
207
//get our windows geometry
208
w.GetGeometry (out viewX, out viewY, out viewW, out viewH);
210
//we want to focus on where the middle of the window is
211
midX = viewX + (viewW / 2);
212
midY = viewY + (viewH / 2);
214
//The positions given above are relative to the current viewport
215
//This makes them absolute
216
midX += wsp.ViewportX;
217
midY += wsp.ViewportY;
219
//Check to make sure our middle didn't wrap
220
if (midX > wsp.Width) {
224
if (midY > wsp.Height) {
228
//take care of negative numbers (happens?)
235
scrn.MoveViewport (midX, midY);
238
if (w.Workspace != null && w.Workspace != w.Screen.ActiveWorkspace)
239
w.Workspace.Activate (Gtk.Global.CurrentEventTime);
243
w.Unminimize (Gtk.Global.CurrentEventTime);
245
w.Activate (Gtk.Global.CurrentEventTime);