From a168f6da42bcd7a66803f666b79c2e3134223861 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 22 Dec 2008 21:05:08 +0000 Subject: [PATCH] Convert to gnome-shell-plugin to new plugin style The plugin-gobject branch of Mutter (now merged into our branch) converts plugins to more-standard GObject GTypePlugin, with the plugin itself being a GObject class. gnome-shell-plugin.c: Switch plugin to the new scheme shell-wm.[ch]: Forward effect signals to ShellWM rather than hooking directly into the plugin vtable. default: Remove this (accidentally committed) file svn path=/trunk/; revision=133 --- src/default.c | 740 --------------------------------------- src/gnome-shell-plugin.c | 259 ++++++++------ src/shell-wm.c | 46 +-- src/shell-wm.h | 33 ++ 4 files changed, 198 insertions(+), 880 deletions(-) delete mode 100644 src/default.c diff --git a/src/default.c b/src/default.c deleted file mode 100644 index a459e842a..000000000 --- a/src/default.c +++ /dev/null @@ -1,740 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (c) 2008 Intel Corp. - * - * Author: Tomas Frydrych - * - * 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 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#define MUTTER_BUILDING_PLUGIN 1 -#include "mutter-plugin.h" - -#include -#define _(x) dgettext (GETTEXT_PACKAGE, x) -#define N_(x) x - -#include -#include -#include - -#define DESTROY_TIMEOUT 250 -#define MINIMIZE_TIMEOUT 250 -#define MAXIMIZE_TIMEOUT 250 -#define MAP_TIMEOUT 250 -#define SWITCH_TIMEOUT 500 - -#define ACTOR_DATA_KEY "MCCP-Default-actor-data" -static GQuark actor_data_quark = 0; - -static gboolean do_init (const char *params); -static void minimize (MutterWindow *actor); -static void map (MutterWindow *actor); -static void destroy (MutterWindow *actor); -static void maximize (MutterWindow *actor, - gint x, gint y, gint width, gint height); -static void unmaximize (MutterWindow *actor, - gint x, gint y, gint width, gint height); - -static void switch_workspace (const GList **actors, gint from, gint to, - MetaMotionDirection direction); - -static void kill_effect (MutterWindow *actor, gulong event); - -static gboolean reload (const char *params); - - -/* - * Create the plugin struct; function pointers initialized in - * g_module_check_init(). - */ -MUTTER_DECLARE_PLUGIN(); - -/* - * Plugin private data that we store in the .plugin_private member. - */ -typedef struct _PluginState -{ - ClutterEffectTemplate *destroy_effect; - ClutterEffectTemplate *minimize_effect; - ClutterEffectTemplate *maximize_effect; - ClutterEffectTemplate *map_effect; - ClutterEffectTemplate *switch_workspace_effect; - - /* Valid only when switch_workspace effect is in progress */ - ClutterTimeline *tml_switch_workspace1; - ClutterTimeline *tml_switch_workspace2; - GList **actors; - ClutterActor *desktop1; - ClutterActor *desktop2; - - gboolean debug_mode : 1; -} PluginState; - - -/* - * Per actor private data we attach to each actor. - */ -typedef struct _ActorPrivate -{ - ClutterActor *orig_parent; - - ClutterTimeline *tml_minimize; - ClutterTimeline *tml_maximize; - ClutterTimeline *tml_destroy; - ClutterTimeline *tml_map; - - gboolean is_minimized : 1; - gboolean is_maximized : 1; -} ActorPrivate; - -static PluginState *plugin_state; - -/* - * Actor private data accessor - */ -static void -free_actor_private (gpointer data) -{ - if (G_LIKELY (data != NULL)) - g_slice_free (ActorPrivate, data); -} - -static ActorPrivate * -get_actor_private (MutterWindow *actor) -{ - ActorPrivate *priv = g_object_get_qdata (G_OBJECT (actor), actor_data_quark); - - if (G_UNLIKELY (actor_data_quark == 0)) - actor_data_quark = g_quark_from_static_string (ACTOR_DATA_KEY); - - if (G_UNLIKELY (!priv)) - { - priv = g_slice_new0 (ActorPrivate); - - g_object_set_qdata_full (G_OBJECT (actor), - actor_data_quark, priv, - free_actor_private); - } - - return priv; -} - -static void -on_switch_workspace_effect_complete (ClutterActor *group, gpointer data) -{ - PluginState *state = plugin_state; - GList *l = *((GList**)data); - MutterWindow *actor_for_cb = l->data; - - while (l) - { - ClutterActor *a = l->data; - MutterWindow *mc_window = MUTTER_WINDOW (a); - ActorPrivate *priv = get_actor_private (mc_window); - - if (priv->orig_parent) - { - clutter_actor_reparent (a, priv->orig_parent); - priv->orig_parent = NULL; - } - - l = l->next; - } - - clutter_actor_destroy (state->desktop1); - clutter_actor_destroy (state->desktop2); - - state->actors = NULL; - state->tml_switch_workspace1 = NULL; - state->tml_switch_workspace2 = NULL; - state->desktop1 = NULL; - state->desktop2 = NULL; - - mutter_plugin_effect_completed (mutter_get_plugin(), actor_for_cb, - MUTTER_PLUGIN_SWITCH_WORKSPACE); -} - -static void -switch_workspace (const GList **actors, gint from, gint to, - MetaMotionDirection direction) -{ - MutterPlugin *plugin = mutter_get_plugin(); - PluginState *state = plugin_state; - GList *l; - gint n_workspaces; - ClutterActor *workspace0 = clutter_group_new (); - ClutterActor *workspace1 = clutter_group_new (); - ClutterActor *stage; - int screen_width, screen_height; - - stage = mutter_plugin_get_stage (plugin); - - mutter_plugin_query_screen_size (plugin, - &screen_width, - &screen_height); - clutter_actor_set_anchor_point (workspace1, - screen_width, - screen_height); - clutter_actor_set_position (workspace1, - screen_width, - screen_height); - - clutter_actor_set_scale (workspace1, 0.0, 0.0); - - clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1); - clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0); - - if (from == to) - { - mutter_plugin_effect_completed (mutter_get_plugin(), NULL, - MUTTER_PLUGIN_SWITCH_WORKSPACE); - return; - } - - n_workspaces = g_list_length (plugin->work_areas); - - l = g_list_last (*((GList**) actors)); - - while (l) - { - MutterWindow *mc_window = l->data; - ActorPrivate *priv = get_actor_private (mc_window); - ClutterActor *window = CLUTTER_ACTOR (mc_window); - gint win_workspace; - - win_workspace = mutter_window_get_workspace (mc_window); - - if (win_workspace == to || win_workspace == from) - { - gint x, y; - guint w, h; - - clutter_actor_get_position (window, &x, &y); - clutter_actor_get_size (window, &w, &h); - - priv->orig_parent = clutter_actor_get_parent (window); - - clutter_actor_reparent (window, - win_workspace == to ? workspace1 : workspace0); - clutter_actor_show_all (window); - clutter_actor_raise_top (window); - } - else if (win_workspace < 0) - { - /* Sticky window */ - priv->orig_parent = NULL; - } - else - { - /* Window on some other desktop */ - clutter_actor_hide (window); - priv->orig_parent = NULL; - } - - l = l->prev; - } - - state->actors = (GList **)actors; - state->desktop1 = workspace0; - state->desktop2 = workspace1; - - state->tml_switch_workspace2 = - clutter_effect_scale (state->switch_workspace_effect, - workspace1, 1.0, 1.0, - on_switch_workspace_effect_complete, - (gpointer)actors); - - state->tml_switch_workspace1 = - clutter_effect_scale (state->switch_workspace_effect, - workspace0, 0.0, 0.0, - NULL, NULL); -} - - -/* - * Minimize effect completion callback; this function restores actor state, and - * calls the manager callback function. - */ -static void -on_minimize_effect_complete (ClutterActor *actor, gpointer data) -{ - /* - * Must reverse the effect of the effect; must hide it first to ensure - * that the restoration will not be visible. - */ - ActorPrivate *apriv; - MutterWindow *mc_window = MUTTER_WINDOW (actor); - - apriv = get_actor_private (MUTTER_WINDOW (actor)); - apriv->tml_minimize = NULL; - - clutter_actor_hide (actor); - - /* FIXME - we shouldn't assume the original scale, it should be saved - * at the start of the effect */ - clutter_actor_set_scale (actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_NORTH_WEST); - - /* Now notify the manager that we are done with this effect */ - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_MINIMIZE); -} - -/* - * Simple minimize handler: it applies a scale effect (which must be reversed on - * completion). - */ -static void -minimize (MutterWindow *mc_window) -{ - PluginState *state = plugin_state; - MetaCompWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (mc_window); - - type = mutter_window_get_window_type (mc_window); - - if (type == META_COMP_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (mc_window); - - apriv->is_minimized = TRUE; - - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - apriv->tml_minimize = clutter_effect_scale (state->minimize_effect, - actor, - 0.0, - 0.0, - (ClutterEffectCompleteFunc) - on_minimize_effect_complete, - NULL); - } - else - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_MINIMIZE); -} - -/* - * Minimize effect completion callback; this function restores actor state, and - * calls the manager callback function. - */ -static void -on_maximize_effect_complete (ClutterActor *actor, gpointer data) -{ - /* - * Must reverse the effect of the effect. - */ - MutterWindow *mc_window = MUTTER_WINDOW (actor); - ActorPrivate *apriv = get_actor_private (mc_window); - - apriv->tml_maximize = NULL; - - /* FIXME - don't assume the original scale was 1.0 */ - clutter_actor_set_scale (actor, 1.0, 1.0); - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_NORTH_WEST); - - /* Now notify the manager that we are done with this effect */ - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_MAXIMIZE); -} - -/* - * The Nature of Maximize operation is such that it is difficult to do a visual - * effect that would work well. Scaling, the obvious effect, does not work that - * well, because at the end of the effect we end up with window content bigger - * and differently laid out than in the real window; this is a proof concept. - * - * (Something like a sound would be more appropriate.) - */ -static void -maximize (MutterWindow *mc_window, - gint end_x, gint end_y, gint end_width, gint end_height) -{ - MetaCompWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (mc_window); - - gdouble scale_x = 1.0; - gdouble scale_y = 1.0; - gint anchor_x = 0; - gint anchor_y = 0; - - type = mutter_window_get_window_type (mc_window); - - if (type == META_COMP_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (mc_window); - guint width, height; - gint x, y; - - apriv->is_maximized = TRUE; - - clutter_actor_get_size (actor, &width, &height); - clutter_actor_get_position (actor, &x, &y); - - /* - * Work out the scale and anchor point so that the window is expanding - * smoothly into the target size. - */ - scale_x = (gdouble)end_width / (gdouble) width; - scale_y = (gdouble)end_height / (gdouble) height; - - anchor_x = (gdouble)(x - end_x)*(gdouble)width / - ((gdouble)(end_width - width)); - anchor_y = (gdouble)(y - end_y)*(gdouble)height / - ((gdouble)(end_height - height)); - - clutter_actor_move_anchor_point (actor, anchor_x, anchor_y); - - apriv->tml_maximize = - clutter_effect_scale (plugin_state->maximize_effect, - actor, - scale_x, - scale_y, - (ClutterEffectCompleteFunc) - on_maximize_effect_complete, - NULL); - - return; - } - - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_MAXIMIZE); -} - -/* - * See comments on the maximize() function. - * - * (Just a skeleton code.) - */ -static void -unmaximize (MutterWindow *mc_window, - gint end_x, gint end_y, gint end_width, gint end_height) -{ - MetaCompWindowType type = mutter_window_get_window_type (mc_window); - - if (type == META_COMP_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (mc_window); - - apriv->is_maximized = FALSE; - } - - /* Do this conditionally, if the effect requires completion callback. */ - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_UNMAXIMIZE); -} - -static void -on_map_effect_complete (ClutterActor *actor, gpointer data) -{ - /* - * Must reverse the effect of the effect. - */ - MutterWindow *mc_window = MUTTER_WINDOW (actor); - ActorPrivate *apriv = get_actor_private (mc_window); - - apriv->tml_map = NULL; - - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_NORTH_WEST); - - /* Now notify the manager that we are done with this effect */ - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, MUTTER_PLUGIN_MAP); -} - -/* - * Simple map handler: it applies a scale effect which must be reversed on - * completion). - */ -static void -map (MutterWindow *mc_window) -{ - MetaCompWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (mc_window); - - type = mutter_window_get_window_type (mc_window); - - if (type == META_COMP_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (mc_window); - - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - clutter_actor_set_scale (actor, 0.0, 0.0); - clutter_actor_show (actor); - - apriv->tml_map = clutter_effect_scale (plugin_state->map_effect, - actor, - 1.0, - 1.0, - (ClutterEffectCompleteFunc) - on_map_effect_complete, - NULL); - - apriv->is_minimized = FALSE; - - } - else - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_MAP); -} - -/* - * Destroy effect completion callback; this is a simple effect that requires no - * further action than notifying the manager that the effect is completed. - */ -static void -on_destroy_effect_complete (ClutterActor *actor, gpointer data) -{ - MutterPlugin *plugin = mutter_get_plugin(); - MutterWindow *mc_window = MUTTER_WINDOW (actor); - ActorPrivate *apriv = get_actor_private (mc_window); - - apriv->tml_destroy = NULL; - - mutter_plugin_effect_completed (plugin, mc_window, - MUTTER_PLUGIN_DESTROY); -} - -/* - * Simple TV-out like effect. - */ -static void -destroy (MutterWindow *mc_window) -{ - MetaCompWindowType type; - ClutterActor *actor = CLUTTER_ACTOR (mc_window); - - type = mutter_window_get_window_type (mc_window); - - if (type == META_COMP_WINDOW_NORMAL) - { - ActorPrivate *apriv = get_actor_private (mc_window); - - clutter_actor_move_anchor_point_from_gravity (actor, - CLUTTER_GRAVITY_CENTER); - - apriv->tml_destroy = clutter_effect_scale (plugin_state->destroy_effect, - actor, - 1.0, - 0.0, - (ClutterEffectCompleteFunc) - on_destroy_effect_complete, - NULL); - } - else - mutter_plugin_effect_completed (mutter_get_plugin(), mc_window, - MUTTER_PLUGIN_DESTROY); -} - -static void -kill_effect (MutterWindow *mc_window, gulong event) -{ - ActorPrivate *apriv; - ClutterActor *actor = CLUTTER_ACTOR (mc_window); - - if (event & MUTTER_PLUGIN_SWITCH_WORKSPACE) - { - PluginState *state = plugin_state; - - if (state->tml_switch_workspace1) - { - clutter_timeline_stop (state->tml_switch_workspace1); - clutter_timeline_stop (state->tml_switch_workspace2); - on_switch_workspace_effect_complete (state->desktop1, state->actors); - } - - if (!(event & ~MUTTER_PLUGIN_SWITCH_WORKSPACE)) - { - /* Workspace switch only, nothing more to do */ - return; - } - } - - apriv = get_actor_private (mc_window); - - if ((event & MUTTER_PLUGIN_MINIMIZE) && apriv->tml_minimize) - { - clutter_timeline_stop (apriv->tml_minimize); - on_minimize_effect_complete (actor, NULL); - } - - if ((event & MUTTER_PLUGIN_MAXIMIZE) && apriv->tml_maximize) - { - clutter_timeline_stop (apriv->tml_maximize); - on_maximize_effect_complete (actor, NULL); - } - - if ((event & MUTTER_PLUGIN_MAP) && apriv->tml_map) - { - clutter_timeline_stop (apriv->tml_map); - on_map_effect_complete (actor, NULL); - } - - if ((event & MUTTER_PLUGIN_DESTROY) && apriv->tml_destroy) - { - clutter_timeline_stop (apriv->tml_destroy); - on_destroy_effect_complete (actor, NULL); - } -} - - -const gchar * g_module_check_init (GModule *module); -const gchar * -g_module_check_init (GModule *module) -{ - MutterPlugin *plugin = mutter_get_plugin (); - - /* Human readable name (for use in UI) */ - plugin->name = "Default Effects"; - - /* Plugin load time initialiser */ - plugin->do_init = do_init; - - /* Effect handlers */ - plugin->minimize = minimize; - plugin->destroy = destroy; - plugin->map = map; - plugin->maximize = maximize; - plugin->unmaximize = unmaximize; - plugin->switch_workspace = switch_workspace; - plugin->kill_effect = kill_effect; - - /* The reload handler */ - plugin->reload = reload; - - return NULL; -} - -/* - * Core of the plugin init function, called for initial initialization and - * by the reload() function. Returns TRUE on success. - */ -static gboolean -do_init (const char *params) -{ - guint destroy_timeout = DESTROY_TIMEOUT; - guint minimize_timeout = MINIMIZE_TIMEOUT; - guint maximize_timeout = MAXIMIZE_TIMEOUT; - guint map_timeout = MAP_TIMEOUT; - guint switch_timeout = SWITCH_TIMEOUT; - - plugin_state = g_new0 (PluginState, 1); - - if (params) - { - if (strstr (params, "debug")) - { - g_debug ("%s: Entering debug mode.", mutter_get_plugin()->name); - - plugin_state->debug_mode = TRUE; - - /* - * Double the effect duration to make them easier to observe. - */ - destroy_timeout *= 2; - minimize_timeout *= 2; - maximize_timeout *= 2; - map_timeout *= 2; - switch_timeout *= 2; - } - } - - plugin_state->destroy_effect - = clutter_effect_template_new (clutter_timeline_new_for_duration ( - destroy_timeout), - CLUTTER_ALPHA_SINE_INC); - - - plugin_state->minimize_effect - = clutter_effect_template_new (clutter_timeline_new_for_duration ( - minimize_timeout), - CLUTTER_ALPHA_SINE_INC); - - plugin_state->maximize_effect - = clutter_effect_template_new (clutter_timeline_new_for_duration ( - maximize_timeout), - CLUTTER_ALPHA_SINE_INC); - - plugin_state->map_effect - = clutter_effect_template_new (clutter_timeline_new_for_duration ( - map_timeout), - CLUTTER_ALPHA_SINE_INC); - - plugin_state->switch_workspace_effect - = clutter_effect_template_new (clutter_timeline_new_for_duration ( - switch_timeout), - CLUTTER_ALPHA_SINE_INC); - - return TRUE; -} - -static void -free_plugin_private (PluginState *state) -{ - if (!state) - return; - - g_object_unref (state->destroy_effect); - g_object_unref (state->minimize_effect); - g_object_unref (state->maximize_effect); - g_object_unref (state->switch_workspace_effect); - - g_free (state); -} - -/* - * Called by the plugin manager when we stuff like the command line parameters - * changed. - */ -static gboolean -reload (const char *params) -{ - PluginState *state; - - state = plugin_state; - - if (do_init (params)) - { - /* Success; free the old state */ - free_plugin_private (plugin_state); - return TRUE; - } - else - { - /* Fail -- fall back to the old state. */ - plugin_state = state; - } - - return FALSE; -} - -/* - * GModule unload function -- do any cleanup required. - */ -G_MODULE_EXPORT void g_module_unload (GModule *module); -G_MODULE_EXPORT void -g_module_unload (GModule *module) -{ - free_plugin_private (plugin_state); -} - diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c index 63eebe577..1f2983186 100644 --- a/src/gnome-shell-plugin.c +++ b/src/gnome-shell-plugin.c @@ -40,67 +40,113 @@ #include "display.h" #include "shell-global.h" +#include "shell-wm.h" -static gboolean do_init (const char *params); -static gboolean reload (const char *params); +static void gnome_shell_plugin_constructed (GObject *object); +static void gnome_shell_plugin_dispose (GObject *object); +static void gnome_shell_plugin_finalize (GObject *object); -static gboolean xevent_filter (XEvent *xev); +#ifdef NOT_YET +static void gnome_shell_plugin_minimize (MutterPlugin *plugin, + MutterWindow *actor); +static void gnome_shell_plugin_maximize (MutterPlugin *plugin, + MutterWindow *actor, + gint x, + gint y, + gint width, + gint height); +static void gnome_shell_plugin_unmaximize (MutterPlugin *plugin, + MutterWindow *actor, + gint x, + gint y, + gint width, + gint height); +static void gnome_shell_plugin_map (MutterPlugin *plugin, + MutterWindow *actor); +static void gnome_shell_plugin_destroy (MutterPlugin *plugin, + MutterWindow *actor); +#endif + +static void gnome_shell_plugin_switch_workspace (MutterPlugin *plugin, + const GList **actors, + gint from, + gint to, + MetaMotionDirection direction); +static void gnome_shell_plugin_kill_effect (MutterPlugin *plugin, + MutterWindow *actor, + gulong events); + +static gboolean gnome_shell_plugin_xevent_filter (MutterPlugin *plugin, + XEvent *event); +static const MutterPluginInfo *gnome_shell_plugin_plugin_info (MutterPlugin *plugin); + +#define GNOME_TYPE_SHELL_PLUGIN (gnome_shell_plugin_get_type ()) +#define GNOME_SHELL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPlugin)) +#define GNOME_SHELL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPluginClass)) +#define GNOME_IS_SHELL_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_SHELL_PLUGIN_TYPE)) +#define GNOME_IS_SHELL_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_SHELL_PLUGIN)) +#define GNOME_SHELL_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_SHELL_PLUGIN, GnomeShellPluginClass)) + +typedef struct _GnomeShellPlugin GnomeShellPlugin; +typedef struct _GnomeShellPluginClass GnomeShellPluginClass; + +struct _GnomeShellPlugin +{ + MutterPlugin parent; + + GjsContext *gjs_context; + Atom panel_action; + Atom panel_action_run_dialog; + Atom panel_action_main_menu; +}; + +struct _GnomeShellPluginClass +{ + MutterPluginClass parent_class; +}; /* * Create the plugin struct; function pointers initialized in * g_module_check_init(). */ -MUTTER_DECLARE_PLUGIN(); +MUTTER_PLUGIN_DECLARE(GnomeShellPlugin, gnome_shell_plugin); -/* - * Plugin private data that we store in the .plugin_private member. - */ -typedef struct _PluginState +static void +gnome_shell_plugin_class_init (GnomeShellPluginClass *klass) { - gboolean debug_mode : 1; - GjsContext *gjs_context; - Atom panel_action; - Atom panel_action_run_dialog; - Atom panel_action_main_menu; -} PluginState; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass); + gobject_class->constructed = gnome_shell_plugin_constructed; + gobject_class->dispose = gnome_shell_plugin_dispose; + gobject_class->finalize = gnome_shell_plugin_finalize; -static PluginState *plugin_state; +#ifdef NOT_YET + plugin_class->map = gnome_shell_plugin_map; + plugin_class->minimize = gnome_shell_plugin_minimize; + plugin_class->maximize = gnome_shell_plugin_maximize; + plugin_class->unmaximize = gnome_shell_plugin_unmaximize; + plugin_class->destroy = gnome_shell_plugin_destroy; +#endif -const gchar * g_module_check_init (GModule *module); -const gchar * -g_module_check_init (GModule *module) -{ - MutterPlugin *plugin = mutter_get_plugin (); + plugin_class->switch_workspace = gnome_shell_plugin_switch_workspace; + plugin_class->kill_effect = gnome_shell_plugin_kill_effect; - /* Human readable name (for use in UI) */ - plugin->name = "GNOME Shell"; - - /* Plugin load time initialiser */ - plugin->do_init = do_init; - - /* The reload handler */ - plugin->reload = reload; - - /* Event handling */ - plugin->xevent_filter = xevent_filter; - - /* This will also create the ShellWM, which will set the appropriate - * window management callbacks in plugin. - */ - _shell_global_set_plugin (shell_global_get(), plugin); - - return NULL; + plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter; + plugin_class->plugin_info = gnome_shell_plugin_plugin_info; } -/* - * Core of the plugin init function, called for initial initialization and - * by the reload() function. Returns TRUE on success. - */ -static gboolean -do_init (const char *params) +static void +gnome_shell_plugin_init (GnomeShellPlugin *shell_plugin) { - MutterPlugin *plugin = mutter_get_plugin(); + _shell_global_set_plugin (shell_global_get(), MUTTER_PLUGIN(shell_plugin)); +} + +static void +gnome_shell_plugin_constructed (GObject *object) +{ + MutterPlugin *plugin = MUTTER_PLUGIN (object); + GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (object); MetaScreen *screen; MetaDisplay *display; GError *error = NULL; @@ -111,18 +157,6 @@ do_init (const char *params) screen = mutter_plugin_get_screen (plugin); display = meta_screen_get_display (screen); - plugin_state = g_new0 (PluginState, 1); - - if (params) - { - if (strstr (params, "debug")) - { - g_debug ("%s: Entering debug mode.", mutter_get_plugin()->name); - - plugin_state->debug_mode = TRUE; - } - } - g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR); shell_js = g_getenv("GNOME_SHELL_JS"); @@ -130,17 +164,17 @@ do_init (const char *params) shell_js = JSDIR; search_path = g_strsplit(shell_js, ":", -1); - plugin_state->gjs_context = gjs_context_new_with_search_path(search_path); + shell_plugin->gjs_context = gjs_context_new_with_search_path(search_path); g_strfreev(search_path); - plugin_state->panel_action = XInternAtom (meta_display_get_xdisplay (display), + shell_plugin->panel_action = XInternAtom (meta_display_get_xdisplay (display), "_GNOME_PANEL_ACTION", FALSE); - plugin_state->panel_action_run_dialog = XInternAtom (meta_display_get_xdisplay (display), + shell_plugin->panel_action_run_dialog = XInternAtom (meta_display_get_xdisplay (display), "_GNOME_PANEL_ACTION_RUN_DIALOG", FALSE); - plugin_state->panel_action_main_menu = XInternAtom (meta_display_get_xdisplay (display), + shell_plugin->panel_action_main_menu = XInternAtom (meta_display_get_xdisplay (display), "_GNOME_PANEL_ACTION_MAIN_MENU", FALSE); - if (!gjs_context_eval (plugin_state->gjs_context, + if (!gjs_context_eval (shell_plugin->gjs_context, "const Main = imports.ui.main; Main.start();", -1, "
", @@ -150,54 +184,65 @@ do_init (const char *params) g_warning ("Evaling main.js failed: %s", error->message); g_error_free (error); } - - return TRUE; } static void -free_plugin_private (PluginState *state) +gnome_shell_plugin_dispose (GObject *object) { - if (!state) - return; - - g_free (state); + G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->dispose (object); } -/* - * Called by the plugin manager when we stuff like the command line parameters - * changed. - */ -static gboolean -reload (const char *params) +static void +gnome_shell_plugin_finalize (GObject *object) { - PluginState *state; + G_OBJECT_CLASS(gnome_shell_plugin_parent_class)->finalize (object); +} - state = plugin_state; +static ShellWM * +get_shell_wm (void) +{ + ShellWM *wm; - if (do_init (params)) - { - /* Success; free the old state */ - free_plugin_private (plugin_state); - return TRUE; - } - else - { - /* Fail -- fall back to the old state. */ - plugin_state = state; - } + g_object_get (shell_global_get (), + "window-manager", &wm, + NULL); + /* drop extra ref added by g_object_get */ + g_object_unref (wm); - return FALSE; + return wm; +} + +static void +gnome_shell_plugin_switch_workspace (MutterPlugin *plugin, + const GList **actors, + gint from, + gint to, + MetaMotionDirection direction) +{ + _shell_wm_switch_workspace (get_shell_wm(), + actors, from, to, direction); +} + +static void +gnome_shell_plugin_kill_effect (MutterPlugin *plugin, + MutterWindow *actor, + gulong events) +{ + _shell_wm_kill_effect (get_shell_wm(), + actor, events); } static gboolean -handle_panel_event (XEvent *xev) +handle_panel_event (GnomeShellPlugin *shell_plugin, + XEvent *xev) { + MutterPlugin *plugin = MUTTER_PLUGIN (shell_plugin); MetaScreen *screen; MetaDisplay *display; XClientMessageEvent *xev_client; Window root; - screen = mutter_plugin_get_screen (mutter_get_plugin ()); + screen = mutter_plugin_get_screen (plugin); display = meta_screen_get_display (screen); if (xev->type != ClientMessage) @@ -207,14 +252,14 @@ handle_panel_event (XEvent *xev) xev_client = (XClientMessageEvent*) xev; if (!(xev_client->window == root && - xev_client->message_type == plugin_state->panel_action && + xev_client->message_type == shell_plugin->panel_action && xev_client->format == 32)) return FALSE; - if (xev_client->data.l[0] == plugin_state->panel_action_run_dialog) + if (xev_client->data.l[0] == shell_plugin->panel_action_run_dialog) g_signal_emit_by_name (shell_global_get (), "panel-run-dialog", (guint32) xev_client->data.l[1]); - else if (xev_client->data.l[0] == plugin_state->panel_action_main_menu) + else if (xev_client->data.l[0] == shell_plugin->panel_action_main_menu) g_signal_emit_by_name (shell_global_get (), "panel-main-menu", (guint32) xev_client->data.l[1]); @@ -222,20 +267,26 @@ handle_panel_event (XEvent *xev) } static gboolean -xevent_filter (XEvent *xev) +gnome_shell_plugin_xevent_filter (MutterPlugin *plugin, + XEvent *xev) { - if (handle_panel_event (xev)) + GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin); + + if (handle_panel_event (shell_plugin, xev)) return TRUE; return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE; } -/* - * GModule unload function -- do any cleanup required. - */ -G_MODULE_EXPORT void g_module_unload (GModule *module); -G_MODULE_EXPORT void -g_module_unload (GModule *module) +static const +MutterPluginInfo *gnome_shell_plugin_plugin_info (MutterPlugin *plugin) { - free_plugin_private (plugin_state); -} + static const MutterPluginInfo info = { + .name = "GNOME Shell", + .version = "0.1", + .author = "Various", + .license = "GPLv2+", + .description = "Provides GNOME Shell core functionality" + }; + return &info; +} diff --git a/src/shell-wm.c b/src/shell-wm.c index 34ba3a7c3..5fed2c322 100644 --- a/src/shell-wm.c +++ b/src/shell-wm.c @@ -80,28 +80,13 @@ shell_wm_class_init (ShellWMClass *klass) G_TYPE_NONE, 0); } -static ShellWM * -shell_wm_get (void) +void +_shell_wm_switch_workspace (ShellWM *wm, + const GList **actors, + gint from, + gint to, + MetaMotionDirection direction) { - ShellWM *wm; - - g_object_get (shell_global_get (), - "window-manager", &wm, - NULL); - /* drop extra ref added by g_object_get */ - g_object_unref (wm); - - return wm; -} - -static void -shell_wm_switch_workspace (const GList **actors, - gint from, - gint to, - MetaMotionDirection direction) -{ - ShellWM *wm = shell_wm_get (); - shell_wm_set_switch_workspace_actors (wm, (GList *)*actors); g_signal_emit (wm, shell_wm_signals[SWITCH_WORKSPACE], 0, from, to, direction); @@ -164,12 +149,11 @@ shell_wm_completed_switch_workspace (ShellWM *wm) } -static void -shell_wm_kill_effect (MutterWindow *actor, - gulong events) +void +_shell_wm_kill_effect (ShellWM *wm, + MutterWindow *actor, + gulong events) { - ShellWM *wm = shell_wm_get (); - #ifdef NOT_YET if (events & MUTTER_PLUGIN_MINIMIZE) g_signal_emit (wm, shell_wm_signals[KILL_MINIMIZE], 0); @@ -203,15 +187,5 @@ shell_wm_new (MutterPlugin *plugin) wm = g_object_new (SHELL_TYPE_WM, NULL); wm->plugin = plugin; -#ifdef NOT_YET - plugin->minimize = shell_wm_minimize; - plugin->maximize = shell_wm_maximize; - plugin->unmaximize = shell_wm_unmaximize; - plugin->map = shell_wm_map; - plugin->destroy = shell_wm_destroy; -#endif - plugin->switch_workspace = shell_wm_switch_workspace; - plugin->kill_effect = shell_wm_kill_effect; - return wm; } diff --git a/src/shell-wm.h b/src/shell-wm.h index d448239aa..7d15a7aa3 100644 --- a/src/shell-wm.h +++ b/src/shell-wm.h @@ -29,6 +29,39 @@ ShellWM *shell_wm_new (MutterPlugin *plugin); GList *shell_wm_get_switch_workspace_actors (ShellWM *wm); void shell_wm_completed_switch_workspace (ShellWM *wm); + +/* These forward along the different effects from GnomeShellPlugin */ + +#ifdef NOT_YET +void _shell_wm_minimize (ShellWM *wm, + MutterWindow *actor); +void _shell_wm_maximize (ShellWM *wm, + MutterWindow *actor, + gint x, + gint y, + gint width, + gint height); +void _shell_wm_unmaximize (ShellWM *wm, + MutterWindow *actor, + gint x, + gint y, + gint width, + gint height); +void _shell_wm_map (ShellWM *wm, + MutterWindow *actor); +void _shell_wm_destroy (ShellWM *wm, + MutterWindow *actor); +#endif + +void _shell_wm_switch_workspace (ShellWM *wm, + const GList **actors, + gint from, + gint to, + MetaMotionDirection direction); +void _shell_wm_kill_effect (ShellWM *wm, + MutterWindow *actor, + gulong events); + G_END_DECLS #endif /* __SHELL_WM_H__ */