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 Docky.Services.Windows
28
public static class WindowControl
31
const int SleepTime = 10;
32
const int FocusDelay = 200;
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)
94
if (windows.Any (w => w.IsInViewport (w.Screen.ActiveWorkspace))) {
95
foreach (Window window in windows.Reverse ()) {
96
if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
97
window.CenterAndFocusWindow ();
98
System.Threading.Thread.Sleep (SleepTime);
102
windows.First ().CenterAndFocusWindow ();
105
if (windows.Count () <= 1)
108
// we do this to make sure our active window is also at the front... Its a tricky thing to do.
109
// sometimes compiz plays badly. This hacks around it
110
uint time = Gtk.Global.CurrentEventTime + FocusDelay;
111
GLib.Timeout.Add (FocusDelay, delegate {
112
try { //unimportant if this fails, its just "nice"
113
windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time);
119
public static void FocusWindows (Window window)
121
FocusWindows (new [] {window});
124
public static void IntelligentFocusOffViewportWindow (Window targetWindow, IEnumerable<Window> additionalWindows)
126
foreach (Window window in additionalWindows.Reverse ()) {
127
if (!window.IsMinimized && WindowsShareViewport (targetWindow, window)) {
128
window.CenterAndFocusWindow ();
129
System.Threading.Thread.Sleep (SleepTime);
133
targetWindow.CenterAndFocusWindow ();
135
if (additionalWindows.Count () <= 1)
138
// we do this to make sure our active window is also at the front... Its a tricky thing to do.
139
// sometimes compiz plays badly. This hacks around it
140
uint time = Gtk.Global.CurrentEventTime + FocusDelay;
141
GLib.Timeout.Add (FocusDelay, delegate {
142
targetWindow.Activate (time);
147
static bool WindowsShareViewport (Wnck.Window first, Wnck.Window second)
149
if (first == null || second == null) return false;
151
Wnck.Workspace wksp = first.Workspace ?? second.Workspace;
152
if (wksp == null) return false;
154
Gdk.Rectangle firstGeo, secondGeo;
156
first.GetGeometry (out firstGeo.X, out firstGeo.Y, out firstGeo.Width, out firstGeo.Height);
157
second.GetGeometry (out secondGeo.X, out secondGeo.Y, out secondGeo.Width, out secondGeo.Height);
159
firstGeo.X += wksp.ViewportX;
160
firstGeo.Y += wksp.ViewportY;
162
secondGeo.X += wksp.ViewportX;
163
secondGeo.Y += wksp.ViewportY;
165
int viewportWidth, viewportHeight;
166
viewportWidth = first.Screen.Width;
167
viewportHeight = first.Screen.Height;
169
int firstViewportX = ((firstGeo.X + firstGeo.Width / 2) / viewportWidth) * viewportWidth;
170
int firstViewportY = ((firstGeo.Y + firstGeo.Height / 2) / viewportHeight) * viewportHeight;
172
Gdk.Rectangle viewpRect = new Gdk.Rectangle (firstViewportX, firstViewportY,
173
viewportWidth, viewportHeight);
175
return viewpRect.IntersectsWith (secondGeo);
178
public static void CloseWindows (IEnumerable<Window> windows)
180
foreach (Window window in windows.Where (w => !w.IsSkipTasklist))
181
window.Close (Gtk.Global.CurrentEventTime);
184
public static void CloseWindows (Window window)
186
CloseWindows (new [] {window});
189
public static void MinimizeRestoreWindows (Window window)
191
MinimizeRestoreWindows (new [] {window});
194
public static void MaximizeWindows (IEnumerable<Window> windows)
196
foreach (Window window in windows)
200
public static void MaximizeWindows (Window window)
205
public static void UnmaximizeWindows (IEnumerable<Window> windows)
207
foreach (Wnck.Window window in windows)
208
UnmaximizeWindows (window);
211
public static void UnmaximizeWindows (Wnck.Window window)
213
if (window.IsMaximized)
214
window.Unmaximize ();
217
public static void MoveToWorkspace (Window window, Workspace workspace)
219
MoveToWorkspace (new [] {window}, workspace);
222
public static void MoveToWorkspace (IEnumerable<Window> windows, Workspace workspace)
224
foreach (Window window in windows.Where (w => w.Workspace != workspace))
225
window.MoveToWorkspace (workspace);
229
/// Moves the current viewport to the selected window and then raises it
232
/// A <see cref="Window"/>
234
public static void CenterAndFocusWindow (this Window w)
239
uint time = Gtk.Global.CurrentEventTime;
240
if (w.Workspace != null && w.Workspace != w.Screen.ActiveWorkspace)
241
w.Workspace.Activate (time);
247
w.ActivateTransient (time);