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;
27
using Docky.Utilities;
31
using Do.Platform.Linux;
33
using Do.Interface.Xlib;
34
using Do.Interface.CairoUtils;
35
using Do.Interface.AnimationBase;
37
namespace Docky.Interface
41
public class DockWindow : Gtk.Window, IDoWindow, IConfigurable
43
public static Gtk.Window Window { get; private set; }
45
BezelGlassResults results;
46
BezelGlassWindow results_window;
49
Interface.DoInteropService interop_service;
50
IDoController controller;
51
Gdk.Rectangle current_mask, blur_mask;
55
int buffer_x, buffer_y;
56
int buffer_width, buffer_height;
58
public new string Name {
59
get { return "Docky"; }
62
public IDoController Controller {
63
get { return controller; }
66
public DockWindow () : base (Gtk.WindowType.Toplevel)
71
public void Initialize (IDoController controller)
73
this.controller = controller;
74
controller.Orientation = ControlOrientation.Vertical;
76
interop_service = new DoInteropService (controller);
77
Core.DockServices.RegisterService (interop_service);
79
Core.DockServices.PainterService.RegisterPainter (new Painters.SummonModeRenderer ());
91
SkipTaskbarHint = true;
94
TypeHint = WindowTypeHint.Dock;
96
this.SetCompositeColormap ();
98
dock_area = new DockArea (this);
101
results = new BezelGlassResults (controller, 450, HUDStyle.Classic, new BezelColors (new Cairo.Color (.1, .1, .1, .8)));
102
results.SlideFromBottom = DockPreferences.Orientation == DockOrientation.Bottom;
103
results_window = new BezelGlassWindow (results);
109
void RegisterEvents ()
111
Realized += (o, a) => GdkWindow.SetBackPixmap (null, false);
113
StyleSet += HandleStyleSet;
115
Screen.Default.SizeChanged += HandleSizeChanged;
116
DockPreferences.AllowOverlapChanged += DelaySetStruts;
117
DockPreferences.AutohideChanged += DelaySetStruts;
118
DockPreferences.MonitorChanged += HandleMonitorChanged;
121
void UnregisterEvents ()
123
StyleSet -= HandleStyleSet;
125
Screen.Default.SizeChanged -= HandleSizeChanged;
126
DockPreferences.AllowOverlapChanged -= DelaySetStruts;
127
DockPreferences.AutohideChanged -= DelaySetStruts;
128
DockPreferences.MonitorChanged -= HandleMonitorChanged;
131
GLib.Source.Remove (strut_timer);
134
void HandleSizeChanged (object o, EventArgs args)
136
LayoutUtils.Recalculate ();
141
void HandleMonitorChanged ()
143
// bring us back down to "minimum" size
148
void HandleStyleSet (object o, StyleSetArgs args)
150
if (!IsRealized) return;
152
GdkWindow.SetBackPixmap (null, false);
154
Gdk.Rectangle tmp = current_mask;
155
current_mask = Gdk.Rectangle.Zero;
160
public void SetInputMask (Gdk.Rectangle area)
162
if (!IsRealized || current_mask == area)
166
if (area.Width == 0 || area.Height == 0) {
167
InputShapeCombineMask (null, 0, 0);
171
Gdk.Pixmap pixmap = new Gdk.Pixmap (null, area.Width, area.Height, 1);
172
Context cr = Gdk.CairoHelper.Create (pixmap);
174
cr.Color = new Cairo.Color (0, 0, 0, 1);
177
InputShapeCombineMask (pixmap, area.X, area.Y);
179
(cr as IDisposable).Dispose ();
183
protected override bool OnButtonReleaseEvent (Gdk.EventButton evnt)
186
GetSize (out rect.Width, out rect.Height);
187
GetPosition (out rect.X, out rect.Y);
189
if (!rect.Contains ((int) evnt.XRoot, (int) evnt.YRoot)) {
190
dock_area.ProxyButtonReleaseEvent (evnt);
193
return base.OnButtonReleaseEvent (evnt);
196
protected override bool OnConfigureEvent (Gdk.EventConfigure evnt)
200
return base.OnConfigureEvent (evnt);
204
protected override bool OnKeyPressEvent (Gdk.EventKey evnt)
206
if (Visible || dock_area.PainterOverlayVisible)
207
KeyPressEvent (evnt);
208
return base.OnKeyPressEvent (evnt);
212
protected override void OnShown ()
220
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
222
buffer_width = allocation.Width;
223
buffer_height = allocation.Height;
225
base.OnSizeAllocated (allocation);
229
public void Reposition ()
231
Gdk.Rectangle geo, main, res;
233
GetSize (out main.Width, out main.Height);
234
results_window.GetSize (out res.Width, out res.Height);
235
geo = LayoutUtils.MonitorGeometry ();
237
switch (DockPreferences.Orientation) {
238
case DockOrientation.Bottom:
239
Move ((geo.X + geo.Width / 2) - main.Width / 2, geo.Y + geo.Height - main.Height);
240
results_window.Move ((geo.X + geo.Width / 2) - res.Width / 2, geo.Y + geo.Height - dock_area.DockHeight - res.Height);
242
case DockOrientation.Top:
244
results_window.Move ((geo.X + geo.Width / 2) - res.Width / 2, geo.Y + dock_area.DockHeight);
248
results.SlideFromBottom = DockPreferences.Orientation == DockOrientation.Bottom;
251
public void GetBufferedPosition (out int x, out int y)
253
if (buffer_x == 0 && buffer_y == 0)
254
GetPosition (out buffer_x, out buffer_y);
259
public void GetBufferedSize (out int width, out int height)
261
if (buffer_width == 0 && buffer_height == 0)
262
GetSize (out buffer_width, out buffer_height);
263
width = buffer_width;
264
height = buffer_height;
267
public void DelaySetStruts ()
272
strut_timer = GLib.Timeout.Add (250, SetStruts);
275
public bool SetStruts ()
277
X11Atoms atoms = X11Atoms.Instance;
279
IntPtr [] struts = dock_area.StrutRequest.Select (i => (IntPtr) i).ToArray ();
280
IntPtr [] first_struts = new [] { struts [0], struts [1], struts [2], struts [3] };
286
Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT_PARTIAL, atoms.XA_CARDINAL,
287
(int) PropertyMode.PropModeReplace, struts);
289
Xlib.XChangeProperty (GdkWindow, atoms._NET_WM_STRUT, atoms.XA_CARDINAL,
290
(int) PropertyMode.PropModeReplace, first_struts);
295
public void SetBackgroundBlur (Gdk.Rectangle area)
297
if (!IsRealized || blur_mask == area)
302
int WindowHeight = dock_area.Height;
303
X11Atoms atoms = X11Atoms.Instance;
305
IntPtr [] data = new IntPtr [8];
307
// this is meant to tell the blur-plugin what and how to blur, somehow
308
// the y-coords are interpreted as being CenterGravity, I wonder why
310
data [0] = (IntPtr) 2; // threshold
311
data [1] = (IntPtr) 0; // filter
312
data [2] = (IntPtr) XGravity.NorthWestGravity; // gravity of top-left
313
data [3] = (IntPtr) area.X; // x-coord of top-left
314
data [4] = (IntPtr) (WindowHeight / 2 - area.Height); // y-coord of top-left
315
data [5] = (IntPtr) XGravity.NorthWestGravity; // gravity of bottom-right
316
data [6] = (IntPtr) (area.X + area.Width); // bottom-right x-coord
317
data [7] = (IntPtr) (WindowHeight / 2); // bottom-right y-coord
319
Xlib.XChangeProperty (GdkWindow, atoms._COMPIZ_WM_WINDOW_BLUR, atoms.XA_INTEGER, (int) PropertyMode.PropModeReplace, data);
322
public void PresentWindow ()
325
Windowing.PresentWindow (this);
330
public void UnpresentWindow ()
333
Windowing.UnpresentWindow (this);
338
#region IDoWindow implementation
340
public new event DoEventKeyDelegate KeyPressEvent;
342
public void Summon ()
345
results_window.Show ();
348
interop_service.SignalSummon ();
351
public void Vanish ()
355
results_window.Hide ();
356
interop_service.SignalVanish ();
361
DockState.Instance.Clear ();
363
interop_service.SignalReset ();
368
DockState.Instance.ThirdPaneVisible = true;
371
public void Shrink ()
373
DockState.Instance.ThirdPaneVisible = false;
376
public void GrowResults ()
379
interop_service.SignalResultsGrow ();
382
public void ShrinkResults ()
385
interop_service.SignalResultsShrink ();
389
public void SetPaneContext (Pane pane, IUIContext context)
391
DockState.Instance.SetContext (context, pane);
392
if (CurrentPane == pane) {
393
results.Context = context;
397
public void ClearPane (Pane pane)
399
DockState.Instance.ClearPane (pane);
402
public new bool Visible {
406
public Pane CurrentPane {
407
get { return DockState.Instance.CurrentPane; }
408
set { DockState.Instance.CurrentPane = value; }
411
public bool ResultsCanHide {
415
public override void Dispose ()
421
dock_area.Dispose ();
422
dock_area.Destroy ();
425
Core.DockServices.Clean ();
434
#region IConfigurable implementation
435
public Bin GetConfiguration ()
437
return new DockyConfigurationWidget ();
440
public string Description {
442
return "Docky configuration";
446
public new string Icon {