gnome-shell r152 - in trunk: . js/ui src



Author: walters
Date: Mon Jan 19 23:06:59 2009
New Revision: 152
URL: http://svn.gnome.org/viewvc/gnome-shell?rev=152&view=rev

Log:
Merge branch 'workspace-salon'

Conflicts:
	src/shell-global.c

Added:
   trunk/src/Makefile-taskpanel.am
   trunk/src/gnomeshell-taskpanel.c
   trunk/src/shell-panel-window.c
   trunk/src/shell-panel-window.h
Modified:
   trunk/configure.ac
   trunk/js/ui/main.js
   trunk/js/ui/workspaces.js
   trunk/src/Makefile.am
   trunk/src/shell-global.c
   trunk/src/shell-global.h

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Mon Jan 19 23:06:59 2009
@@ -9,6 +9,8 @@
 
 AC_DISABLE_STATIC
 AC_PROG_CC
+# Needed for per-target cflags, like in gnomeshell-taskpanel
+AM_PROG_CC_C_O
 AM_PROG_LIBTOOL
 
 GETTEXT_PACKAGE=gnome-shell
@@ -16,10 +18,11 @@
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
                    [The prefix for our gettext translation domains.])
 
-PKG_CHECK_MODULES(MUTTER_PLUGIN, gtk+-2.0 metacity-plugins gjs-gi-1.0)
+PKG_CHECK_MODULES(MUTTER_PLUGIN, gtk+-2.0 dbus-glib-1 metacity-plugins gjs-gi-1.0)
 PKG_CHECK_MODULES(TIDY, clutter-0.8)
 PKG_CHECK_MODULES(BIG, clutter-cairo-0.8 gtk+-2.0 librsvg-2.0)
 PKG_CHECK_MODULES(TRAY, gtk+-2.0)
+PKG_CHECK_MODULES(TASKPANEL, libwnck-1.0 dbus-glib-1)
 # We require libgnomeui for generating thumbnails for recent files with GnomeThumbnailFactory.
 # We'll switch to using GnomeDesktopThumbnailFactory once the branch of gnome-desktop that contains
 # it becomes stable.

Modified: trunk/js/ui/main.js
==============================================================================
--- trunk/js/ui/main.js	(original)
+++ trunk/js/ui/main.js	Mon Jan 19 23:06:59 2009
@@ -97,6 +97,9 @@
 
 function start() {
     let global = Shell.Global.get();
+    
+    // Here we grab our DBus name, etc.
+    global.late_init();
 
     Tweener.setFrameTicker(new ClutterFrameTicker());
 

Modified: trunk/js/ui/workspaces.js
==============================================================================
--- trunk/js/ui/workspaces.js	(original)
+++ trunk/js/ui/workspaces.js	Mon Jan 19 23:06:59 2009
@@ -15,6 +15,7 @@
 
 // Windows are slightly translucent in the overlay mode
 const WINDOW_OPACITY = 0.9 * 255;
+const FOCUS_ANIMATION_TIME = 0.15;
 
 const WINDOWCLONE_BG_COLOR = new Clutter.Color();
 WINDOWCLONE_BG_COLOR.from_pixel(0x000000f0);
@@ -78,17 +79,24 @@
         this._windows = [this._desktop];
         for (let i = 0; i < windows.length; i++) {
             if (this._isOverlayWindow(windows[i])) {
-                let clone = this._makeClone(windows[i]);
+                let clone = this._makeClone(windows[i], i);
                 clone.connect("button-press-event",
                               function(clone, event) {
                                   clone.raise_top();
                                   me._activateWindow(clone.realWindow, event.get_time());
                               });
+                clone.connect('enter-event', function (a, e) {
+                    me._cloneEnter(clone, e);
+                });
+                clone.connect('leave-event', function (a, e) {
+                    me._cloneLeave(clone, e);
+                });
                 this.actor.add_actor(clone);
                 this._windows.push(clone);
             }
         }
 
+        this._overlappedMode = !((this._windows.length-1) in POSITIONS);
         this._removeButton = null;
         this._visible = false;
     },
@@ -191,11 +199,7 @@
                                scale_y: scale,
                                time: Overlay.ANIMATION_TIME,
                                opacity: WINDOW_OPACITY,
-                               transition: "easeOutQuad",
-                               onComplete: function () {
-                                   this._addCloneTitle(window);
-                               },
-                               onCompleteScope: this
+                               transition: "easeOutQuad"
                              });
         }
 
@@ -222,7 +226,7 @@
         for (let i = 0; i < this._windows.length; i++) {
             let window = this._windows[i];
             if (window.cloneTitle)
-                window.cloneTitle.destroy();
+                window.cloneTitle.hide();
             Tweener.addTween(window,
                              { x: this.fullSizeX + window.origX,
                                y: this.fullSizeY + window.origY,
@@ -250,6 +254,7 @@
     // Animates grid shrinking/expanding when a row or column
     // of workspaces is added or removed
     resizeToGrid : function (oldScale) {
+        let me = this;
         let rescale = this.scale / oldScale;
 
         for (let i = 0; i < this._windows.length; i++) {
@@ -263,10 +268,12 @@
                                scale_x: newWindowScale,
                                scale_y: newWindowScale,
                                time: Overlay.ANIMATION_TIME,
-                               transition: "easeOutQuad"
+                               transition: "easeOutQuad",
+                               onComplete: function () {
+                                   me._adjustCloneTitle(me._windows[i]);
+                               }
                              });
-            this._adjustCloneTitle(this._windows[i], newX, newY,
-                                   newWindowScale);
+
         }
 
         if (this._removeButton) {
@@ -364,12 +371,15 @@
 
     // Tests if @win should be shown in the overlay
     _isOverlayWindow : function (win) {
-        return win.get_window_type() != Meta.WindowType.DESKTOP &&
-            !win.is_override_redirect();
+        let wintype = win.get_window_type();
+        if (wintype == Meta.WindowType.DESKTOP || 
+            wintype == Meta.WindowType.DOCK)
+            return false;
+        return !win.is_override_redirect();
     },
 
     // Create a clone of a window to use in the overlay.
-    _makeClone : function(window) {
+    _makeClone : function(window, index) {
         let clone = new Clutter.CloneTexture({ parent_texture: window.get_texture(),
                                                reactive: true,
                                                x: window.x,
@@ -377,6 +387,7 @@
         clone.realWindow = window;
         clone.origX = window.x;
         clone.origY = window.y;
+        clone.index = index;
         return clone;
     },
 
@@ -422,47 +433,68 @@
 
         return [xCenter, yCenter, fraction];
     },
+    
+    _cloneEnter: function (clone, event) {
+        if (!clone.cloneTitle)
+            this._createCloneTitle(clone);
+    	clone.cloneTitle.show();            
+        this._adjustCloneTitle(clone)
+    	if (!this._overlappedMode)
+    	    return;
+    	if (clone.index != this._windows.length-1) {
+    	    clone.raise_top();
+    	    clone.cloneTitle.raise(clone);
+    	}
+    },
+    
+    _cloneLeave: function (clone, event) {
+        clone.cloneTitle.hide();
+    	if (!this._overlappedMode)
+    	    return;    	
+    	if (clone.index != this._windows.length-1) {
+    	    clone.lower(this._windows[clone.index+1]);
+    	    clone.cloneTitle.raise(clone);    	    
+    	}
+    },
 
-    _addCloneTitle : function (clone) {
-        let transformed = clone.get_transformed_size();
+    _createCloneTitle : function (clone) {
+        let me = this;
         let window = clone.realWindow;
-        let icon = window.meta_window.mini_icon;
-        let iconTexture = new Clutter.Texture({ width: 16, height: 16, keep_aspect_ratio: true});
-        Shell.clutter_texture_set_from_pixbuf(iconTexture, icon);
+        
         let box = new Big.Box({background_color : WINDOWCLONE_BG_COLOR,
                                y_align: Big.BoxAlignment.CENTER,
                                corner_radius: 5,
                                padding: 4,
                                spacing: 4,
-                               orientation: Big.BoxOrientation.HORIZONTAL});
+                               orientation: Big.BoxOrientation.HORIZONTAL});        
+        
+        let icon = window.meta_window.mini_icon;
+        let iconTexture = new Clutter.Texture({ x: clone.x,
+                                                y: clone.y + clone.height - 16,
+                                                width: 16, height: 16, keep_aspect_ratio: true});
+        Shell.clutter_texture_set_from_pixbuf(iconTexture, icon);
         box.append(iconTexture, Big.BoxPackFlags.NONE);
+        
         let title = new Clutter.Label({color: WINDOWCLONE_TITLE_COLOR,
-                                       font_name: "Sans 14",
+                                       font_name: "Sans 12",
                                        text: window.meta_window.title,
                                        ellipsize: Pango.EllipsizeMode.END});
-        // Get current width (just the icon), with spacing, plus title
-        box.fullWidth = box.width + box.spacing + title.width;
-        box.width = Math.min(box.fullWidth, transformed[0]);
-        box.append(title, Big.BoxPackFlags.EXPAND);
-        box.set_position(clone.x, clone.y);
-        let parent = clone.get_parent();
-        clone.cloneTitle = box;
+        box.append(title, Big.BoxPackFlags.EXPAND);                                       
+        // Get and cache the expected width (just the icon), with spacing, plus title
+        box.fullWidth = box.width;
+        box.hide(); // Hidden by default, show on mouseover
+        clone.cloneTitle = box;        
+        
+        let parent = clone.get_parent();        
         parent.add_actor(box);
     },
 
-    _adjustCloneTitle : function (clone, newX, newY, newScale) {
-        let title = clone.cloneTitle;
-        if (!title)
-            return;
-
-        let newWidth = Math.min(title.fullWidth, clone.width * newScale);
-        Tweener.addTween(title,
-                         { x: newX,
-                           y: newY,
-                           width: newWidth,
-                           time: Overlay.ANIMATION_TIME,
-                           transition: "easeOutQuad"
-                         });
+    _adjustCloneTitle : function (clone) {
+        let transformed = clone.get_transformed_size();
+        let title = clone.cloneTitle;    
+        title.width = Math.min(title.fullWidth, transformed[0]);
+        let xoff = (transformed[0] - title.width)/2;
+        title.set_position(clone.x+xoff, clone.y);
     },
 
     _activateWindow : function(w, time) {

Added: trunk/src/Makefile-taskpanel.am
==============================================================================
--- (empty file)
+++ trunk/src/Makefile-taskpanel.am	Mon Jan 19 23:06:59 2009
@@ -0,0 +1,17 @@
+gnomeshell_taskpanel_CPPFLAGS =					\
+	-I$(top_srcdir)/src			\
+	-DG_DISABLE_DEPRECATED			\
+	-DWNCK_I_KNOW_THIS_IS_UNSTABLE \
+	-DG_LOG_DOMAIN=\"gnomeshell-taskpanel\"	\
+	$(TASKPANEL_CFLAGS)	\
+	$(NULL)
+
+gnomeshell_taskpanel_SOURCES =			\
+	gnomeshell-taskpanel.c  \
+	shell-panel-window.c	\
+	shell-panel-window.h	\
+	$(NULL)
+	
+gnomeshell_taskpanel_LDADD = $(TASKPANEL_LIBS)
+
+bin_PROGRAMS += gnomeshell-taskpanel

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Mon Jan 19 23:06:59 2009
@@ -2,11 +2,13 @@
 BUILT_SOURCES =
 CLEANFILES =
 EXTRA_DIST = 
+bin_PROGRAMS =
 noinst_LTLIBRARIES = 
 
 include Makefile-tidy.am
 include Makefile-big.am
 include Makefile-tray.am
+include Makefile-taskpanel.am
 
 gnome_shell_cflags =				\
 	$(MUTTER_PLUGIN_CFLAGS)			\

Added: trunk/src/gnomeshell-taskpanel.c
==============================================================================
--- (empty file)
+++ trunk/src/gnomeshell-taskpanel.c	Mon Jan 19 23:06:59 2009
@@ -0,0 +1,70 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+#include "shell-panel-window.h"
+#include <libwnck/libwnck.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dbus/dbus-glib.h>
+
+static void
+on_name_owner_changed (DBusGProxy *proxy,
+    const char *name,
+    const char *prev_owner,
+    const char *new_owner,
+    gpointer   user_data)
+{
+  if (strcmp (name, "org.gnome.Shell") == 0 && new_owner[0] == '\0')
+    exit (0);
+}
+
+static void
+monitor_main_shell ()
+{
+  DBusGConnection *session;
+  DBusGProxy *driver;
+  
+  session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+  
+  driver = dbus_g_proxy_new_for_name (session,
+                                      DBUS_SERVICE_DBUS,
+                                      DBUS_PATH_DBUS,
+                                      DBUS_INTERFACE_DBUS);
+
+  dbus_g_proxy_add_signal (driver,
+                           "NameOwnerChanged",
+                           G_TYPE_STRING,
+                           G_TYPE_STRING,
+                           G_TYPE_STRING,
+                           G_TYPE_INVALID);
+  
+  dbus_g_proxy_connect_signal (driver,
+                               "NameOwnerChanged", 
+                               G_CALLBACK (on_name_owner_changed),
+                               NULL,
+                               NULL);  
+}
+
+int 
+main (int argc, char **argv)
+{
+  ShellPanelWindow *panel;
+  WnckScreen *screen;
+  WnckTasklist *tasks;
+  
+  gtk_init (&argc, &argv);
+  
+  monitor_main_shell ();
+  
+  panel = shell_panel_window_new ();
+  
+  screen = wnck_screen_get_default();
+  tasks = WNCK_TASKLIST (wnck_tasklist_new (screen));
+  
+  gtk_container_add (GTK_CONTAINER (panel), GTK_WIDGET (tasks));
+  
+  gtk_widget_show_all (GTK_WIDGET (panel));
+  
+  gtk_main ();
+  
+  exit (0);
+}
\ No newline at end of file

Modified: trunk/src/shell-global.c
==============================================================================
--- trunk/src/shell-global.c	(original)
+++ trunk/src/shell-global.c	Mon Jan 19 23:06:59 2009
@@ -7,8 +7,11 @@
 #include <clutter/x11/clutter-x11.h>
 #include <unistd.h>
 #include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <libgnomeui-2.0/libgnomeui/gnome-thumbnail.h>
+#include <dbus/dbus-glib.h>
 #include <libgnomeui/gnome-thumbnail.h>
 
 struct _ShellGlobal {
@@ -456,3 +459,49 @@
   g_warning ("failed to reexec: %s", g_strerror (errno));
   g_ptr_array_free (arr, TRUE);
 }
+
+/**
+ * shell_global_late_init
+ * 
+ * Perform once-only global initialization; currently this executes
+ * the external tasklist process and grabs the org.gnome.Shell DBus name.
+ */
+void 
+shell_global_late_init (ShellGlobal *global)
+{
+  static gboolean initialized = FALSE;
+  GError *error = NULL;
+  DBusGConnection *session;
+  DBusGProxy *bus;
+  guint32 request_name_result;
+  const char* panel_args[] = {"gnomeshell-taskpanel", NULL};
+  
+  if (initialized)
+    return;
+  initialized = TRUE;
+  
+  session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+  
+  bus = dbus_g_proxy_new_for_name (session,
+                                   DBUS_SERVICE_DBUS,
+                                   DBUS_PATH_DBUS,
+                                   DBUS_INTERFACE_DBUS);
+  
+  if (!dbus_g_proxy_call (bus, "RequestName", &error,
+                          G_TYPE_STRING, "org.gnome.Shell",
+                          G_TYPE_UINT, 0,
+                          G_TYPE_INVALID,
+                          G_TYPE_UINT, &request_name_result,
+                          G_TYPE_INVALID)) {
+    g_print ("failed to acquire org.gnome.Shell: %s\n", error->message);
+    exit (0);  
+  }
+  
+  if (!g_spawn_async (NULL, &panel_args, NULL, G_SPAWN_SEARCH_PATH, NULL,
+                      NULL, NULL, &error)) {
+    g_critical ("failed to execute %s: %s", panel_args[0], error->message);
+    g_clear_error (&error);
+  }
+  
+  g_object_unref (bus);
+}
\ No newline at end of file

Modified: trunk/src/shell-global.h
==============================================================================
--- trunk/src/shell-global.h	(original)
+++ trunk/src/shell-global.h	Mon Jan 19 23:06:59 2009
@@ -38,6 +38,8 @@
 
 ShellGlobal *shell_global_get (void);
 
+void shell_global_late_init (ShellGlobal *global);
+
 void shell_global_set_stage_input_area (ShellGlobal *global,
 					int          x,
 					int          y,

Added: trunk/src/shell-panel-window.c
==============================================================================
--- (empty file)
+++ trunk/src/shell-panel-window.c	Mon Jan 19 23:06:59 2009
@@ -0,0 +1,260 @@
+#include "shell-panel-window.h"
+
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#define PANEL_HEIGHT 25
+
+enum {
+   PROP_0,
+
+};
+
+static void shell_panel_window_dispose (GObject *object);
+static void shell_panel_window_finalize (GObject *object);
+static void shell_panel_window_set_property ( GObject *object,
+                                       guint property_id,
+                                       const GValue *value,
+                                       GParamSpec *pspec );
+static void shell_panel_window_get_property( GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec );
+static void shell_panel_window_size_request (GtkWidget *self, GtkRequisition *req);
+static void shell_panel_window_size_allocate (GtkWidget *self, GtkAllocation *allocation);
+static void shell_panel_window_realize (GtkWidget *self);
+static void shell_panel_window_show (GtkWidget *self);
+static void set_strut (ShellPanelWindow *self);
+static void on_workarea_changed (ShellPanelWindow *self);
+static void handle_new_workarea (ShellPanelWindow *self);
+static GdkFilterReturn filter_func (GdkXEvent *xevent,
+				    GdkEvent *event,
+				    gpointer data);
+
+G_DEFINE_TYPE(ShellPanelWindow, shell_panel_window, GTK_TYPE_WINDOW);
+
+struct ShellPanelWindowPrivate {
+  GtkAllocation workarea;
+  guint width;
+};
+
+static void
+shell_panel_window_class_init(ShellPanelWindowClass *klass)
+{
+    GObjectClass *gobject_class = (GObjectClass *)klass;
+    GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+    gobject_class->dispose = shell_panel_window_dispose;
+    gobject_class->finalize = shell_panel_window_finalize;
+    gobject_class->set_property = shell_panel_window_set_property;
+    gobject_class->get_property = shell_panel_window_get_property;
+
+    widget_class->realize = shell_panel_window_realize;
+    widget_class->size_request = shell_panel_window_size_request;    
+    widget_class->size_allocate = shell_panel_window_size_allocate;
+    widget_class->show = shell_panel_window_show;
+}
+
+static void shell_panel_window_init (ShellPanelWindow *self)
+{
+  self->priv = g_new0 (ShellPanelWindowPrivate, 1);
+
+  gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_DOCK);
+  gtk_window_set_focus_on_map (GTK_WINDOW (self), FALSE);
+  gdk_window_add_filter (NULL, filter_func, self);
+}
+
+static void shell_panel_window_dispose (GObject *object)
+{
+    ShellPanelWindow *self = (ShellPanelWindow*)object;
+
+    G_OBJECT_CLASS (shell_panel_window_parent_class)->dispose(object);
+}
+
+static void shell_panel_window_finalize (GObject *object)
+{
+    ShellPanelWindow *self = (ShellPanelWindow*)object;
+
+    g_free (self->priv);
+    g_signal_handlers_destroy(object);
+    G_OBJECT_CLASS (shell_panel_window_parent_class)->finalize(object);
+}
+
+static void shell_panel_window_set_property ( GObject *object,
+                                         guint property_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec ) 
+{
+   ShellPanelWindow* self = SHELL_PANEL_WINDOW(object);
+    switch (property_id) {
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+
+static void shell_panel_window_get_property ( GObject *object,
+                                         guint property_id,
+                                         GValue *value,
+                                         GParamSpec *pspec ) 
+{
+   ShellPanelWindow* self = SHELL_PANEL_WINDOW(object);
+    switch (property_id) {
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+        break;
+    }
+}
+
+ShellPanelWindow* shell_panel_window_new(void)
+{
+    return (ShellPanelWindow*) g_object_new(SHELL_TYPE_PANEL_WINDOW, 
+        "type", GTK_WINDOW_TOPLEVEL, NULL);
+}
+
+
+static void
+set_strut (ShellPanelWindow *self)
+{
+  long *buf;
+  int x, y;
+  int strut_size;
+
+  strut_size = GTK_WIDGET (self)->allocation.height;
+
+  gtk_window_get_position (GTK_WINDOW (self), &x, &y);
+  
+  buf = g_new0(long, 4);
+  buf[3] = strut_size;
+  gdk_property_change (GTK_WIDGET (self)->window, gdk_atom_intern_static_string ("_NET_WM_STRUT"),
+		       gdk_atom_intern_static_string ("CARDINAL"), 32,
+		       GDK_PROP_MODE_REPLACE,
+		       (guchar*) buf, 4);
+  g_free (buf);
+}
+
+static void
+shell_panel_window_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);  
+  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->size_request(widget, requisition);  
+  requisition->width = self->priv->width;
+  requisition->height = PANEL_HEIGHT; 
+}
+
+static void
+shell_panel_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
+  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->size_allocate(widget, allocation);
+  if (GTK_WIDGET_REALIZED (self))
+    set_strut (self);
+}
+
+static void
+shell_panel_window_realize (GtkWidget *widget)
+{
+  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
+  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->realize(widget);
+  set_strut (self);
+}
+
+static void
+shell_panel_window_show (GtkWidget *widget)
+{
+  ShellPanelWindow *self = SHELL_PANEL_WINDOW (widget);
+  on_workarea_changed (self);
+  GTK_WIDGET_CLASS (shell_panel_window_parent_class)->show(widget);
+}
+
+static void
+handle_new_workarea (ShellPanelWindow *self)
+{
+  int monitor;
+  GtkRequisition requisition;
+  GdkRectangle monitor_geometry;
+  int x, y;
+  int width;
+
+  monitor = gdk_screen_get_monitor_at_point (gdk_screen_get_default (),
+					     self->priv->workarea.x,
+					     self->priv->workarea.y);
+  gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
+				   monitor, &monitor_geometry);
+  gtk_widget_size_request (GTK_WIDGET (self), &requisition);
+
+  x = self->priv->workarea.x;
+  y = monitor_geometry.y + monitor_geometry.height - requisition.height;
+  width = monitor_geometry.width - x;
+
+  self->priv->width = width;
+  gtk_widget_set_size_request (GTK_WIDGET (self), width, PANEL_HEIGHT);
+  gtk_window_move (GTK_WINDOW (self), x, y);
+}
+
+static void
+on_workarea_changed (ShellPanelWindow *self)
+{
+  gulong bytes_after, nitems;
+  Atom type;
+  gint format;
+  guchar *data;
+  long *data32;
+  Atom workarea = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
+
+  XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+		      workarea,
+		      0, 4, FALSE, workarea,
+		      &type, &format, &nitems, &bytes_after, &data);
+  if ((format == 32) && (nitems == 4) && (bytes_after == 0)) {
+    int x, y, width, height;
+    data32 = (long*)data;
+    x = data32[0]; y = data32[1];
+    width = data32[2]; height = data32[3];
+    if (x == self->priv->workarea.x &&
+	y == self->priv->workarea.y &&
+	width == self->priv->workarea.width &&
+	height == self->priv->workarea.height)
+      return;
+
+    self->priv->workarea.x = x;
+    self->priv->workarea.y = y;
+    self->priv->workarea.width = width;
+    self->priv->workarea.height = height;
+
+    handle_new_workarea (self);
+  } else if (nitems == 0) {
+    self->priv->workarea.x = self->priv->workarea.y = 0;
+    self->priv->workarea.width = self->priv->workarea.height = -1;
+    handle_new_workarea (self);
+  } else {
+    g_printerr ("unexpected return from XGetWindowProperty: %d %ld %ld\n",
+		format, nitems, bytes_after);
+  }
+}
+
+static GdkFilterReturn
+filter_func (GdkXEvent *gdk_xevent,
+	     GdkEvent *event,
+	     gpointer data)
+{
+  ShellPanelWindow *self = SHELL_PANEL_WINDOW (data);
+  GdkFilterReturn ret = GDK_FILTER_CONTINUE;
+  XEvent *xevent = (XEvent *) event;
+  Atom workarea = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
+
+  switch (xevent->type) {
+  case PropertyNotify:
+    {
+      if (xevent->xproperty.atom != workarea)
+	break;
+
+      on_workarea_changed (self);
+    }
+    break;
+  default:
+    break;
+  }
+  return ret;
+}

Added: trunk/src/shell-panel-window.h
==============================================================================
--- (empty file)
+++ trunk/src/shell-panel-window.h	Mon Jan 19 23:06:59 2009
@@ -0,0 +1,35 @@
+#ifndef __SHELL_PANEL_WINDOW_H__
+#define __SHELL_PANEL_WINDOW_H__
+
+#include <gtk/gtk.h>
+
+#define SHELL_TYPE_PANEL_WINDOW                 (shell_panel_window_get_type ())
+#define SHELL_PANEL_WINDOW(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindow))
+#define SHELL_PANEL_WINDOW_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindowClass))
+#define SHELL_IS_PANEL_WINDOW(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_PANEL_WINDOW))
+#define SHELL_IS_PANEL_WINDOW_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_PANEL_WINDOW))
+#define SHELL_PANEL_WINDOW_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_PANEL_WINDOW, ShellPanelWindowClass))
+
+typedef struct _ShellPanelWindow ShellPanelWindow;
+typedef struct _ShellPanelWindowClass ShellPanelWindowClass;
+
+typedef struct ShellPanelWindowPrivate ShellPanelWindowPrivate;
+
+struct _ShellPanelWindow
+{
+    GtkWindow parent;
+
+    ShellPanelWindowPrivate *priv;
+};
+
+struct _ShellPanelWindowClass
+{
+    GtkWindowClass parent_class;
+
+};
+
+GType shell_panel_window_get_type (void) G_GNUC_CONST;
+ShellPanelWindow* shell_panel_window_new(void);
+
+
+#endif /* __SHELL_PANEL_WINDOW_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]