File gnome-do-plugins-wink.patch of Package gnome-do-plugins

=== modified file 'WindowManager/Makefile.am'
--- WindowManager/Makefile.am	2009-06-22 04:05:16 +0000
+++ WindowManager/Makefile.am	2010-03-08 02:43:56 +0000
@@ -1,4 +1,6 @@
+if HAVE_WNCK
 include $(top_srcdir)/build.rules.mk
+endif
 
 ASSEMBLY=WindowManager
 
@@ -22,7 +24,17 @@
 	src/WindowActions/WindowFocusAction.cs \
 	src/WindowActions/WindowMaximizeAction.cs \
 	src/WindowActions/WindowMinimizeAction.cs \
-	src/WindowActions/WindowMoveAction.cs
+	src/WindowActions/WindowMoveAction.cs \
+	src/Wink/ScreenUtils.cs \
+	src/Wink/WindowControl.cs \
+	src/Wink/WnckWindow_Extensions.cs \
+	src/Wink/Position.cs \
+	src/Wink/Viewport.cs \
+	src/Wink/WindowUtils.cs \
+	src/Xlib/X11Atoms.cs \
+	src/Xlib/Xlib.cs      
+
+
 
 
 RESOURCES = \
@@ -31,10 +43,10 @@
 REFERENCES = \
 	System \
 	System.Core \
+	Mono.Posix \
 	$(WNCK_SHARP_10_LIBS) \
 	$(GTK_SHARP_20_LIBS) \
 	$(GLIB_SHARP_20_LIBS) \
 	$(GNOME_DESKTOP_SHARP_20_LIBS) \
 	$(DO_PLATFORM_LIBS) \
-	$(DO_UNIVERSE_LIBS) \
-	$(DO_INTERFACE_WINK_LIBS)
+	$(DO_UNIVERSE_LIBS)

=== modified file 'WindowManager/src/CurrentApplicationItem.cs'
--- WindowManager/src/CurrentApplicationItem.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/CurrentApplicationItem.cs	2009-10-11 20:48:44 +0000
@@ -23,7 +23,7 @@
 using Mono.Addins;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {	

=== modified file 'WindowManager/src/CurrentWindowItem.cs'
--- WindowManager/src/CurrentWindowItem.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/CurrentWindowItem.cs	2009-10-11 20:48:44 +0000
@@ -23,7 +23,7 @@
 using Mono.Addins;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {	

=== modified file 'WindowManager/src/IWindowList.cs'
--- WindowManager/src/IWindowList.cs	2009-03-30 00:03:03 +0000
+++ WindowManager/src/IWindowList.cs	2009-10-11 20:48:44 +0000
@@ -25,7 +25,7 @@
 using Wnck;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {

=== modified file 'WindowManager/src/Screen/CurrentScreenItem.cs'
--- WindowManager/src/Screen/CurrentScreenItem.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/CurrentScreenItem.cs	2009-10-11 20:48:44 +0000
@@ -23,7 +23,7 @@
 using Mono.Addins;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {
@@ -65,4 +65,4 @@
 			}
 		}
 	}
-}
\ No newline at end of file
+}

=== modified file 'WindowManager/src/Screen/ScreenActionAction.cs'
--- WindowManager/src/Screen/ScreenActionAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenActionAction.cs	2009-10-11 20:48:44 +0000
@@ -22,7 +22,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/Screen/ScreenCascadeAction.cs'
--- WindowManager/src/Screen/ScreenCascadeAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenCascadeAction.cs	2009-10-11 20:48:44 +0000
@@ -22,7 +22,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/Screen/ScreenItem.cs'
--- WindowManager/src/Screen/ScreenItem.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenItem.cs	2009-10-11 20:48:44 +0000
@@ -23,7 +23,7 @@
 using Mono.Addins;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {

=== modified file 'WindowManager/src/Screen/ScreenItemSource.cs'
--- WindowManager/src/Screen/ScreenItemSource.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenItemSource.cs	2009-10-11 20:48:44 +0000
@@ -24,7 +24,7 @@
 using System.Collections.Generic;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 using Wnck;
 using Mono.Addins;
 

=== modified file 'WindowManager/src/Screen/ScreenRestoreAction.cs'
--- WindowManager/src/Screen/ScreenRestoreAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenRestoreAction.cs	2009-10-11 20:48:44 +0000
@@ -27,7 +27,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/Screen/ScreenSwapAction.cs'
--- WindowManager/src/Screen/ScreenSwapAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenSwapAction.cs	2009-10-11 20:48:44 +0000
@@ -22,7 +22,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/Screen/ScreenTileAction.cs'
--- WindowManager/src/Screen/ScreenTileAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/Screen/ScreenTileAction.cs	2009-10-11 20:48:44 +0000
@@ -22,7 +22,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowActionAction.cs'
--- WindowManager/src/WindowActions/WindowActionAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowActions/WindowActionAction.cs	2009-10-11 20:48:44 +0000
@@ -27,7 +27,7 @@
 using System.Threading;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowCloseAction.cs'
--- WindowManager/src/WindowActions/WindowCloseAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowActions/WindowCloseAction.cs	2009-10-11 20:48:44 +0000
@@ -20,7 +20,7 @@
 using System.Linq;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowFocusAction.cs'
--- WindowManager/src/WindowActions/WindowFocusAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowActions/WindowFocusAction.cs	2009-10-11 20:48:44 +0000
@@ -20,7 +20,7 @@
 using System.Linq;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowMaximizeAction.cs'
--- WindowManager/src/WindowActions/WindowMaximizeAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowActions/WindowMaximizeAction.cs	2009-10-11 20:48:44 +0000
@@ -20,7 +20,7 @@
 using System.Linq;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowMinimizeAction.cs'
--- WindowManager/src/WindowActions/WindowMinimizeAction.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowActions/WindowMinimizeAction.cs	2009-10-11 20:48:44 +0000
@@ -20,7 +20,7 @@
 using System.Linq;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== modified file 'WindowManager/src/WindowActions/WindowMoveAction.cs'
--- WindowManager/src/WindowActions/WindowMoveAction.cs	2009-04-04 04:53:33 +0000
+++ WindowManager/src/WindowActions/WindowMoveAction.cs	2009-10-11 20:48:44 +0000
@@ -23,7 +23,7 @@
 
 using Do.Platform;
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {

=== modified file 'WindowManager/src/WindowItem.cs'
--- WindowManager/src/WindowItem.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowItem.cs	2009-10-11 20:48:44 +0000
@@ -28,7 +28,7 @@
 using Mono.Addins;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 namespace WindowManager
 {	

=== modified file 'WindowManager/src/WindowItemSource.cs'
--- WindowManager/src/WindowItemSource.cs	2009-06-22 04:05:16 +0000
+++ WindowManager/src/WindowItemSource.cs	2009-10-11 20:48:44 +0000
@@ -25,7 +25,7 @@
 using System.Linq;
 
 using Do.Universe;
-using Do.Interface.Wink;
+using WindowManager.Wink;
 
 using Wnck;
 using Mono.Addins;

=== added directory 'WindowManager/src/Wink'
=== added file 'WindowManager/src/Wink/Position.cs'
--- WindowManager/src/Wink/Position.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/Position.cs	2009-10-11 20:48:44 +0000
@@ -0,0 +1,30 @@
+//  
+//  Copyright (C) 2009 GNOME Do
+// 
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
+
+using System;
+
+namespace WindowManager.Wink
+{
+	
+	
+	public enum Position {
+		Left = 0,
+		Right,
+		Top,
+		Bottom,
+	}
+}

=== added file 'WindowManager/src/Wink/ScreenUtils.cs'
--- WindowManager/src/Wink/ScreenUtils.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/ScreenUtils.cs	2009-10-11 20:48:44 +0000
@@ -0,0 +1,160 @@
+//  
+//  Copyright (C) 2009 GNOME Do
+// 
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Mono.Unix;
+
+using Wnck;
+
+namespace WindowManager.Wink
+{
+	
+	
+	public static class ScreenUtils
+	{
+		static bool initialized;
+		static string ViewportFormatString = Catalog.GetString ("Desktop") + " {0}";
+		static Dictionary<Workspace, Viewport [,]> layouts;
+		
+		public static event EventHandler ViewportsChanged;
+		
+		public static Viewport ActiveViewport {
+			get {
+				Workspace wsp = Wnck.Screen.Default.ActiveWorkspace;
+				Gdk.Rectangle geo = new Gdk.Rectangle (wsp.ViewportX, wsp.ViewportY, wsp.Screen.Width, wsp.Screen.Height);
+				if (Viewports.Any (vp => vp.IsActive))
+					return Viewports.First (vp => vp.IsActive);
+				return null;
+			}
+		}
+		
+		public static IEnumerable<Viewport> Viewports {
+			get { 
+				foreach (Viewport [,] layout in layouts.Values) {
+					foreach (Viewport viewport in layout)
+						yield return viewport;
+				}
+			}
+		}
+		
+		public static void Initialize ()
+		{
+			if (initialized)
+				return;
+			
+			initialized = true;
+			Wnck.Global.ClientType = Wnck.ClientType.Pager;
+			
+			Wnck.Screen.Default.ViewportsChanged += HandleViewportsChanged;
+			Wnck.Screen.Default.WorkspaceCreated += HandleWorkspaceCreated;
+			Wnck.Screen.Default.WorkspaceDestroyed += HandleWorkspaceDestroyed;
+			
+			UpdateViewports ();
+		}
+		
+		static void HandleWorkspaceDestroyed(object o, WorkspaceDestroyedArgs args)
+		{
+			UpdateViewports ();
+		}
+
+		static void HandleWorkspaceCreated(object o, WorkspaceCreatedArgs args)
+		{
+			UpdateViewports ();
+		}
+
+		static void HandleViewportsChanged(object sender, EventArgs e)
+		{
+			UpdateViewports ();
+		}
+		
+		public static bool DesktopShown (Screen screen)
+		{
+			return screen.ShowingDesktop;
+		}
+		
+		public static void ShowDesktop (Screen screen)
+		{
+			if (!screen.ShowingDesktop)
+				screen.ToggleShowingDesktop (true);
+		}
+		
+		public static void UnshowDesktop (Screen screen)
+		{
+			if (screen.ShowingDesktop)
+				screen.ToggleShowingDesktop (false);
+		}
+		
+		public static Viewport [,] ViewportLayout ()
+		{
+			return ViewportLayout (Wnck.Screen.Default.ActiveWorkspace);
+		}
+		
+		public static Viewport [,] ViewportLayout (Workspace workspace)
+		{
+			if (!layouts.ContainsKey (workspace))
+				return new Viewport [0,0];
+			
+			return layouts [workspace];
+		}
+		
+		static void UpdateViewports ()
+		{
+			layouts = new Dictionary<Workspace, Viewport [,]> ();
+
+			int currentViewport = 1;
+			foreach (Wnck.Workspace workspace in Wnck.Screen.Default.Workspaces) {
+				
+				if (workspace.IsVirtual) {
+					int viewportWidth;
+					int viewportHeight;
+					viewportWidth = workspace.Screen.Width;
+					viewportHeight = workspace.Screen.Height;
+					
+					int rows = workspace.Height / viewportHeight;
+					int columns = workspace.Width / viewportWidth;
+					
+					layouts [workspace] = new Viewport [rows, columns];
+					
+					for (int i = 0; i < rows; i++) {
+						for (int j = 0; j < columns; j++) {
+							Gdk.Rectangle area = new Gdk.Rectangle (j * viewportWidth,
+							                                        i * viewportHeight,
+							                                        viewportWidth,
+							                                        viewportHeight);
+							layouts [workspace] [i, j] = new Viewport (string.Format (ViewportFormatString, currentViewport),
+							                                           area,
+							                                           workspace);
+							currentViewport++;
+						}
+					}
+				} else {
+					layouts [workspace] = new Viewport [1,1];
+					Viewport viewport = new Viewport (string.Format (ViewportFormatString, currentViewport),
+					                                  new Gdk.Rectangle (0, 0, workspace.Width, workspace.Height),
+					                                  workspace);
+					layouts [workspace] [0,0] = viewport;
+					currentViewport++;
+				}
+			}
+			if (ViewportsChanged != null)
+				ViewportsChanged (new object (), EventArgs.Empty);
+		}
+	}
+}

=== added file 'WindowManager/src/Wink/Viewport.cs'
--- WindowManager/src/Wink/Viewport.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/Viewport.cs	2009-10-11 21:50:55 +0000
@@ -0,0 +1,280 @@
+//  
+//  Copyright (C) 2009 GNOME Do
+// 
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Linq;
+
+
+using Gdk;
+using Wnck;
+
+using Do.Platform;
+using WindowManager.Xlib;
+
+namespace WindowManager.Wink
+{
+	public class Viewport
+	{
+		static Dictionary<Wnck.Window, WindowState> window_states = new Dictionary<Wnck.Window, WindowState> ();
+		
+		private class WindowState {
+			public Gdk.Rectangle Area;
+			public Wnck.WindowState State;
+			
+			public WindowState (Gdk.Rectangle area, Wnck.WindowState state)
+			{
+				Area = area;
+				State = state;
+			}
+		}
+		
+		Workspace parent;
+		Rectangle area;
+		
+		public string Name { get; private set; }
+		
+		public Rectangle Area {
+			get { return area; }
+		}
+		
+		public bool IsActive {
+			get {
+				if (!parent.IsVirtual)
+					return Wnck.Screen.Default.ActiveWorkspace == parent;
+				else
+					return Wnck.Screen.Default.ActiveWorkspace.ViewportX == area.X && Wnck.Screen.Default.ActiveWorkspace.ViewportY == area.Y;
+			}
+		}
+		
+		WindowMoveResizeMask MoveMask {
+			get {
+				return WindowMoveResizeMask.X | WindowMoveResizeMask.Y;
+			}
+		}
+		
+		WindowMoveResizeMask ResizeMask {
+			get {
+				return WindowMoveResizeMask.Width | WindowMoveResizeMask.Height;
+			}
+		}
+		
+		WindowMoveResizeMask MoveResizeMask {
+			get {
+				return WindowMoveResizeMask.X |
+					   WindowMoveResizeMask.Y |
+					   WindowMoveResizeMask.Height |
+					   WindowMoveResizeMask.Width;
+			}
+		}
+		
+		internal Viewport(string name, Rectangle area, Workspace parent)
+		{
+			this.area = area;
+			this.parent = parent;
+			Name = name;
+		}
+		
+		public void Present ()
+		{
+			parent.Screen.MoveViewport (area.X, area.Y);
+		}
+		
+		public bool Contains (Gdk.Point point)
+		{
+			return area.Contains (point);
+		}
+		
+		private IEnumerable<Wnck.Window> RawWindows ()
+		{
+			foreach (Wnck.Window window in WindowUtils.GetWindows ()) {
+				if (WindowCenterInViewport (window) || window.IsSticky)
+					yield return window;
+			}
+		}
+		
+		public IEnumerable<Wnck.Window> Windows ()
+		{
+			return RawWindows ().Where (w => !w.IsSkipTasklist && w.WindowType != Wnck.WindowType.Dock);
+		}
+		
+		public IEnumerable<Wnck.Window> UnprocessedWindows ()
+		{
+			return RawWindows ().Where (w => w.WindowType != Wnck.WindowType.Dock);
+		}
+		
+		public void MoveWindowInto (Wnck.Window window)
+		{
+			if (parent.IsVirtual) {
+				Rectangle geo = window.EasyGeometry ();
+				
+				geo.X += window.Workspace.ViewportX;
+				geo.Y += window.Workspace.ViewportY;
+				
+				int x = area.X + (geo.X % area.Width);
+				int y = area.Y + (geo.Y % area.Height);
+				
+				x -= window.Workspace.ViewportX;
+				y -= window.Workspace.ViewportY;
+				
+				window.SetWorkaroundGeometry (WindowGravity.Current, MoveMask, x, y, 0, 0);
+			} else {
+				window.MoveToWorkspace (parent);
+			}
+		}
+		
+		bool WindowCenterInViewport (Wnck.Window window)
+		{
+			if (!window.IsOnWorkspace (parent))
+				return false;
+				
+			Rectangle geo = window.EasyGeometry ();
+			geo.X += parent.ViewportX;
+			geo.Y += parent.ViewportY;
+			
+			Point center = new Point (geo.X + geo.Width / 2, geo.Y + geo.Height / 2);
+			return Contains (center);
+		}
+		
+		public void RestoreLayout ()
+		{
+			foreach (Wnck.Window window in Windows ())
+				RestoreTemporaryWindowGeometry (window);
+		}
+		
+		public void Cascade ()
+		{
+			IEnumerable<Wnck.Window> windows = Windows ().Where (w => !w.IsMinimized);
+			if (windows.Count () <= 1) return;
+			
+			Gdk.Rectangle screenGeo = GetScreenGeoMinusStruts ();
+			
+			int titleBarSize = windows.First ().FrameExtents () [(int) Position.Top];
+			int windowHeight = screenGeo.Height - ((windows.Count () - 1) * titleBarSize);
+			int windowWidth = screenGeo.Width - ((windows.Count () - 1) * titleBarSize);
+			
+			int count = 0;
+			int x, y;
+			foreach (Wnck.Window window in windows) {
+				x = screenGeo.X + titleBarSize * count - parent.ViewportX;
+				y = screenGeo.Y + titleBarSize * count - parent.ViewportY;
+				
+				SetTemporaryWindowGeometry (window, new Gdk.Rectangle (x, y, windowWidth, windowHeight));
+				count++;
+			}
+		}
+		
+		public void ShowDesktop ()
+		{
+			if (!ScreenUtils.DesktopShown (parent.Screen))
+				ScreenUtils.ShowDesktop (parent.Screen);
+			else
+				ScreenUtils.UnshowDesktop (parent.Screen);
+		}
+		
+		public void Tile ()
+		{
+			IEnumerable<Wnck.Window> windows = Windows ().Where (w => !w.IsMinimized);
+			if (windows.Count () <= 1) return;
+			
+			Gdk.Rectangle screenGeo = GetScreenGeoMinusStruts ();
+			
+			int width, height;
+			//We are going to tile to a square, so what we want is to find
+			//the smallest perfect square all our windows will fit into
+			width = (int) Math.Ceiling (Math.Sqrt (windows.Count ()));
+			
+			//Our height is at least one (e.g. a 2x1)
+			height = 1;
+			while (width * height < windows.Count ())
+				height++;
+			
+			int windowWidth, windowHeight;
+			windowWidth = screenGeo.Width / width;
+			windowHeight = screenGeo.Height / height;
+			
+			int row = 0, column = 0;
+			int x, y;
+			
+			foreach (Wnck.Window window in windows) {
+				x = screenGeo.X + (column * windowWidth) - parent.ViewportX;
+				y = screenGeo.Y + (row * windowHeight) - parent.ViewportY;
+				
+				Gdk.Rectangle windowArea = new Gdk.Rectangle (x, y, windowWidth, windowHeight);;
+				
+				if (window == windows.Last ())
+					windowArea.Width *= width - column;
+				
+				SetTemporaryWindowGeometry (window, windowArea);
+				
+				column++;
+				if (column == width) {
+					column = 0;
+					row++;
+				}
+			}
+		}
+		
+		Gdk.Rectangle GetScreenGeoMinusStruts ()
+		{
+			IEnumerable<int []> struts = RawWindows ()
+				.Where (w => w.WindowType == Wnck.WindowType.Dock)
+				.Select (w => w.GetCardinalProperty (X11Atoms.Instance._NET_WM_STRUT_PARTIAL));
+			
+			int [] offsets = new int [4];
+			for (int i = 0; i < 4; i++)
+				offsets [i] = struts.Max (a => a[i]);
+			
+			Gdk.Rectangle screenGeo = Area;
+			screenGeo.Width -= offsets [(int) Position.Left] + offsets [(int) Position.Right];
+			screenGeo.Height -= offsets [(int) Position.Top] + offsets [(int) Position.Bottom];
+			screenGeo.X += offsets [(int) Position.Left];
+			screenGeo.Y += offsets [(int) Position.Top];
+			
+			return screenGeo;
+		}
+		
+		void SetTemporaryWindowGeometry (Wnck.Window window, Gdk.Rectangle area)
+		{
+			Gdk.Rectangle oldGeo = window.EasyGeometry ();
+			
+			oldGeo.X += parent.ViewportX;
+			oldGeo.Y += parent.ViewportY;
+			
+			if (!window_states.ContainsKey (window)) 
+				window_states [window] = new WindowState (oldGeo, window.State);
+			
+			if (window.IsMaximized)
+				window.Unmaximize ();
+			
+			window.SetWorkaroundGeometry (WindowGravity.Current, MoveResizeMask, area.X, area.Y, area.Width, area.Height);
+		}
+		
+		void RestoreTemporaryWindowGeometry (Wnck.Window window)
+		{
+			if (!window_states.ContainsKey (window))
+				return;
+				
+			WindowState state = window_states [window];
+			window.SetWorkaroundGeometry (WindowGravity.Current, MoveResizeMask, state.Area.X - parent.ViewportX, 
+			                              state.Area.Y - parent.ViewportY, state.Area.Width, state.Area.Height);
+			
+			window_states.Remove (window);
+		}
+	}
+}

=== added file 'WindowManager/src/Wink/WindowControl.cs'
--- WindowManager/src/Wink/WindowControl.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/WindowControl.cs	2009-10-11 21:50:55 +0000
@@ -0,0 +1,173 @@
+// WindowControl.cs
+// 
+// Copyright (C) 2008 GNOME Do
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Wnck;
+
+namespace WindowManager.Wink
+{
+	
+	
+	public static class WindowControl
+	{
+		
+		const int SleepTime = 10;
+		const int FocusDelay = 200;
+		
+		static WindowControl ()
+		{
+			Wnck.Global.ClientType = Wnck.ClientType.Pager;
+		}
+		
+		/// <summary>
+		/// Handles intelligent minimize/restoring of windows.  If one or more windows is minimized, it restores
+		/// all windows.  If more all are visible, it minimizes.  This operation only takes into account windows
+		/// on the current workspace (by design).
+		/// </summary>
+		/// <param name="windows">
+		/// A <see cref="IEnumerable"/>
+		/// </param>
+		public static void MinimizeRestoreWindows (IEnumerable<Window> windows)
+		{
+			bool restore = false;
+			foreach (Window w in windows) {
+				if (w.IsMinimized) {
+					restore = true;
+					break;
+				}
+			}
+			if (restore)
+				RestoreWindows (windows);
+			else
+				MinimizeWindows (windows);
+		}
+		
+		/// <summary>
+		/// Minimizes every window in the list if it is not minimized
+		/// </summary>
+		/// <param name="windows">
+		/// A <see cref="IEnumerable"/>
+		/// </param>
+		public static void MinimizeWindows (IEnumerable<Window> windows)
+		{
+			foreach (Window window in windows) {
+				if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
+					window.Minimize ();
+					System.Threading.Thread.Sleep (SleepTime);
+				}
+			}
+		}
+		
+		/// <summary>
+		/// Restores every window in the list that is minimized
+		/// </summary>
+		/// <param name="windows">
+		/// A <see cref="IEnumerable"/>
+		/// </param>
+		public static void RestoreWindows (IEnumerable<Window> windows)
+		{
+			foreach (Window window in windows.Reverse ()) {
+				if (window.IsInViewport (window.Screen.ActiveWorkspace) && window.IsMinimized) {
+					window.Unminimize (Gtk.Global.CurrentEventTime);
+					System.Threading.Thread.Sleep (SleepTime);
+				}
+			}
+		}
+		
+		public static void FocusWindows (IEnumerable<Window> windows)
+		{
+			if (!windows.Any ())
+				return;
+			
+			if (windows.Any (w => w.IsInViewport (w.Screen.ActiveWorkspace))) {
+				foreach (Window window in windows.Reverse ()) {
+					if (window.IsInViewport (window.Screen.ActiveWorkspace) && !window.IsMinimized) {
+						window.CenterAndFocusWindow ();
+						System.Threading.Thread.Sleep (SleepTime);
+					}
+				}
+			} else {
+				windows.First ().CenterAndFocusWindow ();
+			}
+			
+			if (windows.Count () <= 1)
+				return;
+			
+			// we do this to make sure our active window is also at the front... Its a tricky thing to do.
+			// sometimes compiz plays badly.  This hacks around it
+			uint time = Gtk.Global.CurrentEventTime + FocusDelay;
+			GLib.Timeout.Add (FocusDelay, delegate {
+				try { //unimportant if this fails, its just "nice"
+					windows.Where (w => w.IsInViewport (w.Screen.ActiveWorkspace) && !w.IsMinimized).First ().Activate (time);
+				} catch { }
+				return false;
+			});
+		}
+		
+		public static void FocusWindows (Window window)
+		{
+			FocusWindows (new [] {window});
+		}
+		
+		public static void CloseWindows (IEnumerable<Window> windows)
+		{
+			foreach (Window window in windows.Where (w => !w.IsSkipTasklist))
+				window.Close (Gtk.Global.CurrentEventTime);
+		}
+		
+		public static void CloseWindows (Window window)
+		{
+			CloseWindows (new [] {window});
+		}
+		
+		public static void MinimizeRestoreWindows (Window window)
+		{
+			MinimizeRestoreWindows (new [] {window});
+		}
+		
+		public static void MaximizeWindow (Window window)
+		{
+			window.Maximize ();
+		}
+		
+		/// <summary>
+		/// Moves the current viewport to the selected window and then raises it
+		/// </summary>
+		/// <param name="w">
+		/// A <see cref="Window"/>
+		/// </param>
+		public static void CenterAndFocusWindow (this Window w) 
+		{
+			if (w == null)
+				return;
+
+			uint time = Gtk.Global.CurrentEventTime;
+			if (w.Workspace != null && w.Workspace != w.Screen.ActiveWorkspace) 
+				w.Workspace.Activate (time);
+			
+			
+			if (w.IsMinimized) 
+				w.Unminimize (time);
+			
+			w.ActivateTransient (time);
+		}
+	}
+}

=== added file 'WindowManager/src/Wink/WindowUtils.cs'
--- WindowManager/src/Wink/WindowUtils.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/WindowUtils.cs	2009-10-11 21:50:55 +0000
@@ -0,0 +1,402 @@
+// WindowUtils.cs
+// 
+// Copyright (C) 2008 GNOME Do
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+using Do.Platform;
+
+using Wnck;
+
+namespace WindowManager.Wink
+{
+	
+	public static class WindowUtils
+	{
+		enum OpenOfficeProducts {
+			Writer,
+			Calc,
+			Base,
+			Math,
+			Impress,
+		}
+		
+		static bool initialized;
+		
+		static string RemapFile {
+			get { return Path.Combine (Services.Paths.UserDataDirectory, "RemapFile"); }
+		}
+		
+		static IEnumerable<string> PrefixStrings {
+			get {
+				yield return "gksu";
+				yield return "sudo";
+				yield return "java";
+				yield return "mono";
+				yield return "ruby";
+				yield return "padsp";
+				yield return "aoss";
+				yield return "python(\\d.\\d)?";
+				yield return "(ba)?sh";
+			}
+		}
+		
+		public static IEnumerable<Regex> BadPrefixes { get; private set; }
+		
+		static Dictionary<string, string> RemapDictionary { get; set; }
+		
+		static List<Window> window_list;
+		static bool window_list_update_needed;
+		
+		static Dictionary<int, string> exec_lines = new Dictionary<int, string> ();
+		static DateTime last_update = new DateTime (0);
+		
+		#region ctor
+		public static void Initialize ()
+		{
+			if (initialized)
+				return;
+			
+			initialized = true;
+			Wnck.Global.ClientType = Wnck.ClientType.Pager;
+			
+			List<Regex> regex = new List<Regex> ();
+			foreach (string s in PrefixStrings) {
+				 regex.Add (new Regex (string.Format ("^{0}$", s), RegexOptions.IgnoreCase));
+			}
+			
+			BadPrefixes = regex.AsEnumerable ();
+			
+			Wnck.Screen.Default.WindowClosed += delegate {
+				window_list_update_needed = true;
+			};
+			
+			Wnck.Screen.Default.WindowOpened += delegate {
+				window_list_update_needed = true;
+			};
+			
+			Wnck.Screen.Default.ApplicationOpened += delegate {
+				window_list_update_needed = true;
+			};
+			
+			Wnck.Screen.Default.ApplicationClosed += delegate {
+				window_list_update_needed = true;
+			};
+			
+			BuildRemapDictionary ();
+		}
+		#endregion
+		
+		#region Private Methods
+		static void BuildRemapDictionary ()
+		{
+			if (!File.Exists (RemapFile)) {
+				RemapDictionary = BuildDefaultRemapDictionary ();
+				
+				try {
+					using (StreamWriter writer = new StreamWriter (RemapFile)) {
+						writer.WriteLine ("# Docky Remap File");
+						writer.WriteLine ("# Add key value pairs following dictionary syntax");
+						writer.WriteLine ("# key, value");
+						writer.WriteLine ("# key, altKey, value");
+						writer.WriteLine ("# Lines starting with # are comments, otherwise # is a valid character");
+						
+						foreach (KeyValuePair<string, string> kvp in RemapDictionary) {
+							writer.WriteLine ("{0}, {1}", kvp.Key, kvp.Value);
+						}
+						writer.Close ();
+					}
+				} catch {
+				}
+			} else {
+				RemapDictionary = new Dictionary<string, string> ();
+				
+				try {
+					using (StreamReader reader = new StreamReader (RemapFile)) {
+						string line;
+						while (!reader.EndOfStream) {
+							line = reader.ReadLine ();
+							if (line.StartsWith ("#") || !line.Contains (","))
+								continue;
+							string [] array = line.Split (',');
+							if (array.Length < 2 || array [0].Length == 0)
+								continue;
+							
+							string val = array [array.Length - 1].Trim ().ToLower ();
+							if (string.IsNullOrEmpty (val))
+								continue;
+							
+							for (int i=0; i < array.Length - 1; i++) {
+								string key = array [i].Trim ().ToLower ();
+								if (string.IsNullOrEmpty (key))
+									continue;
+								RemapDictionary [key] = val;
+							}
+						}
+						
+						reader.Close ();
+					}
+				} catch {
+					Log.Error ("Could not read remap file");
+					RemapDictionary = BuildDefaultRemapDictionary ();
+				}
+			}
+		}
+		
+		static Dictionary<string, string> BuildDefaultRemapDictionary ()
+		{
+			Dictionary<string, string> remapDict = new Dictionary<string, string> ();
+			remapDict ["banshee.exe"] = "banshee";
+			remapDict ["banshee-1"] = "banshee";
+			remapDict ["azureus"] = "vuze";
+			remapDict ["thunderbird-3.0"] = "thunderbird";
+			remapDict ["thunderbird-bin"] = "thunderbird";
+			
+			return remapDict;
+		}
+		
+		static void UpdateExecList ()
+		{
+			if ((DateTime.UtcNow - last_update).TotalMilliseconds < 200) return;
+			
+			Dictionary<int, string> old = exec_lines;
+			
+			exec_lines = new Dictionary<int, string> ();
+			
+			foreach (string dir in Directory.GetDirectories ("/proc")) {
+				int pid;
+				try { pid = Convert.ToInt32 (Path.GetFileName (dir)); } 
+				catch { continue; }
+				
+				if (old.ContainsKey (pid)) {
+					exec_lines [pid] = old [pid];
+					continue;
+				}
+				
+				string exec_line = CmdLineForPid (pid);
+				if (string.IsNullOrEmpty (exec_line))
+					continue;
+				
+				if (exec_line.Contains ("java") && exec_line.Contains ("jar")) {
+					foreach (Window window in GetWindows ()) {
+						if (window == null)
+							continue;
+						
+						if (window.Pid == pid || window.Application.Pid == pid) {
+							exec_line = window.ClassGroup.ResClass;
+								
+							// Vuze is retarded
+							if (exec_line == "SWT")
+								exec_line = window.Name;
+						}
+					}
+				}	
+				
+				exec_line = ProcessExecString (exec_line);
+					
+				exec_lines [pid] = exec_line;
+			}
+			
+			last_update = DateTime.UtcNow;
+		}
+		#endregion
+		
+		#region Public Methods
+		/// <summary>
+		/// Returns a list of all windows on the default screen
+		/// </summary>
+		/// <returns>
+		/// A <see cref="List"/>
+		/// </returns>
+		public static List<Window> GetWindows ()
+		{
+			if (window_list == null || window_list_update_needed)
+				window_list = new List<Window> (Wnck.Screen.Default.WindowsStacked);
+			
+			return window_list;
+		}
+		
+		/// <summary>
+		/// Gets the command line excec string for a PID
+		/// </summary>
+		/// <param name="pid">
+		/// A <see cref="System.Int32"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		public static string CmdLineForPid (int pid)
+		{
+			string cmdline = null;
+			
+			try {
+				string procPath = new [] { "/proc", pid.ToString (), "cmdline" }.Aggregate (Path.Combine);
+				using (StreamReader reader = new StreamReader (procPath)) {
+					cmdline = reader.ReadLine ();
+					reader.Close ();
+				}
+			} catch { }
+			
+			return cmdline;
+		}
+		
+		public static List<Window> WindowListForCmd (string exec)
+		{
+			List<Window> windows = new List<Window> ();
+			if (string.IsNullOrEmpty (exec))
+				return windows;
+			
+			// open office hakk
+			if (exec.Contains ("ooffice")) {
+				return GetOpenOfficeWindows (exec);
+			}
+			
+			exec = ProcessExecString (exec);
+			if (string.IsNullOrEmpty (exec))
+				return windows;
+			
+			UpdateExecList ();
+			
+			foreach (KeyValuePair<int, string> kvp in exec_lines) {
+				if (!string.IsNullOrEmpty (kvp.Value) && kvp.Value.Contains (exec)) {
+					// we have a matching exec, now we just find every window whose PID matches this exec
+					foreach (Window window in GetWindows ()) {
+						if (window == null)
+							continue;
+						
+						// this window matches the right PID and exec string, we can match it.
+						bool pidMatch = window.Pid == kvp.Key || 
+							(window.Application != null && window.Application.Pid == kvp.Key);
+						
+						if (pidMatch)
+							windows.Add (window);
+					}
+				}
+			}
+			
+			return windows.Distinct ().ToList ();
+		}
+		
+		static List<Window> GetOpenOfficeWindows (string exec)
+		{
+			if (exec.Contains ("writer")) {
+				return GetWindows ().Where ((Wnck.Window w) => w.Name.Contains ("OpenOffice.org Writer")).ToList ();
+			} else if (exec.Contains ("math")) {
+				return GetWindows ().Where ((Wnck.Window w) => w.Name.Contains ("OpenOffice.org Math")).ToList ();
+			} else if (exec.Contains ("calc")) {
+				return GetWindows ().Where ((Wnck.Window w) => w.Name.Contains ("OpenOffice.org Calc")).ToList ();
+			} else if (exec.Contains ("impress")) {
+				return GetWindows ().Where ((Wnck.Window w) => w.Name.Contains ("OpenOffice.org Impress")).ToList ();
+			} else if (exec.Contains ("draw")) {
+				return GetWindows ().Where ((Wnck.Window w) => w.Name.Contains ("OpenOffice.org Draw")).ToList ();
+			} else {
+				return new List<Window> (0);
+			}
+		}
+		
+		/// <summary>
+		/// This method takes in an "execution string" from proc and applies a heureustic to try
+		/// to magic out the name of the actual executing application.  The executing binary is not
+		/// the desired target all the time.
+		/// </summary>
+		/// <param name="exec">
+		/// A <see cref="System.String"/>
+		/// </param>
+		/// <returns>
+		/// A <see cref="System.String"/>
+		/// </returns>
+		static string ProcessExecString (string exec)
+		{
+			if (string.IsNullOrEmpty (exec))
+				return exec;
+			
+			// lower it and trim off white space so we can abuse whitespace a bit
+			exec = exec.ToLower ().Trim ();
+			
+			// if the user has specified a specific mapping, we can use that here
+			if (RemapDictionary.ContainsKey (exec))
+				return RemapDictionary [exec];
+			
+			// this is the "split" character or the argument separator.  If the string contains a null
+			// it was fetched from /proc/PID/cmdline and will be nicely split up. Otherwise things get a bit
+			// nasty, and it likely came from a .desktop file.
+			char splitChar = Convert.ToChar (0x0);
+			splitChar = exec.Contains (splitChar) ? splitChar : ' ';
+			
+			// this part is here soley for the remap file so that users may specify to remap based on just the name
+			// without the full path.  If no remap file match is found, the net effect of this is nothing.
+			if (exec.StartsWith ("/")) {
+				string first_part = exec.Split (splitChar) [0];
+				int length = first_part.Length;
+				first_part = first_part.Split ('/').Last ();
+				
+				if (length < exec.Length)
+					 first_part = first_part + " " + exec.Substring (length + 1);
+						
+				if (RemapDictionary.ContainsKey (first_part)) {
+					return RemapDictionary [first_part];
+				}
+			}
+			
+			string [] parts = exec.Split (splitChar);
+			for (int i = 0; i < parts.Length; i++) {
+				// we're going to use this a lot
+				string out_val = parts [i];
+				
+				// arguments are useless
+				if (out_val.StartsWith ("-"))
+					continue;
+				
+				// we want the end of paths
+				if (out_val.Contains ("/"))
+					out_val = out_val.Split ('/').Last ();
+				
+				// wine apps can do it backwards... who knew?
+				if (out_val.Contains ("\\"))
+					out_val = out_val.Split ('\\').Last ();
+				
+				// null out our part if is a bad prefix
+				foreach (Regex regex in BadPrefixes) {
+					if (regex.IsMatch (out_val)) {
+						out_val = null;
+						break;
+					}
+				}
+				
+				// check if it was a bad prefix...
+				if (!string.IsNullOrEmpty (out_val)) {
+					// sometimes we hide things with shell scripts.  This is the most common method of doing it.
+					if (out_val.EndsWith (".real"))
+						out_val = out_val.Substring (0, out_val.Length - ".real".Length);
+					
+					// give the remap dictionary one last shot at this
+					if (RemapDictionary.ContainsKey (out_val))
+						out_val = RemapDictionary [out_val];
+					return out_val;
+				}
+			}
+			return null;
+		}
+		
+		#endregion
+	}
+}

=== added file 'WindowManager/src/Wink/WnckWindow_Extensions.cs'
--- WindowManager/src/Wink/WnckWindow_Extensions.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Wink/WnckWindow_Extensions.cs	2009-10-11 20:48:44 +0000
@@ -0,0 +1,94 @@
+//  
+//  Copyright (C) 2009 GNOME Do
+// 
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+// 
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+// 
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// 
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+using Wnck;
+using WindowManager.Xlib;
+
+namespace WindowManager.Wink
+{
+	
+	
+	public static class WnckWindow_Extensions
+	{
+		public static int Area (this Wnck.Window self)
+		{
+			Gdk.Rectangle geo = self.EasyGeometry ();
+			return geo.Width * geo.Height;
+		}
+		
+		public static Gdk.Rectangle EasyGeometry (this Wnck.Window self)
+		{
+			Gdk.Rectangle geo;
+			self.GetGeometry (out geo.X, out geo.Y, out geo.Width, out geo.Height);
+			return geo;
+		}
+		
+		public static void SetWorkaroundGeometry (this Wnck.Window window, WindowGravity gravity, WindowMoveResizeMask mask, 
+		                                     int x, int y, int width, int height)
+		{
+			// This is very weird.  Don't know when they will fix it. You must subtract the top and left
+			// frame extents from a move operation to get the window to actually show in the right spot.
+			// Save for maybe kwin, I think only compiz uses Viewports anyhow, so this is ok.
+			int [] extents = window.FrameExtents ();
+			
+			x -= extents [(int) Position.Left];
+			y -= extents [(int) Position.Top];
+			
+			window.SetGeometry (gravity, mask, x, y, width, height);
+		}
+		
+		public static int [] FrameExtents (this Wnck.Window window)
+		{
+			return GetCardinalProperty (window, X11Atoms.Instance._NET_FRAME_EXTENTS);
+		}
+		
+		public static int [] GetCardinalProperty (this Wnck.Window window, IntPtr atom)
+		{
+			X11Atoms atoms = X11Atoms.Instance;
+			IntPtr display;
+			IntPtr type;
+			int format;
+			IntPtr prop_return;
+			IntPtr nitems, bytes_after;
+			int result;
+			int [] extents = new int[12];
+			
+			IntPtr window_handle = (IntPtr) window.Xid;
+			
+			display = Xlib.Xlib.GdkDisplayXDisplay (Gdk.Screen.Default.Display);
+			type = IntPtr.Zero;
+			
+			result = Xlib.Xlib.XGetWindowProperty (display, window_handle, atom, (IntPtr) 0,
+			                                  (IntPtr) System.Int32.MaxValue, false, atoms.XA_CARDINAL, out type, out format,
+			                                  out nitems, out bytes_after, out prop_return);
+			
+			if (type == atoms.XA_CARDINAL && format == 32) {
+				extents = new int [(int) nitems];
+				for (int i = 0; i < (int) nitems; i++) {
+					extents [i] = Marshal.ReadInt32 (prop_return, i * IntPtr.Size);
+				}
+			}
+			
+			return extents;
+		}
+	}
+}

=== added directory 'WindowManager/src/Xlib'
=== added file 'WindowManager/src/Xlib/X11Atoms.cs'
--- WindowManager/src/Xlib/X11Atoms.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Xlib/X11Atoms.cs	2009-10-11 20:48:44 +0000
@@ -0,0 +1,336 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
+//
+//
+
+using System;
+
+namespace WindowManager.Xlib {
+
+	public class X11Atoms {
+		
+		static X11Atoms instance;
+		public static X11Atoms Instance {
+			get {
+				if (instance == null)
+					instance = new X11Atoms (Gdk.Screen.Default.Display);
+				return instance;
+			}
+		}
+
+		// Our atoms
+		public readonly IntPtr AnyPropertyType		= (IntPtr)0;
+		public readonly IntPtr XA_PRIMARY		= (IntPtr)1;
+		public readonly IntPtr XA_SECONDARY		= (IntPtr)2;
+		public readonly IntPtr XA_ARC			= (IntPtr)3;
+		public readonly IntPtr XA_ATOM			= (IntPtr)4;
+		public readonly IntPtr XA_BITMAP		= (IntPtr)5;
+		public readonly IntPtr XA_CARDINAL		= (IntPtr)6;
+		public readonly IntPtr XA_COLORMAP		= (IntPtr)7;
+		public readonly IntPtr XA_CURSOR		= (IntPtr)8;
+		public readonly IntPtr XA_CUT_BUFFER0		= (IntPtr)9;
+		public readonly IntPtr XA_CUT_BUFFER1		= (IntPtr)10;
+		public readonly IntPtr XA_CUT_BUFFER2		= (IntPtr)11;
+		public readonly IntPtr XA_CUT_BUFFER3		= (IntPtr)12;
+		public readonly IntPtr XA_CUT_BUFFER4		= (IntPtr)13;
+		public readonly IntPtr XA_CUT_BUFFER5		= (IntPtr)14;
+		public readonly IntPtr XA_CUT_BUFFER6		= (IntPtr)15;
+		public readonly IntPtr XA_CUT_BUFFER7		= (IntPtr)16;
+		public readonly IntPtr XA_DRAWABLE		= (IntPtr)17;
+		public readonly IntPtr XA_FONT			= (IntPtr)18;
+		public readonly IntPtr XA_INTEGER		= (IntPtr)19;
+		public readonly IntPtr XA_PIXMAP		= (IntPtr)20;
+		public readonly IntPtr XA_POINT			= (IntPtr)21;
+		public readonly IntPtr XA_RECTANGLE		= (IntPtr)22;
+		public readonly IntPtr XA_RESOURCE_MANAGER	= (IntPtr)23;
+		public readonly IntPtr XA_RGB_COLOR_MAP		= (IntPtr)24;
+		public readonly IntPtr XA_RGB_BEST_MAP		= (IntPtr)25;
+		public readonly IntPtr XA_RGB_BLUE_MAP		= (IntPtr)26;
+		public readonly IntPtr XA_RGB_DEFAULT_MAP	= (IntPtr)27;
+		public readonly IntPtr XA_RGB_GRAY_MAP		= (IntPtr)28;
+		public readonly IntPtr XA_RGB_GREEN_MAP		= (IntPtr)29;
+		public readonly IntPtr XA_RGB_RED_MAP		= (IntPtr)30;
+		public readonly IntPtr XA_STRING		= (IntPtr)31;
+		public readonly IntPtr XA_VISUALID		= (IntPtr)32;
+		public readonly IntPtr XA_WINDOW		= (IntPtr)33;
+		public readonly IntPtr XA_WM_COMMAND		= (IntPtr)34;
+		public readonly IntPtr XA_WM_HINTS		= (IntPtr)35;
+		public readonly IntPtr XA_WM_CLIENT_MACHINE	= (IntPtr)36;
+		public readonly IntPtr XA_WM_ICON_NAME		= (IntPtr)37;
+		public readonly IntPtr XA_WM_ICON_SIZE		= (IntPtr)38;
+		public readonly IntPtr XA_WM_NAME		= (IntPtr)39;
+		public readonly IntPtr XA_WM_NORMAL_HINTS	= (IntPtr)40;
+		public readonly IntPtr XA_WM_SIZE_HINTS		= (IntPtr)41;
+		public readonly IntPtr XA_WM_ZOOM_HINTS		= (IntPtr)42;
+		public readonly IntPtr XA_MIN_SPACE		= (IntPtr)43;
+		public readonly IntPtr XA_NORM_SPACE		= (IntPtr)44;
+		public readonly IntPtr XA_MAX_SPACE		= (IntPtr)45;
+		public readonly IntPtr XA_END_SPACE		= (IntPtr)46;
+		public readonly IntPtr XA_SUPERSCRIPT_X		= (IntPtr)47;
+		public readonly IntPtr XA_SUPERSCRIPT_Y		= (IntPtr)48;
+		public readonly IntPtr XA_SUBSCRIPT_X		= (IntPtr)49;
+		public readonly IntPtr XA_SUBSCRIPT_Y		= (IntPtr)50;
+		public readonly IntPtr XA_UNDERLINE_POSITION	= (IntPtr)51;
+		public readonly IntPtr XA_UNDERLINE_THICKNESS	= (IntPtr)52;
+		public readonly IntPtr XA_STRIKEOUT_ASCENT	= (IntPtr)53;
+		public readonly IntPtr XA_STRIKEOUT_DESCENT	= (IntPtr)54;
+		public readonly IntPtr XA_ITALIC_ANGLE		= (IntPtr)55;
+		public readonly IntPtr XA_X_HEIGHT		= (IntPtr)56;
+		public readonly IntPtr XA_QUAD_WIDTH		= (IntPtr)57;
+		public readonly IntPtr XA_WEIGHT		= (IntPtr)58;
+		public readonly IntPtr XA_POINT_SIZE		= (IntPtr)59;
+		public readonly IntPtr XA_RESOLUTION		= (IntPtr)60;
+		public readonly IntPtr XA_COPYRIGHT		= (IntPtr)61;
+		public readonly IntPtr XA_NOTICE		= (IntPtr)62;
+		public readonly IntPtr XA_FONT_NAME		= (IntPtr)63;
+		public readonly IntPtr XA_FAMILY_NAME		= (IntPtr)64;
+		public readonly IntPtr XA_FULL_NAME		= (IntPtr)65;
+		public readonly IntPtr XA_CAP_HEIGHT		= (IntPtr)66;
+		public readonly IntPtr XA_WM_CLASS		= (IntPtr)67;
+		public readonly IntPtr XA_WM_TRANSIENT_FOR	= (IntPtr)68;
+
+		public readonly IntPtr WM_PROTOCOLS;
+		public readonly IntPtr WM_DELETE_WINDOW;
+		public readonly IntPtr WM_TAKE_FOCUS;
+		public readonly IntPtr _NET_SUPPORTED;
+		public readonly IntPtr _NET_CLIENT_LIST;
+		public readonly IntPtr _NET_NUMBER_OF_DESKTOPS;
+		public readonly IntPtr _NET_DESKTOP_GEOMETRY;
+		public readonly IntPtr _NET_DESKTOP_VIEWPORT;
+		public readonly IntPtr _NET_CURRENT_DESKTOP;
+		public readonly IntPtr _NET_DESKTOP_NAMES;
+		public readonly IntPtr _NET_ACTIVE_WINDOW;
+		public readonly IntPtr _NET_WORKAREA;
+		public readonly IntPtr _NET_SUPPORTING_WM_CHECK;
+		public readonly IntPtr _NET_VIRTUAL_ROOTS;
+		public readonly IntPtr _NET_DESKTOP_LAYOUT;
+		public readonly IntPtr _NET_SHOWING_DESKTOP;
+		public readonly IntPtr _NET_CLOSE_WINDOW;
+		public readonly IntPtr _NET_MOVERESIZE_WINDOW;
+		public readonly IntPtr _NET_WM_MOVERESIZE;
+		public readonly IntPtr _NET_RESTACK_WINDOW;
+		public readonly IntPtr _NET_REQUEST_FRAME_EXTENTS;
+		public readonly IntPtr _NET_WM_NAME;
+		public readonly IntPtr _NET_WM_VISIBLE_NAME;
+		public readonly IntPtr _NET_WM_ICON_NAME;
+		public readonly IntPtr _NET_WM_VISIBLE_ICON_NAME;
+		public readonly IntPtr _NET_WM_DESKTOP;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE;
+		public readonly IntPtr _NET_WM_STATE;
+		public readonly IntPtr _NET_WM_ALLOWED_ACTIONS;
+		public readonly IntPtr _NET_WM_STRUT;
+		public readonly IntPtr _NET_WM_STRUT_PARTIAL;
+		public readonly IntPtr _NET_WM_ICON_GEOMETRY;
+		public readonly IntPtr _NET_WM_ICON;
+		public readonly IntPtr _NET_WM_PID;
+		public readonly IntPtr _NET_WM_HANDLED_ICONS;
+		public readonly IntPtr _NET_WM_USER_TIME;
+		public readonly IntPtr _NET_FRAME_EXTENTS;
+		public readonly IntPtr _NET_WM_PING;
+		public readonly IntPtr _NET_WM_SYNC_REQUEST;
+		public readonly IntPtr _NET_SYSTEM_TRAY_ORIENTATION;
+		public readonly IntPtr _NET_SYSTEM_TRAY_OPCODE;
+		public readonly IntPtr _NET_WM_STATE_MAXIMIZED_HORZ;
+		public readonly IntPtr _NET_WM_STATE_MAXIMIZED_VERT;
+		public readonly IntPtr _XEMBED;
+		public readonly IntPtr _XEMBED_INFO;
+		public readonly IntPtr _MOTIF_WM_HINTS;
+		public readonly IntPtr _NET_WM_STATE_SKIP_TASKBAR;
+		public readonly IntPtr _NET_WM_STATE_ABOVE;
+		public readonly IntPtr _NET_WM_STATE_MODAL;
+		public readonly IntPtr _NET_WM_STATE_HIDDEN;
+		public readonly IntPtr _NET_WM_CONTEXT_HELP;
+		public readonly IntPtr _NET_WM_WINDOW_OPACITY;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DESKTOP;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DOCK;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_TOOLBAR;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_MENU;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_UTILITY;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_SPLASH;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_DIALOG;
+		public readonly IntPtr _NET_WM_WINDOW_TYPE_NORMAL;
+		public readonly IntPtr _COMPIZ_WM_WINDOW_BLUR;
+		public readonly IntPtr CLIPBOARD;
+		public readonly IntPtr PRIMARY;
+		public readonly IntPtr DIB;
+		public readonly IntPtr OEMTEXT;
+		public readonly IntPtr UNICODETEXT;
+		public readonly IntPtr TARGETS;
+		public readonly IntPtr PostAtom;
+		public readonly IntPtr AsyncAtom;
+
+
+		X11Atoms (Gdk.Display dsp) {
+			IntPtr display = Xlib.GdkDisplayXDisplay (dsp);
+			// make sure this array stays in sync with the statements below
+			string [] atom_names = new string[] {
+				"WM_PROTOCOLS",
+				"WM_DELETE_WINDOW",
+				"WM_TAKE_FOCUS",
+				"_NET_SUPPORTED",
+				"_NET_CLIENT_LIST",
+				"_NET_NUMBER_OF_DESKTOPS",
+				"_NET_DESKTOP_GEOMETRY",
+				"_NET_DESKTOP_VIEWPORT",
+				"_NET_CURRENT_DESKTOP",
+				"_NET_DESKTOP_NAMES",
+				"_NET_ACTIVE_WINDOW",
+				"_NET_WORKAREA",
+				"_NET_SUPPORTING_WM_CHECK",
+				"_NET_VIRTUAL_ROOTS",
+				"_NET_DESKTOP_LAYOUT",
+				"_NET_SHOWING_DESKTOP",
+				"_NET_CLOSE_WINDOW",
+				"_NET_MOVERESIZE_WINDOW",
+				"_NET_WM_MOVERESIZE",
+				"_NET_RESTACK_WINDOW",
+				"_NET_REQUEST_FRAME_EXTENTS",
+				"_NET_WM_NAME",
+				"_NET_WM_VISIBLE_NAME",
+				"_NET_WM_ICON_NAME",
+				"_NET_WM_VISIBLE_ICON_NAME",
+				"_NET_WM_DESKTOP",
+				"_NET_WM_WINDOW_TYPE",
+				"_NET_WM_STATE",
+				"_NET_WM_ALLOWED_ACTIONS",
+				"_NET_WM_STRUT",
+				"_NET_WM_STRUT_PARTIAL",
+				"_NET_WM_ICON_GEOMETRY",
+				"_NET_WM_ICON",
+				"_NET_WM_PID",
+				"_NET_WM_HANDLED_ICONS",
+				"_NET_WM_USER_TIME",
+				"_NET_FRAME_EXTENTS",
+				"_NET_WM_PING",
+				"_NET_WM_SYNC_REQUEST",
+				"_NET_SYSTEM_TRAY_OPCODE",
+				"_NET_SYSTEM_TRAY_ORIENTATION",
+				"_NET_WM_STATE_MAXIMIZED_HORZ",
+				"_NET_WM_STATE_MAXIMIZED_VERT",
+				"_NET_WM_STATE_HIDDEN",
+				"_XEMBED",
+				"_XEMBED_INFO",
+				"_MOTIF_WM_HINTS",
+				"_NET_WM_STATE_SKIP_TASKBAR",
+				"_NET_WM_STATE_ABOVE",
+				"_NET_WM_STATE_MODAL",
+				"_NET_WM_CONTEXT_HELP",
+				"_NET_WM_WINDOW_OPACITY",
+				"_NET_WM_WINDOW_TYPE_DESKTOP",
+				"_NET_WM_WINDOW_TYPE_DOCK",
+				"_NET_WM_WINDOW_TYPE_TOOLBAR",
+				"_NET_WM_WINDOW_TYPE_MENU",
+				"_NET_WM_WINDOW_TYPE_UTILITY",
+				"_NET_WM_WINDOW_TYPE_DIALOG",
+				"_NET_WM_WINDOW_TYPE_SPLASH",
+				"_NET_WM_WINDOW_TYPE_NORMAL",
+				"_COMPIZ_WM_WINDOW_BLUR",
+				"CLIPBOARD",
+				"PRIMARY",
+				"COMPOUND_TEXT",
+				"UTF8_STRING",
+				"TARGETS",
+				"_SWF_AsyncAtom",
+				"_SWF_PostMessageAtom",
+				"_SWF_HoverAtom",
+			};
+
+			IntPtr[] atoms = new IntPtr [atom_names.Length];;
+
+			Xlib.XInternAtoms (display, atom_names, atom_names.Length, false, atoms);
+
+			int off = 0;
+			WM_PROTOCOLS = atoms [off++];
+			WM_DELETE_WINDOW = atoms [off++];
+			WM_TAKE_FOCUS = atoms [off++];
+			_NET_SUPPORTED = atoms [off++];
+			_NET_CLIENT_LIST = atoms [off++];
+			_NET_NUMBER_OF_DESKTOPS = atoms [off++];
+			_NET_DESKTOP_GEOMETRY = atoms [off++];
+			_NET_DESKTOP_VIEWPORT = atoms [off++];
+			_NET_CURRENT_DESKTOP = atoms [off++];
+			_NET_DESKTOP_NAMES = atoms [off++];
+			_NET_ACTIVE_WINDOW = atoms [off++];
+			_NET_WORKAREA = atoms [off++];
+			_NET_SUPPORTING_WM_CHECK = atoms [off++];
+			_NET_VIRTUAL_ROOTS = atoms [off++];
+			_NET_DESKTOP_LAYOUT = atoms [off++];
+			_NET_SHOWING_DESKTOP = atoms [off++];
+			_NET_CLOSE_WINDOW = atoms [off++];
+			_NET_MOVERESIZE_WINDOW = atoms [off++];
+			_NET_WM_MOVERESIZE = atoms [off++];
+			_NET_RESTACK_WINDOW = atoms [off++];
+			_NET_REQUEST_FRAME_EXTENTS = atoms [off++];
+			_NET_WM_NAME = atoms [off++];
+			_NET_WM_VISIBLE_NAME = atoms [off++];
+			_NET_WM_ICON_NAME = atoms [off++];
+			_NET_WM_VISIBLE_ICON_NAME = atoms [off++];
+			_NET_WM_DESKTOP = atoms [off++];
+			_NET_WM_WINDOW_TYPE = atoms [off++];
+			_NET_WM_STATE = atoms [off++];
+			_NET_WM_ALLOWED_ACTIONS = atoms [off++];
+			_NET_WM_STRUT = atoms [off++];
+			_NET_WM_STRUT_PARTIAL = atoms [off++];
+			_NET_WM_ICON_GEOMETRY = atoms [off++];
+			_NET_WM_ICON = atoms [off++];
+			_NET_WM_PID = atoms [off++];
+			_NET_WM_HANDLED_ICONS = atoms [off++];
+			_NET_WM_USER_TIME = atoms [off++];
+			_NET_FRAME_EXTENTS = atoms [off++];
+			_NET_WM_PING = atoms [off++];
+			_NET_WM_SYNC_REQUEST = atoms [off++];
+			_NET_SYSTEM_TRAY_OPCODE = atoms [off++];
+			_NET_SYSTEM_TRAY_ORIENTATION = atoms [off++];
+			_NET_WM_STATE_MAXIMIZED_HORZ = atoms [off++];
+			_NET_WM_STATE_MAXIMIZED_VERT = atoms [off++];
+			_NET_WM_STATE_HIDDEN = atoms [off++];
+			_XEMBED = atoms [off++];
+			_XEMBED_INFO = atoms [off++];
+			_MOTIF_WM_HINTS = atoms [off++];
+			_NET_WM_STATE_SKIP_TASKBAR = atoms [off++];
+			_NET_WM_STATE_ABOVE = atoms [off++];
+			_NET_WM_STATE_MODAL = atoms [off++];
+			_NET_WM_CONTEXT_HELP = atoms [off++];
+			_NET_WM_WINDOW_OPACITY = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DESKTOP = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DOCK = atoms [off++];
+			_NET_WM_WINDOW_TYPE_TOOLBAR = atoms [off++];
+			_NET_WM_WINDOW_TYPE_MENU = atoms [off++];
+			_NET_WM_WINDOW_TYPE_UTILITY = atoms [off++];
+			_NET_WM_WINDOW_TYPE_DIALOG = atoms [off++];
+			_NET_WM_WINDOW_TYPE_SPLASH = atoms [off++];
+			_NET_WM_WINDOW_TYPE_NORMAL = atoms [off++];
+			_COMPIZ_WM_WINDOW_BLUR = atoms [off++];
+			CLIPBOARD = atoms [off++];
+			PRIMARY = atoms [off++];
+			OEMTEXT = atoms [off++];
+			UNICODETEXT = atoms [off++];
+			TARGETS = atoms [off++];
+			AsyncAtom = atoms [off++];
+			PostAtom = atoms [off++];
+
+			DIB = XA_PIXMAP;
+		}
+
+	}
+
+}
+

=== added file 'WindowManager/src/Xlib/Xlib.cs'
--- WindowManager/src/Xlib/Xlib.cs	1970-01-01 00:00:00 +0000
+++ WindowManager/src/Xlib/Xlib.cs	2009-10-11 20:48:44 +0000
@@ -0,0 +1,126 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2006 Novell, Inc. (http://www.novell.com)
+//
+//
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace WindowManager.Xlib {
+
+	public enum PropertyMode
+	{
+		PropModeReplace = 0, 
+		PropModePrepend = 1, 
+		PropModeAppend = 2,
+	}
+	
+	public enum Struts 
+	{
+		Left = 0,
+		Right = 1,
+		Top = 2,
+		Bottom = 3,
+		LeftStart = 4,
+		LeftEnd = 5,
+		RightStart = 6,
+		RightEnd = 7,
+		TopStart = 8,
+		TopEnd = 9,
+		BottomStart = 10,
+		BottomEnd = 11
+	}
+	
+	public enum XGravity
+	{
+		ForgetGravity = 0,
+		NorthWestGravity = 1,
+		NorthGravity = 2,
+		NorthEastGravity = 3,
+		WestGravity = 4,
+		CenterGravity = 5,
+		EastGravity = 6,
+		SouthWestGravity = 7,
+		SouthGravity = 8,
+		SouthEastGravity = 9,
+		StaticGravity = 10,
+	}
+	
+	public static class Xlib {
+		const string libX11 = "X11";
+		const string libGdkX11 = "libgdk-x11";
+		
+		[DllImport (libGdkX11)]
+		static extern IntPtr gdk_x11_drawable_get_xid (IntPtr handle);
+		
+		[DllImport (libGdkX11)]
+		static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr handle);
+		
+		[DllImport (libGdkX11)]
+        static extern IntPtr gdk_x11_display_get_xdisplay (IntPtr display);
+		
+		[DllImport (libGdkX11)]
+		static extern void gdk_x11_window_set_user_time (IntPtr window, uint timestamp);
+
+		[DllImport (libX11)]
+		public extern static IntPtr XOpenDisplay (IntPtr display);
+		
+		[DllImport (libX11)]
+		public extern static int XInternAtoms (IntPtr display, string[] atom_names, int atom_count, bool only_if_exists, IntPtr[] atoms);
+		
+		[DllImport (libX11)]
+		extern static int XChangeProperty (IntPtr display, IntPtr window, IntPtr property, IntPtr type, int format, int mode, IntPtr[] data, int nelements);
+	
+		[DllImport (libX11)]
+		public extern static int XGetWindowProperty (IntPtr display, IntPtr window, IntPtr atom, IntPtr long_offset, 
+		                                             IntPtr long_length, bool delete, IntPtr req_type, out IntPtr actual_type, 
+		                                             out int actual_format, out IntPtr nitems, out IntPtr bytes_after, out IntPtr prop);
+		
+		public static IntPtr GdkWindowX11Xid (Gdk.Window window)
+		{
+			return gdk_x11_drawable_get_xid (window.Handle);
+		}
+
+		public static IntPtr GdkDrawableXDisplay (Gdk.Window window)
+		{
+			return gdk_x11_drawable_get_xdisplay (window.Handle);
+		}
+		
+		public static IntPtr GdkDisplayXDisplay (Gdk.Display display)
+		{
+			return gdk_x11_display_get_xdisplay (display.Handle);
+		}
+		
+		public static int XChangeProperty (Gdk.Window window, IntPtr property, IntPtr type, int mode, IntPtr[] data)
+		{
+			return XChangeProperty (GdkDrawableXDisplay (window), GdkWindowX11Xid (window), property, type, 32, mode, data, data.Length); 
+		}
+		
+		public static void GdkWindowSetUserTime (Gdk.Window window, uint timestamp)
+		{
+			gdk_x11_window_set_user_time (window.Handle, timestamp);
+		}
+
+	}
+}

=== modified file 'configure.ac'
--- configure.ac	2010-02-07 21:56:33 +0000
+++ configure.ac	2010-03-08 02:43:56 +0000
@@ -159,7 +159,7 @@
    	PKG_CHECK_MODULES([GDATA_SHARP_YOUTUBE], [gdata-sharp-youtube], HAVE_YOUTUBE=yes, HAVE_YOUTUBE=no)
 
    	if test "x$enable_youtube" = "xyes" -a "x$HAVE_YOUTUBE" = "no"; then
-   		AC_MSG_ERROR([YouTube support explicitly requested but dependencies no found])
+   		AC_MSG_ERROR([YouTube support explicitly requested but dependencies not found])
 	fi
 fi
 
@@ -168,6 +168,25 @@
 AC_SUBST([GDATA_SHARP_YOUTUBE_LIBS])
 dnl}}}
 
+dnl {{{ check for Wnck libraries
+AC_ARG_ENABLE(wnck,
+	AC_HELP_STRING([--enable-window-manager], [Build plugin to control window (default: auto]),
+	enable_wnck=$enableval,
+	enable_wnck=auto)
+
+if test "x$enable_wnck" != "xno"; then
+   	PKG_CHECK_MODULES([WNCK_SHARP_10], [wnck-sharp-1.0], HAVE_WNCK=yes, HAVE_WNCK=no)
+
+	if test "x$enable_wnck" = "xyes" -a "x$HAVE_WNCK" = "no"; then
+   		AC_MSG_ERROR([Window manager support explicitly requested but dependencies not found])
+	fi
+fi
+
+AM_CONDITIONAL(HAVE_WNCK, test "x$HAVE_WNCK" = "xyes")
+
+AC_SUBST([WNCK_SHARP_10_LIBS])
+dnl}}}
+
 PKG_CHECK_MODULES([GCONF_SHARP_20], [gconf-sharp-2.0])
 PKG_CHECK_MODULES([GLADE_SHARP_20], [glade-sharp-2.0])
 PKG_CHECK_MODULES([GLIB_SHARP_20], [glib-sharp-2.0])
@@ -182,7 +201,7 @@
 PKG_CHECK_MODULES([NDESK_DBUS_10], [ndesk-dbus-1.0])
 PKG_CHECK_MODULES([NDESK_DBUS_GLIB_10], [ndesk-dbus-glib-1.0])
 PKG_CHECK_MODULES([NOTIFY_SHARP], [notify-sharp])
-PKG_CHECK_MODULES([WNCK_SHARP_10], [wnck-sharp-1.0])
+
 
 AC_SUBST([GCONF_SHARP_20_LIBS])
 AC_SUBST([GLADE_SHARP_20_LIBS])
@@ -198,18 +217,15 @@
 AC_SUBST([NDESK_DBUS_10_LIBS])
 AC_SUBST([NDESK_DBUS_GLIB_10_LIBS])
 AC_SUBST([NOTIFY_SHARP_LIBS])
-AC_SUBST([WNCK_SHARP_10_LIBS])
 
 dnl Do core references
 PKG_CHECK_MODULES([DO_PLATFORM], [do.platform >= 0.8])
 PKG_CHECK_MODULES([DO_PLATFORM_LINUX], [do.platform.linux >= 0.8])
 PKG_CHECK_MODULES([DO_UNIVERSE], [do.universe >= 0.8])
-PKG_CHECK_MODULES([DO_INTERFACE_WINK], [do.interface.wink >= 0.8])
 
 AC_SUBST([DO_PLATFORM_LIBS])
 AC_SUBST([DO_PLATFORM_LINUX_LIBS])
 AC_SUBST([DO_UNIVERSE_LIBS])
-AC_SUBST([DO_INTERFACE_WINK_LIBS])
 
 AC_ARG_ENABLE(debug,
 	AC_HELP_STRING([--enable-debug],
@@ -414,6 +430,7 @@
     Google Calendar:   ${HAVE_GCAL}
     Google Contacts:   ${HAVE_GMAIL}
     Google Docs:       ${HAVE_GDOCS}
+    Window Manager:    ${HAVE_WNCK}
     YouTube:           ${HAVE_YOUTUBE}
 
   Build/Development: