Make a ClutterActor subclass that wraps a GtkWindow, and use it for the tray.
In particular, this lets us track the actor's location better; the old code didn't work if the actor was put into a container that got moved around. Part of #568712. svn path=/trunk/; revision=167
This commit is contained in:
parent
c86ce82921
commit
3a84625888
@ -36,6 +36,8 @@ libgnome_shell_la_SOURCES = \
|
||||
gnome-shell-plugin.c \
|
||||
shell-app-monitor.c \
|
||||
shell-app-monitor.h \
|
||||
shell-gtkwindow-actor.c \
|
||||
shell-gtkwindow-actor.h \
|
||||
shell-process.c \
|
||||
shell-process.h \
|
||||
shell-global.c \
|
||||
@ -45,6 +47,11 @@ libgnome_shell_la_SOURCES = \
|
||||
shell-wm.c \
|
||||
shell-wm.h
|
||||
|
||||
# ClutterGLXTexturePixmap is currently not wrapped
|
||||
non_gir_sources = shell-gtkwindow-actor.h
|
||||
libgnome_shell_la_gir_sources = \
|
||||
$(filter-out $(non_gir_sources), $(libgnome_shell_la_SOURCES))
|
||||
|
||||
shell-marshal.h: stamp-shell-marshal.h
|
||||
@true
|
||||
stamp-shell-marshal.h: Makefile shell-marshal.list
|
||||
@ -86,7 +93,7 @@ Shell-0.1.gir: $(metacity) $(G_IR_SCANNER) libgnome-shell.la Makefile
|
||||
--include=Meta-2.25 \
|
||||
--program=metacity \
|
||||
--program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \
|
||||
$(libgnome_shell_la_SOURCES) \
|
||||
$(libgnome_shell_la_gir_sources) \
|
||||
$(libgnome_shell_la_CPPFLAGS) \
|
||||
-o $@
|
||||
CLEANFILES += Shell-1.0.gir
|
||||
|
174
src/shell-gtkwindow-actor.c
Normal file
174
src/shell-gtkwindow-actor.c
Normal file
@ -0,0 +1,174 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include "shell-gtkwindow-actor.h"
|
||||
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_WINDOW
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ShellGtkWindowActor, shell_gtk_window_actor, CLUTTER_GLX_TYPE_TEXTURE_PIXMAP);
|
||||
|
||||
struct _ShellGtkWindowActorPrivate {
|
||||
GtkWidget *window;
|
||||
};
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_WINDOW:
|
||||
wactor->priv->window = g_value_dup_object (value);
|
||||
|
||||
/* Here automatic=FALSE means to use CompositeRedirectManual.
|
||||
* That is, the X server shouldn't draw the window onto the
|
||||
* screen.
|
||||
*/
|
||||
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (wactor),
|
||||
GDK_WINDOW_XWINDOW (wactor->priv->window->window),
|
||||
FALSE);
|
||||
/* Here automatic has a different meaning--whether
|
||||
* ClutterX11TexturePixmap should process damage update and
|
||||
* refresh the pixmap itself.
|
||||
*/
|
||||
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (wactor), TRUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_WINDOW:
|
||||
g_value_set_object (value, wactor->priv->window);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_allocate (ClutterActor *actor,
|
||||
const ClutterActorBox *box,
|
||||
gboolean absolute_origin_changed)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (actor);
|
||||
int wx = 0, wy = 0, x, y, ax, ay;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (shell_gtk_window_actor_parent_class)->
|
||||
allocate (actor, box, absolute_origin_changed);
|
||||
|
||||
/* Find the actor's new coordinates in terms of the stage (which is
|
||||
* priv->window's parent window.
|
||||
*/
|
||||
while (actor)
|
||||
{
|
||||
clutter_actor_get_position (actor, &x, &y);
|
||||
clutter_actor_get_anchor_point (actor, &ax, &ay);
|
||||
|
||||
wx += x - ax;
|
||||
wy += y - ay;
|
||||
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
|
||||
gtk_window_move (GTK_WINDOW (wactor->priv->window), wx, wy);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_show (ClutterActor *actor)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (actor);
|
||||
|
||||
gtk_widget_show (wactor->priv->window);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (shell_gtk_window_actor_parent_class)->show (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_hide (ClutterActor *actor)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (actor);
|
||||
|
||||
gtk_widget_hide (wactor->priv->window);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (shell_gtk_window_actor_parent_class)->hide (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_dispose (GObject *object)
|
||||
{
|
||||
ShellGtkWindowActor *wactor = SHELL_GTK_WINDOW_ACTOR (object);
|
||||
|
||||
if (wactor->priv->window)
|
||||
{
|
||||
gtk_widget_destroy (wactor->priv->window);
|
||||
wactor->priv->window = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (shell_gtk_window_actor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_class_init (ShellGtkWindowActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ShellGtkWindowActorPrivate));
|
||||
|
||||
object_class->get_property = shell_gtk_window_actor_get_property;
|
||||
object_class->set_property = shell_gtk_window_actor_set_property;
|
||||
object_class->dispose = shell_gtk_window_actor_dispose;
|
||||
|
||||
actor_class->allocate = shell_gtk_window_actor_allocate;
|
||||
actor_class->show = shell_gtk_window_actor_show;
|
||||
actor_class->hide = shell_gtk_window_actor_hide;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_WINDOW,
|
||||
g_param_spec_object ("window",
|
||||
"Window",
|
||||
"GtkWindow to wrap",
|
||||
GTK_TYPE_WINDOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
shell_gtk_window_actor_init (ShellGtkWindowActor *actor)
|
||||
{
|
||||
actor->priv = G_TYPE_INSTANCE_GET_PRIVATE (actor, SHELL_TYPE_GTK_WINDOW_ACTOR,
|
||||
ShellGtkWindowActorPrivate);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
shell_gtk_window_actor_new (GtkWidget *window)
|
||||
{
|
||||
return g_object_new (SHELL_TYPE_GTK_WINDOW_ACTOR,
|
||||
"window", window,
|
||||
NULL);
|
||||
}
|
35
src/shell-gtkwindow-actor.h
Normal file
35
src/shell-gtkwindow-actor.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __SHELL_GTK_WINDOW_ACTOR_H__
|
||||
#define __SHELL_GTK_WINDOW_ACTOR_H__
|
||||
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define SHELL_TYPE_GTK_WINDOW_ACTOR (shell_gtk_window_actor_get_type ())
|
||||
#define SHELL_GTK_WINDOW_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_GTK_WINDOW_ACTOR, ShellGtkWindowActor))
|
||||
#define SHELL_GTK_WINDOW_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_GTK_WINDOW_ACTOR, ShellGtkWindowActorClass))
|
||||
#define SHELL_IS_GTK_WINDOW_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_GTK_WINDOW_ACTOR))
|
||||
#define SHELL_IS_GTK_WINDOW_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_GTK_WINDOW_ACTOR))
|
||||
#define SHELL_GTK_WINDOW_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_GTK_WINDOW_ACTOR, ShellGtkWindowActorClass))
|
||||
|
||||
typedef struct _ShellGtkWindowActor ShellGtkWindowActor;
|
||||
typedef struct _ShellGtkWindowActorClass ShellGtkWindowActorClass;
|
||||
|
||||
typedef struct _ShellGtkWindowActorPrivate ShellGtkWindowActorPrivate;
|
||||
|
||||
struct _ShellGtkWindowActor
|
||||
{
|
||||
ClutterGLXTexturePixmap parent;
|
||||
|
||||
ShellGtkWindowActorPrivate *priv;
|
||||
};
|
||||
|
||||
struct _ShellGtkWindowActorClass
|
||||
{
|
||||
ClutterGLXTexturePixmapClass parent_class;
|
||||
|
||||
};
|
||||
|
||||
GType shell_gtk_window_actor_get_type (void) G_GNUC_CONST;
|
||||
ClutterActor *shell_gtk_window_actor_new (GtkWidget *window);
|
||||
|
||||
#endif /* __SHELL_GTK_WINDOW_ACTOR_H__ */
|
@ -1,13 +1,14 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "shell-tray-manager.h"
|
||||
#include "na-tray-manager.h"
|
||||
|
||||
#include "shell-gtkwindow-actor.h"
|
||||
|
||||
struct _ShellTrayManagerPrivate {
|
||||
NaTrayManager *na_manager;
|
||||
ClutterStage *stage;
|
||||
@ -204,30 +205,6 @@ shell_tray_manager_manage_stage (ShellTrayManager *manager,
|
||||
gdk_drawable_get_screen (GDK_DRAWABLE (manager->priv->stage_window)));
|
||||
}
|
||||
|
||||
static void
|
||||
actor_moved (GObject *object, GParamSpec *param, gpointer user_data)
|
||||
{
|
||||
ShellTrayManagerChild *child = user_data;
|
||||
ClutterActor *actor = child->actor;
|
||||
int wx = 0, wy = 0, x, y, ax, ay;
|
||||
|
||||
/* Find the actor's new coordinates in terms of the stage (which is
|
||||
* child->window's parent window.
|
||||
*/
|
||||
while (actor)
|
||||
{
|
||||
clutter_actor_get_position (actor, &x, &y);
|
||||
clutter_actor_get_anchor_point (actor, &ax, &ay);
|
||||
|
||||
wx += x - ax;
|
||||
wy += y - ay;
|
||||
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
|
||||
gtk_window_move (GTK_WINDOW (child->window), wx, wy);
|
||||
}
|
||||
|
||||
static GdkPixmap *
|
||||
create_bg_pixmap (GdkColormap *colormap,
|
||||
ClutterColor *color)
|
||||
@ -291,15 +268,9 @@ na_tray_icon_added (NaTrayManager *na_manager, GtkWidget *socket,
|
||||
gdk_window_reparent (win->window, manager->priv->stage_window, 0, 0);
|
||||
gtk_widget_show_all (win);
|
||||
|
||||
icon = clutter_glx_texture_pixmap_new ();
|
||||
/* Here automatic=FALSE means to use CompositeRedirectManual - that is,
|
||||
* the X server shouldn't draw the window onto the screen */
|
||||
clutter_x11_texture_pixmap_set_window (CLUTTER_X11_TEXTURE_PIXMAP (icon),
|
||||
GDK_WINDOW_XWINDOW (win->window),
|
||||
FALSE);
|
||||
/* Here automatic has a different meaning - whether ClutterX11TexturePixmap
|
||||
* should process damage update and refresh the pixmap itself */
|
||||
clutter_x11_texture_pixmap_set_automatic (CLUTTER_X11_TEXTURE_PIXMAP (icon), TRUE);
|
||||
icon = shell_gtk_window_actor_new (win);
|
||||
|
||||
/* Move to ShellGtkWindowActor? FIXME */
|
||||
clutter_actor_set_size (icon, 24, 24);
|
||||
|
||||
child = g_slice_new (ShellTrayManagerChild);
|
||||
@ -308,11 +279,6 @@ na_tray_icon_added (NaTrayManager *na_manager, GtkWidget *socket,
|
||||
child->actor = g_object_ref (icon);
|
||||
g_hash_table_insert (manager->priv->icons, socket, child);
|
||||
|
||||
g_signal_connect (child->actor, "notify::x",
|
||||
G_CALLBACK (actor_moved), child);
|
||||
g_signal_connect (child->actor, "notify::y",
|
||||
G_CALLBACK (actor_moved), child);
|
||||
|
||||
g_signal_emit (manager,
|
||||
shell_tray_manager_signals[TRAY_ICON_ADDED], 0,
|
||||
icon);
|
||||
|
Loading…
Reference in New Issue
Block a user