mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
Merge branch 'plugin-gobject' into next-generation
Conflicts: src/compositor/mutter/compositor-mutter.c src/core/window.c
This commit is contained in:
commit
3b3226b678
@ -9,7 +9,7 @@ m4_define([metacity_micro_version], [55])
|
||||
m4_define([metacity_version],
|
||||
[metacity_major_version.metacity_minor_version.metacity_micro_version])
|
||||
|
||||
m4_define([metacity_clutter_plugin_api_version], [1])
|
||||
m4_define([metacity_clutter_plugin_api_version], [2])
|
||||
|
||||
AC_INIT([metacity], [metacity_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=metacity])
|
||||
|
@ -113,6 +113,9 @@ metacity_SOURCES += \
|
||||
compositor/mutter/mutter-plugin-manager.h \
|
||||
compositor/mutter/tidy/tidy-texture-frame.c \
|
||||
compositor/mutter/tidy/tidy-texture-frame.h \
|
||||
compositor/mutter/mutter-module.c \
|
||||
compositor/mutter/mutter-module.h \
|
||||
compositor/mutter/mutter-plugin.c \
|
||||
include/mutter-plugin.h
|
||||
endif
|
||||
|
||||
|
@ -245,9 +245,10 @@ mutter_window_class_init (MutterWindowClass *klass)
|
||||
object_class->get_property = mutter_window_get_property;
|
||||
object_class->constructed = mutter_window_constructed;
|
||||
|
||||
pspec = g_param_spec_pointer ("meta-window",
|
||||
"MetaWindow",
|
||||
pspec = g_param_spec_object ("meta-window",
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
META_TYPE_WINDOW,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
@ -425,7 +426,7 @@ mutter_window_set_property (GObject *object,
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MCW_META_WINDOW:
|
||||
priv->window = g_value_get_pointer (value);
|
||||
priv->window = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_MCW_META_SCREEN:
|
||||
priv->screen = g_value_get_pointer (value);
|
||||
@ -453,7 +454,7 @@ mutter_window_get_property (GObject *object,
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MCW_META_WINDOW:
|
||||
g_value_set_pointer (value, priv->window);
|
||||
g_value_set_object (value, priv->window);
|
||||
break;
|
||||
case PROP_MCW_META_SCREEN:
|
||||
g_value_set_pointer (value, priv->screen);
|
||||
@ -2005,6 +2006,10 @@ clutter_cmp_update_workspace_geometry (MetaCompositor *compositor,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#if 0
|
||||
/* FIXME -- should do away with this function in favour of MetaWorkspace
|
||||
* signal.
|
||||
*/
|
||||
MetaScreen *screen = meta_workspace_get_screen (workspace);
|
||||
MetaCompScreen *info;
|
||||
MutterPluginManager *mgr;
|
||||
@ -2018,6 +2023,7 @@ clutter_cmp_update_workspace_geometry (MetaCompositor *compositor,
|
||||
|
||||
mutter_plugin_manager_update_workspace (mgr, workspace);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
206
src/compositor/mutter/mutter-module.c
Normal file
206
src/compositor/mutter/mutter-module.c
Normal file
@ -0,0 +1,206 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
#include "mutter-module.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
};
|
||||
|
||||
struct _MutterModulePrivate
|
||||
{
|
||||
GModule *lib;
|
||||
gchar *path;
|
||||
GType plugin_type;
|
||||
};
|
||||
|
||||
#define MUTTER_MODULE_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_MODULE, MutterModulePrivate))
|
||||
|
||||
G_DEFINE_TYPE (MutterModule, mutter_module, G_TYPE_TYPE_MODULE);
|
||||
|
||||
static gboolean
|
||||
mutter_module_load (GTypeModule *gmodule)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||
MutterPluginVersion *info = NULL;
|
||||
GType (*register_type) (GTypeModule *) = NULL;
|
||||
|
||||
if (priv->lib && priv->plugin_type)
|
||||
return TRUE;
|
||||
|
||||
g_assert (priv->path);
|
||||
|
||||
if (!priv->lib &&
|
||||
!(priv->lib = g_module_open (priv->path, G_MODULE_BIND_LOCAL)))
|
||||
{
|
||||
g_warning ("Could not load library [%s]", priv->path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_module_symbol (priv->lib, "mutter_plugin_version", (gpointer *)&info) &&
|
||||
g_module_symbol (priv->lib, "mutter_plugin_register_type",
|
||||
(gpointer *)®ister_type) &&
|
||||
info && register_type)
|
||||
{
|
||||
if (info->version_api != METACITY_CLUTTER_PLUGIN_API_VERSION)
|
||||
g_warning ("Plugin API mismatch for [%s]", priv->path);
|
||||
else
|
||||
{
|
||||
GType plugin_type;
|
||||
|
||||
if (!(plugin_type = register_type (gmodule)))
|
||||
{
|
||||
g_warning ("Could not register type for plugin %s",
|
||||
priv->path);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->plugin_type = plugin_type;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_warning ("Broken plugin module [%s]", priv->path);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_unload (GTypeModule *gmodule)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||
|
||||
g_module_close (priv->lib);
|
||||
|
||||
priv->lib = NULL;
|
||||
priv->plugin_type = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_module_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_finalize (GObject *object)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
g_free (priv->path);
|
||||
priv->path = NULL;
|
||||
|
||||
G_OBJECT_CLASS (mutter_module_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_free (priv->path);
|
||||
priv->path = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_value_set_string (value, priv->path);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_class_init (MutterModuleClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_module_finalize;
|
||||
gobject_class->dispose = mutter_module_dispose;
|
||||
gobject_class->set_property = mutter_module_set_property;
|
||||
gobject_class->get_property = mutter_module_get_property;
|
||||
|
||||
gmodule_class->load = mutter_module_load;
|
||||
gmodule_class->unload = mutter_module_unload;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PATH,
|
||||
g_param_spec_string ("path",
|
||||
"Path",
|
||||
"Load path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterModulePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_init (MutterModule *self)
|
||||
{
|
||||
MutterModulePrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_MODULE_GET_PRIVATE (self);
|
||||
|
||||
}
|
||||
|
||||
GType
|
||||
mutter_module_get_plugin_type (MutterModule *module)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (module)->priv;
|
||||
|
||||
return priv->plugin_type;
|
||||
}
|
||||
|
57
src/compositor/mutter/mutter-module.h
Normal file
57
src/compositor/mutter/mutter-module.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MUTTER_MODULE_H_
|
||||
#define MUTTER_MODULE_H_
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#define MUTTER_TYPE_MODULE (mutter_module_get_type ())
|
||||
#define MUTTER_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_MODULE, MutterModule))
|
||||
#define MUTTER_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||
#define MUTTER_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_MODULE_TYPE))
|
||||
#define MUTTER_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_MODULE))
|
||||
#define MUTTER_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||
|
||||
typedef struct _MutterModule MutterModule;
|
||||
typedef struct _MutterModuleClass MutterModuleClass;
|
||||
typedef struct _MutterModulePrivate MutterModulePrivate;
|
||||
|
||||
struct _MutterModule
|
||||
{
|
||||
GTypeModule parent;
|
||||
|
||||
MutterModulePrivate *priv;
|
||||
};
|
||||
|
||||
struct _MutterModuleClass
|
||||
{
|
||||
GTypeModuleClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType mutter_module_get_type (void);
|
||||
|
||||
GType mutter_module_get_plugin_type (MutterModule *module);
|
||||
|
||||
#endif
|
@ -26,215 +26,52 @@
|
||||
#include "prefs.h"
|
||||
#include "errors.h"
|
||||
#include "workspace.h"
|
||||
#include "mutter-module.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
static gboolean mutter_plugin_manager_reload (
|
||||
MutterPluginManager *plugin_mgr);
|
||||
/*
|
||||
* There is only one instace of each module per the process.
|
||||
*/
|
||||
static GHashTable *plugin_modules = NULL;
|
||||
|
||||
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
|
||||
|
||||
struct MutterPluginManager
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *plugins; /* TODO -- maybe use hash table */
|
||||
GList *plugins;
|
||||
GList *unload; /* Plugins that are disabled and pending unload */
|
||||
|
||||
guint idle_unload_id;
|
||||
};
|
||||
|
||||
typedef struct MutterPluginPrivate
|
||||
{
|
||||
char *name;
|
||||
MutterPluginManager *self;
|
||||
GModule *module;
|
||||
gulong features;
|
||||
/* We use this to track the number of effects currently being managed
|
||||
* by a plugin. Currently this is used to block unloading while effects
|
||||
* are in progress. */
|
||||
gint running;
|
||||
|
||||
gboolean disabled : 1;
|
||||
} MutterPluginPrivate;
|
||||
|
||||
|
||||
static void
|
||||
free_plugin_workspaces (MutterPlugin *plugin)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
l = plugin->work_areas;
|
||||
|
||||
while (l)
|
||||
{
|
||||
g_free (l->data);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (plugin->work_areas)
|
||||
g_list_free (plugin->work_areas);
|
||||
|
||||
plugin->work_areas = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets work area geometry and stores it in list in the plugin.
|
||||
*
|
||||
* If the plugin list is already populated, we simply replace it (we are
|
||||
* dealing with a small number of items in the list and unfrequent changes).
|
||||
*/
|
||||
static void
|
||||
update_plugin_workspaces (MetaScreen *screen,
|
||||
MutterPlugin *plugin)
|
||||
{
|
||||
GList *l, *l2 = NULL;
|
||||
|
||||
l = meta_screen_get_workspaces (screen);
|
||||
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
MetaRectangle *r;
|
||||
|
||||
r = g_new0 (MetaRectangle, 1);
|
||||
|
||||
meta_workspace_get_work_area_all_xineramas (w, (MetaRectangle*)r);
|
||||
|
||||
l2 = g_list_append (l2, r);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
free_plugin_workspaces (plugin);
|
||||
|
||||
plugin->work_areas = l2;
|
||||
}
|
||||
|
||||
/**
|
||||
* parse_disable_params:
|
||||
* @params: as read from gconf, a ':' seperated list of plugin options
|
||||
* @features: The mask of features the plugin advertises
|
||||
*
|
||||
* This function returns a new mask of features removing anything that
|
||||
* the user has disabled.
|
||||
*/
|
||||
static gulong
|
||||
parse_disable_params (const char *params, MutterPlugin *plugin)
|
||||
{
|
||||
char *p;
|
||||
gulong features = 0;
|
||||
|
||||
/*
|
||||
* Feature flags: identify events that the plugin can handle; a plugin can
|
||||
* handle one or more events.
|
||||
*/
|
||||
if (plugin->minimize)
|
||||
features |= MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (plugin->maximize)
|
||||
features |= MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (plugin->unmaximize)
|
||||
features |= MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (plugin->map)
|
||||
features |= MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (plugin->destroy)
|
||||
features |= MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (plugin->switch_workspace)
|
||||
features |= MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
if (!params)
|
||||
return features;
|
||||
|
||||
if ((p = strstr (params, "disable:")))
|
||||
{
|
||||
gchar *d = g_strdup (p+8);
|
||||
|
||||
p = strchr (d, ';');
|
||||
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
if (strstr (d, "minimize"))
|
||||
features &= ~ MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (strstr (d, "maximize"))
|
||||
features &= ~ MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (strstr (d, "unmaximize"))
|
||||
features &= ~ MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (strstr (d, "map"))
|
||||
features &= ~ MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (strstr (d, "destroy"))
|
||||
features &= ~ MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (strstr (d, "switch-workspace"))
|
||||
features &= ~MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
g_free (d);
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks that the plugin is compatible with the WM and sets up the plugin
|
||||
* struct.
|
||||
*/
|
||||
static MutterPlugin *
|
||||
mutter_plugin_load (MutterPluginManager *plugin_mgr,
|
||||
GModule *module,
|
||||
mutter_plugin_load (MutterPluginManager *mgr,
|
||||
MutterModule *module,
|
||||
const gchar *params)
|
||||
{
|
||||
MutterPlugin *plugin;
|
||||
MutterPlugin *plugin = NULL;
|
||||
GType plugin_type = mutter_module_get_plugin_type (module);
|
||||
|
||||
if (g_module_symbol (module, "mutter_plugin", (gpointer *)&plugin))
|
||||
if (!plugin_type)
|
||||
{
|
||||
if (plugin->version_api == METACITY_CLUTTER_PLUGIN_API_VERSION)
|
||||
{
|
||||
MutterPluginPrivate *priv;
|
||||
|
||||
priv = g_new0 (MutterPluginPrivate, 1);
|
||||
priv->name = _(plugin->name);
|
||||
priv->module = module;
|
||||
priv->self = plugin_mgr;
|
||||
|
||||
/* FIXME: instead of hanging private data of the plugin descriptor
|
||||
* we could make the descriptor const if we were to hang it off
|
||||
* a plugin manager structure */
|
||||
plugin->manager_private = priv;
|
||||
|
||||
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
||||
|
||||
priv->features = parse_disable_params (params, plugin);
|
||||
|
||||
/*
|
||||
* Check for and run the plugin init function.
|
||||
*/
|
||||
if (!plugin->do_init || !(plugin->do_init (params)))
|
||||
{
|
||||
g_free (priv);
|
||||
|
||||
free_plugin_workspaces (plugin);
|
||||
|
||||
g_warning ("Plugin type not registered !!!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meta_verbose ("Loaded plugin [%s]\n", priv->name);
|
||||
plugin = g_object_new (plugin_type,
|
||||
"screen", mgr->screen,
|
||||
"params", params,
|
||||
NULL);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -245,22 +82,13 @@ mutter_plugin_load (MutterPluginManager *plugin_mgr,
|
||||
static gboolean
|
||||
mutter_plugin_unload (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv;
|
||||
GModule *module;
|
||||
|
||||
priv = plugin->manager_private;
|
||||
module = priv->module;
|
||||
|
||||
if (priv->running)
|
||||
if (mutter_plugin_running (plugin))
|
||||
{
|
||||
priv->disabled = TRUE;
|
||||
g_object_set (plugin, "disabled", TRUE, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (priv);
|
||||
plugin->manager_private = NULL;
|
||||
|
||||
g_module_close (module);
|
||||
g_object_unref (plugin);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -353,10 +181,20 @@ prefs_changed_callback (MetaPreference pref,
|
||||
{
|
||||
mutter_plugin_manager_reload (plugin_mgr);
|
||||
}
|
||||
else if (pref == META_PREF_NUM_WORKSPACES)
|
||||
}
|
||||
|
||||
static MutterModule *
|
||||
mutter_plugin_manager_get_module (const gchar *path)
|
||||
{
|
||||
MutterModule *module = g_hash_table_lookup (plugin_modules, path);
|
||||
|
||||
if (!module &&
|
||||
(module = g_object_new (MUTTER_TYPE_MODULE, "path", path, NULL)))
|
||||
{
|
||||
mutter_plugin_manager_update_workspaces (plugin_mgr);
|
||||
g_hash_table_insert (plugin_modules, g_strdup (path), module);
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -388,7 +226,7 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||
|
||||
if (plugin_string)
|
||||
{
|
||||
GModule *plugin;
|
||||
MutterModule *module;
|
||||
gchar *path;
|
||||
|
||||
params = strchr (plugin_string, ':');
|
||||
@ -404,20 +242,35 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||
else
|
||||
path = g_strconcat (dpath, plugin_string, ".so", NULL);
|
||||
|
||||
if ((plugin = g_module_open (path, G_MODULE_BIND_LOCAL)))
|
||||
module = mutter_plugin_manager_get_module (path);
|
||||
|
||||
if (module)
|
||||
{
|
||||
MutterPlugin *p;
|
||||
|
||||
if ((p = mutter_plugin_load (plugin_mgr, plugin, params)))
|
||||
/*
|
||||
* This dlopens the module and registers the plugin type with the
|
||||
* GType system, if the module is not already loaded. When we
|
||||
* create a plugin, the type system also calls g_type_module_use()
|
||||
* to guarantee the module will not be unloaded during the plugin
|
||||
* life time. Consequently we can unuse() the module again.
|
||||
*/
|
||||
g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
if ((p = mutter_plugin_load (plugin_mgr, module, params)))
|
||||
{
|
||||
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Plugin load for [%s] failed", path);
|
||||
g_module_close (plugin);
|
||||
g_warning ("Plugin load for [%s] failed", path);
|
||||
}
|
||||
|
||||
g_type_module_unuse (G_TYPE_MODULE (module));
|
||||
}
|
||||
else
|
||||
g_message ("Unable to load plugin [%s]: %s", path, g_module_error());
|
||||
g_warning ("Unable to load plugin module [%s]: %s",
|
||||
path, g_module_error());
|
||||
|
||||
g_free (path);
|
||||
g_free (plugin_string);
|
||||
@ -459,57 +312,17 @@ mutter_plugin_manager_init (MutterPluginManager *plugin_mgr)
|
||||
return mutter_plugin_manager_load (plugin_mgr);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_manager_update_workspace (MutterPluginManager *plugin_mgr,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
GList *l;
|
||||
gint index;
|
||||
|
||||
index = meta_workspace_index (workspace);
|
||||
l = plugin_mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MetaRectangle *rect = g_list_nth_data (plugin->work_areas, index);
|
||||
|
||||
if (rect)
|
||||
{
|
||||
meta_workspace_get_work_area_all_xineramas (workspace, rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something not entirely right; redo the whole thing */
|
||||
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_manager_update_workspaces (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
l = plugin_mgr->plugins;
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
|
||||
update_plugin_workspaces (plugin_mgr->screen, plugin);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
MutterPluginManager *
|
||||
mutter_plugin_manager_new (MetaScreen *screen)
|
||||
{
|
||||
MutterPluginManager *plugin_mgr;
|
||||
|
||||
if (!plugin_modules)
|
||||
{
|
||||
plugin_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
NULL);
|
||||
}
|
||||
|
||||
plugin_mgr = g_new0 (MutterPluginManager, 1);
|
||||
|
||||
plugin_mgr->screen = screen;
|
||||
@ -533,12 +346,12 @@ mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!priv->disabled
|
||||
&& (priv->features & events)
|
||||
&& plugin->kill_effect)
|
||||
plugin->kill_effect (actor, events);
|
||||
if (!mutter_plugin_disabled (plugin)
|
||||
&& (mutter_plugin_features (plugin) & events)
|
||||
&& klass->kill_effect)
|
||||
klass->kill_effect (plugin, actor, events);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
@ -567,43 +380,41 @@ mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!priv->disabled && (priv->features & event))
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case MUTTER_PLUGIN_MINIMIZE:
|
||||
if (plugin->minimize)
|
||||
if (klass->minimize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
priv->running++;
|
||||
plugin->minimize (actor);
|
||||
klass->minimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_MAP:
|
||||
if (plugin->map)
|
||||
if (klass->map)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
priv->running++;
|
||||
plugin->map (actor);
|
||||
klass->map (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_DESTROY:
|
||||
if (plugin->destroy)
|
||||
if (klass->destroy)
|
||||
{
|
||||
priv->running++;
|
||||
plugin->destroy (actor);
|
||||
klass->destroy (plugin, actor);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -641,35 +452,36 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!priv->disabled && (priv->features & event))
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case MUTTER_PLUGIN_MAXIMIZE:
|
||||
if (plugin->maximize)
|
||||
if (klass->maximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
plugin->maximize (actor,
|
||||
klass->maximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_UNMAXIMIZE:
|
||||
if (plugin->unmaximize)
|
||||
if (klass->unmaximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
plugin->unmaximize (actor,
|
||||
klass->unmaximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
@ -706,13 +518,13 @@ mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!priv->disabled &&
|
||||
(priv->features & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||
(actors && *actors))
|
||||
{
|
||||
if (plugin->switch_workspace)
|
||||
if (klass->switch_workspace)
|
||||
{
|
||||
retval = TRUE;
|
||||
mutter_plugin_manager_kill_effect (
|
||||
@ -720,7 +532,7 @@ mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||
MUTTER_WINDOW ((*actors)->data),
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
|
||||
plugin->switch_workspace (actors, from, to, direction);
|
||||
klass->switch_workspace (plugin, actors, from, to, direction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -752,10 +564,11 @@ mutter_plugin_manager_xevent_filter (MutterPluginManager *plugin_mgr,
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (plugin->xevent_filter)
|
||||
if (klass->xevent_filter)
|
||||
{
|
||||
if (plugin->xevent_filter (xev) == TRUE)
|
||||
if (klass->xevent_filter (plugin, xev) == TRUE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -765,176 +578,3 @@ mutter_plugin_manager_xevent_filter (MutterPluginManager *plugin_mgr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Public accessors for plugins, exposed from mutter-plugin.h
|
||||
*/
|
||||
ClutterActor *
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
return mutter_get_overlay_group_for_screen (plugin_mgr->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
return mutter_get_stage_for_screen (plugin_mgr->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_window_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
return mutter_get_window_group_for_screen (plugin_mgr->screen);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
|
||||
priv->running--;
|
||||
|
||||
if (!actor)
|
||||
{
|
||||
g_warning ("Plugin [%s] passed NULL for actor!",
|
||||
(plugin && plugin->name) ? plugin->name : "unknown");
|
||||
}
|
||||
|
||||
mutter_window_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
meta_screen_get_size (plugin_mgr->screen, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
||||
gboolean reactive)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *mgr = priv->self;
|
||||
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (mgr->screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (mgr->screen);
|
||||
|
||||
static XserverRegion region = None;
|
||||
|
||||
if (region == None)
|
||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
|
||||
if (reactive)
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, None);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, None);
|
||||
}
|
||||
else
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *mgr = priv->self;
|
||||
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
XRectangle rect;
|
||||
XserverRegion region;
|
||||
|
||||
stage = mutter_get_stage_for_screen (mgr->screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (mgr->screen);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
region = XFixesCreateRegion (xdpy, &rect, 1);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
|
||||
XFixesDestroyRegion (xdpy, region);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
XserverRegion region)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *mgr = priv->self;
|
||||
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (mgr->screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (mgr->screen);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
}
|
||||
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *plugin_mgr = priv->self;
|
||||
|
||||
return mutter_get_windows (plugin_mgr->screen);
|
||||
}
|
||||
|
||||
Display *
|
||||
mutter_plugin_get_xdisplay (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *mgr = priv->self;
|
||||
MetaDisplay *display = meta_screen_get_display (mgr->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
|
||||
return xdpy;
|
||||
}
|
||||
|
||||
MetaScreen *
|
||||
mutter_plugin_get_screen (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = plugin->manager_private;
|
||||
MutterPluginManager *mgr = priv->self;
|
||||
|
||||
return mgr->screen;
|
||||
}
|
||||
|
||||
|
574
src/compositor/mutter/mutter-plugin.c
Normal file
574
src/compositor/mutter/mutter-plugin.c
Normal file
@ -0,0 +1,574 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
#include "screen.h"
|
||||
#include "display.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MutterPlugin, mutter_plugin, G_TYPE_OBJECT);
|
||||
|
||||
#define MUTTER_PLUGIN_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_PLUGIN, MutterPluginPrivate))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SCREEN,
|
||||
PROP_PARAMS,
|
||||
PROP_FEATURES,
|
||||
PROP_DISABLED,
|
||||
PROP_DEBUG_MODE,
|
||||
};
|
||||
|
||||
struct _MutterPluginPrivate
|
||||
{
|
||||
MetaScreen *screen;
|
||||
gchar *params;
|
||||
gulong features;
|
||||
|
||||
gint running;
|
||||
|
||||
gboolean disabled : 1;
|
||||
gboolean debug : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
mutter_plugin_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_finalize (GObject *object)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
g_free (priv->params);
|
||||
priv->params = NULL;
|
||||
|
||||
G_OBJECT_CLASS (mutter_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_parse_params (MutterPlugin *plugin)
|
||||
{
|
||||
char *p;
|
||||
gulong features = 0;
|
||||
MutterPluginPrivate *priv = plugin->priv;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
/*
|
||||
* Feature flags: identify events that the plugin can handle; a plugin can
|
||||
* handle one or more events.
|
||||
*/
|
||||
if (klass->minimize)
|
||||
features |= MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (klass->maximize)
|
||||
features |= MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (klass->unmaximize)
|
||||
features |= MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (klass->map)
|
||||
features |= MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (klass->destroy)
|
||||
features |= MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (klass->switch_workspace)
|
||||
features |= MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
if (priv->params)
|
||||
{
|
||||
gboolean debug = FALSE;
|
||||
|
||||
if ((p = strstr (priv->params, "disable:")))
|
||||
{
|
||||
gchar *d = g_strdup (p+8);
|
||||
|
||||
p = strchr (d, ';');
|
||||
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
if (strstr (d, "minimize"))
|
||||
features &= ~ MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (strstr (d, "maximize"))
|
||||
features &= ~ MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (strstr (d, "unmaximize"))
|
||||
features &= ~ MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (strstr (d, "map"))
|
||||
features &= ~ MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (strstr (d, "destroy"))
|
||||
features &= ~ MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (strstr (d, "switch-workspace"))
|
||||
features &= ~MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
g_free (d);
|
||||
}
|
||||
|
||||
if (strstr (priv->params, "debug"))
|
||||
debug = TRUE;
|
||||
|
||||
if (debug != priv->debug)
|
||||
{
|
||||
priv->debug = debug;
|
||||
|
||||
g_object_notify (G_OBJECT (plugin), "debug-mode");
|
||||
}
|
||||
}
|
||||
|
||||
if (features != priv->features)
|
||||
{
|
||||
priv->features = features;
|
||||
|
||||
g_object_notify (G_OBJECT (plugin), "features");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
priv->screen = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_PARAMS:
|
||||
priv->params = g_value_dup_string (value);
|
||||
mutter_plugin_parse_params (MUTTER_PLUGIN (object));
|
||||
break;
|
||||
case PROP_DISABLED:
|
||||
priv->disabled = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_DEBUG_MODE:
|
||||
priv->debug = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, priv->screen);
|
||||
break;
|
||||
case PROP_PARAMS:
|
||||
g_value_set_string (value, priv->params);
|
||||
break;
|
||||
case PROP_DISABLED:
|
||||
g_value_set_boolean (value, priv->disabled);
|
||||
break;
|
||||
case PROP_DEBUG_MODE:
|
||||
g_value_set_boolean (value, priv->debug);
|
||||
break;
|
||||
case PROP_FEATURES:
|
||||
g_value_set_ulong (value, priv->features);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_real_minimize (MutterPlugin *plugin, MutterWindow *actor)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_real_maximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_real_unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_real_map (MutterPlugin *plugin, MutterWindow *actor)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_real_destroy (MutterPlugin *plugin, MutterWindow *actor)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_real_switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_class_init (MutterPluginClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_plugin_finalize;
|
||||
gobject_class->dispose = mutter_plugin_dispose;
|
||||
gobject_class->set_property = mutter_plugin_set_property;
|
||||
gobject_class->get_property = mutter_plugin_get_property;
|
||||
|
||||
plugin_class->map = mutter_plugin_real_map;
|
||||
plugin_class->minimize = mutter_plugin_real_minimize;
|
||||
plugin_class->maximize = mutter_plugin_real_maximize;
|
||||
plugin_class->unmaximize = mutter_plugin_real_unmaximize;
|
||||
plugin_class->destroy = mutter_plugin_real_destroy;
|
||||
plugin_class->switch_workspace = mutter_plugin_real_switch_workspace;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SCREEN,
|
||||
g_param_spec_object ("screen",
|
||||
"MetaScreen",
|
||||
"MetaScreen",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PARAMS,
|
||||
g_param_spec_string ("params",
|
||||
"Parameters",
|
||||
"Plugin Parameters",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_FEATURES,
|
||||
g_param_spec_ulong ("features",
|
||||
"Features",
|
||||
"Plugin Features",
|
||||
0 , G_MAXULONG, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DISABLED,
|
||||
g_param_spec_boolean ("disabled",
|
||||
"Plugin disabled",
|
||||
"Plugin disabled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DEBUG_MODE,
|
||||
g_param_spec_boolean ("debug-mode",
|
||||
"Debug Mode",
|
||||
"Debug Mode",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_init (MutterPlugin *self)
|
||||
{
|
||||
MutterPluginPrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_PLUGIN_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
gulong
|
||||
mutter_plugin_features (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->features;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_disabled (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->disabled;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_running (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return (priv->running > 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_debug_mode (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->debug;
|
||||
}
|
||||
|
||||
const MutterPluginInfo *
|
||||
mutter_plugin_get_info (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (klass && klass->plugin_info)
|
||||
return klass->plugin_info (plugin);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_overlay_group_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_stage_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_window_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_window_group_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->running-- < 0)
|
||||
{
|
||||
g_warning ("Error in running effect accounting, adjusting.");
|
||||
priv->running = 0;
|
||||
}
|
||||
|
||||
if (!actor)
|
||||
{
|
||||
const MutterPluginInfo *info;
|
||||
const gchar *name = NULL;
|
||||
|
||||
if (plugin && (info = mutter_plugin_get_info (plugin)))
|
||||
name = info->name;
|
||||
|
||||
g_warning ("Plugin [%s] passed NULL for actor!",
|
||||
name ? name : "unknown");
|
||||
}
|
||||
|
||||
mutter_window_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
meta_screen_get_size (priv->screen, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
||||
gboolean reactive)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
static XserverRegion region = None;
|
||||
|
||||
if (region == None)
|
||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
|
||||
if (reactive)
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, None);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, None);
|
||||
}
|
||||
else
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
XRectangle rect;
|
||||
XserverRegion region;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
region = XFixesCreateRegion (xdpy, &rect, 1);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
|
||||
XFixesDestroyRegion (xdpy, region);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
XserverRegion region)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
}
|
||||
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_windows (priv->screen);
|
||||
}
|
||||
|
||||
Display *
|
||||
mutter_plugin_get_xdisplay (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaDisplay *display = meta_screen_get_display (priv->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
|
||||
return xdpy;
|
||||
}
|
||||
|
||||
MetaScreen *
|
||||
mutter_plugin_get_screen (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->screen;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define MUTTER_BUILDING_PLUGIN 1
|
||||
#include "mutter-plugin.h"
|
||||
|
||||
#include <libintl.h>
|
||||
@ -39,35 +38,63 @@
|
||||
#define SWITCH_TIMEOUT 500
|
||||
|
||||
#define ACTOR_DATA_KEY "MCCP-Default-actor-data"
|
||||
|
||||
#define MUTTER_TYPE_DEFAULT_PLUGIN (mutter_default_plugin_get_type ())
|
||||
#define MUTTER_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPlugin))
|
||||
#define MUTTER_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginClass))
|
||||
#define MUTTER_IS_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_DEFAULT_PLUGIN_TYPE))
|
||||
#define MUTTER_IS_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_DEFAULT_PLUGIN))
|
||||
#define MUTTER_DEFAULT_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginClass))
|
||||
|
||||
#define MUTTER_DEFAULT_PLUGIN_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginPrivate))
|
||||
|
||||
typedef struct _MutterDefaultPlugin MutterDefaultPlugin;
|
||||
typedef struct _MutterDefaultPluginClass MutterDefaultPluginClass;
|
||||
typedef struct _MutterDefaultPluginPrivate MutterDefaultPluginPrivate;
|
||||
|
||||
struct _MutterDefaultPlugin
|
||||
{
|
||||
MutterPlugin parent;
|
||||
|
||||
MutterDefaultPluginPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MutterDefaultPluginClass
|
||||
{
|
||||
MutterPluginClass parent_class;
|
||||
};
|
||||
|
||||
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,
|
||||
static void minimize (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void map (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void destroy (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void maximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x, gint y, gint width, gint height);
|
||||
static void unmaximize (MutterWindow *actor,
|
||||
static void unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
static void switch_workspace (const GList **actors, gint from, gint to,
|
||||
static void switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
static void kill_effect (MutterWindow *actor, gulong event);
|
||||
static void kill_effect (MutterPlugin *plugin,
|
||||
MutterWindow *actor, gulong event);
|
||||
|
||||
static gboolean reload (const char *params);
|
||||
static const MutterPluginInfo * plugin_info (MutterPlugin *plugin);
|
||||
|
||||
|
||||
/*
|
||||
* Create the plugin struct; function pointers initialized in
|
||||
* g_module_check_init().
|
||||
*/
|
||||
MUTTER_DECLARE_PLUGIN();
|
||||
MUTTER_PLUGIN_DECLARE(MutterDefaultPlugin, mutter_default_plugin);
|
||||
|
||||
/*
|
||||
* Plugin private data that we store in the .plugin_private member.
|
||||
*/
|
||||
typedef struct _PluginState
|
||||
struct _MutterDefaultPluginPrivate
|
||||
{
|
||||
ClutterEffectTemplate *destroy_effect;
|
||||
ClutterEffectTemplate *minimize_effect;
|
||||
@ -82,8 +109,150 @@ typedef struct _PluginState
|
||||
ClutterActor *desktop1;
|
||||
ClutterActor *desktop2;
|
||||
|
||||
MutterPluginInfo info;
|
||||
|
||||
gboolean debug_mode : 1;
|
||||
} PluginState;
|
||||
};
|
||||
|
||||
static void
|
||||
mutter_default_plugin_dispose (GObject *object)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
|
||||
|
||||
g_object_unref (priv->destroy_effect);
|
||||
g_object_unref (priv->minimize_effect);
|
||||
g_object_unref (priv->maximize_effect);
|
||||
g_object_unref (priv->switch_workspace_effect);
|
||||
|
||||
G_OBJECT_CLASS (mutter_default_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_default_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_constructed (GObject *object)
|
||||
{
|
||||
MutterPlugin *plugin = MUTTER_PLUGIN (object);
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
|
||||
|
||||
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;
|
||||
|
||||
if (mutter_plugin_debug_mode (plugin))
|
||||
{
|
||||
g_debug ("Plugin %s: Entering debug mode.", priv->info.name);
|
||||
|
||||
priv->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;
|
||||
}
|
||||
|
||||
priv->destroy_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
destroy_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
|
||||
priv->minimize_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
minimize_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
priv->maximize_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
maximize_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
priv->map_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
map_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
|
||||
priv->switch_workspace_effect
|
||||
= clutter_effect_template_new (clutter_timeline_new_for_duration (
|
||||
switch_timeout),
|
||||
CLUTTER_ALPHA_SINE_INC);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_class_init (MutterDefaultPluginClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_default_plugin_finalize;
|
||||
gobject_class->dispose = mutter_default_plugin_dispose;
|
||||
gobject_class->constructed = mutter_default_plugin_constructed;
|
||||
gobject_class->set_property = mutter_default_plugin_set_property;
|
||||
gobject_class->get_property = mutter_default_plugin_get_property;
|
||||
|
||||
plugin_class->map = map;
|
||||
plugin_class->minimize = minimize;
|
||||
plugin_class->maximize = maximize;
|
||||
plugin_class->unmaximize = unmaximize;
|
||||
plugin_class->destroy = destroy;
|
||||
plugin_class->switch_workspace = switch_workspace;
|
||||
plugin_class->kill_effect = kill_effect;
|
||||
plugin_class->plugin_info = plugin_info;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterDefaultPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_init (MutterDefaultPlugin *self)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_DEFAULT_PLUGIN_GET_PRIVATE (self);
|
||||
|
||||
priv->info.name = "Default Effects";
|
||||
priv->info.version = "0.1";
|
||||
priv->info.author = "Intel Corp.";
|
||||
priv->info.license = "GPL";
|
||||
priv->info.description = "This is an example of a plugin implementation.";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@ -102,8 +271,6 @@ typedef struct _ActorPrivate
|
||||
gboolean is_maximized : 1;
|
||||
} ActorPrivate;
|
||||
|
||||
static PluginState *plugin_state;
|
||||
|
||||
/*
|
||||
* Actor private data accessor
|
||||
*/
|
||||
@ -134,53 +301,72 @@ get_actor_private (MutterWindow *actor)
|
||||
return priv;
|
||||
}
|
||||
|
||||
typedef struct SwitchWorkspaceData
|
||||
{
|
||||
MutterPlugin *plugin;
|
||||
const GList **actors;
|
||||
} SwitchWorkspaceData;
|
||||
|
||||
static void
|
||||
on_switch_workspace_effect_complete (ClutterActor *group, gpointer data)
|
||||
{
|
||||
PluginState *state = plugin_state;
|
||||
GList *l = *((GList**)data);
|
||||
SwitchWorkspaceData *sw_data = data;
|
||||
MutterPlugin *plugin = sw_data->plugin;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l = *((GList**)sw_data->actors);
|
||||
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);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
if (priv->orig_parent)
|
||||
if (apriv->orig_parent)
|
||||
{
|
||||
clutter_actor_reparent (a, priv->orig_parent);
|
||||
priv->orig_parent = NULL;
|
||||
clutter_actor_reparent (a, apriv->orig_parent);
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
clutter_actor_destroy (state->desktop1);
|
||||
clutter_actor_destroy (state->desktop2);
|
||||
clutter_actor_destroy (priv->desktop1);
|
||||
clutter_actor_destroy (priv->desktop2);
|
||||
|
||||
state->actors = NULL;
|
||||
state->tml_switch_workspace1 = NULL;
|
||||
state->tml_switch_workspace2 = NULL;
|
||||
state->desktop1 = NULL;
|
||||
state->desktop2 = NULL;
|
||||
priv->actors = NULL;
|
||||
priv->tml_switch_workspace1 = NULL;
|
||||
priv->tml_switch_workspace2 = NULL;
|
||||
priv->desktop1 = NULL;
|
||||
priv->desktop2 = NULL;
|
||||
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), actor_for_cb,
|
||||
g_free (data);
|
||||
|
||||
mutter_plugin_effect_completed (plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_workspace (const GList **actors, gint from, gint to,
|
||||
switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
MutterPlugin *plugin = mutter_get_plugin();
|
||||
PluginState *state = plugin_state;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l;
|
||||
gint n_workspaces;
|
||||
ClutterActor *workspace0 = clutter_group_new ();
|
||||
ClutterActor *workspace1 = clutter_group_new ();
|
||||
ClutterActor *stage;
|
||||
int screen_width, screen_height;
|
||||
MetaScreen *screen = mutter_plugin_get_screen (plugin);
|
||||
SwitchWorkspaceData *sw_data = g_new (SwitchWorkspaceData, 1);
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
switch_workspace (plugin, actors, from, to, direction);
|
||||
|
||||
sw_data->plugin = plugin;
|
||||
sw_data->actors = actors;
|
||||
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
@ -201,19 +387,19 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), NULL,
|
||||
mutter_plugin_effect_completed (plugin, NULL,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
return;
|
||||
}
|
||||
|
||||
n_workspaces = g_list_length (plugin->work_areas);
|
||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
|
||||
l = g_list_last (*((GList**) actors));
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterWindow *mc_window = l->data;
|
||||
ActorPrivate *priv = get_actor_private (mc_window);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
ClutterActor *window = CLUTTER_ACTOR (mc_window);
|
||||
gint win_workspace;
|
||||
|
||||
@ -227,7 +413,7 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
clutter_actor_get_position (window, &x, &y);
|
||||
clutter_actor_get_size (window, &w, &h);
|
||||
|
||||
priv->orig_parent = clutter_actor_get_parent (window);
|
||||
apriv->orig_parent = clutter_actor_get_parent (window);
|
||||
|
||||
clutter_actor_reparent (window,
|
||||
win_workspace == to ? workspace1 : workspace0);
|
||||
@ -237,30 +423,30 @@ switch_workspace (const GList **actors, gint from, gint to,
|
||||
else if (win_workspace < 0)
|
||||
{
|
||||
/* Sticky window */
|
||||
priv->orig_parent = NULL;
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Window on some other desktop */
|
||||
clutter_actor_hide (window);
|
||||
priv->orig_parent = NULL;
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
state->actors = (GList **)actors;
|
||||
state->desktop1 = workspace0;
|
||||
state->desktop2 = workspace1;
|
||||
priv->actors = (GList **)actors;
|
||||
priv->desktop1 = workspace0;
|
||||
priv->desktop2 = workspace1;
|
||||
|
||||
state->tml_switch_workspace2 =
|
||||
clutter_effect_scale (state->switch_workspace_effect,
|
||||
priv->tml_switch_workspace2 =
|
||||
clutter_effect_scale (priv->switch_workspace_effect,
|
||||
workspace1, 1.0, 1.0,
|
||||
on_switch_workspace_effect_complete,
|
||||
(gpointer)actors);
|
||||
(gpointer)sw_data);
|
||||
|
||||
state->tml_switch_workspace1 =
|
||||
clutter_effect_scale (state->switch_workspace_effect,
|
||||
priv->tml_switch_workspace1 =
|
||||
clutter_effect_scale (priv->switch_workspace_effect,
|
||||
workspace0, 0.0, 0.0,
|
||||
NULL, NULL);
|
||||
}
|
||||
@ -277,6 +463,7 @@ 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.
|
||||
*/
|
||||
MutterPlugin *plugin = data;
|
||||
ActorPrivate *apriv;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (actor);
|
||||
|
||||
@ -292,7 +479,7 @@ on_minimize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
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_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -301,12 +488,16 @@ on_minimize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
* completion).
|
||||
*/
|
||||
static void
|
||||
minimize (MutterWindow *mc_window)
|
||||
minimize (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
PluginState *state = plugin_state;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
minimize (plugin, mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
@ -318,16 +509,16 @@ minimize (MutterWindow *mc_window)
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
apriv->tml_minimize = clutter_effect_scale (state->minimize_effect,
|
||||
apriv->tml_minimize = clutter_effect_scale (priv->minimize_effect,
|
||||
actor,
|
||||
0.0,
|
||||
0.0,
|
||||
(ClutterEffectCompleteFunc)
|
||||
on_minimize_effect_complete,
|
||||
NULL);
|
||||
plugin);
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
@ -341,6 +532,7 @@ on_maximize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
/*
|
||||
* Must reverse the effect of the effect.
|
||||
*/
|
||||
MutterPlugin * plugin = data;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
@ -352,7 +544,7 @@ on_maximize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
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_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -365,9 +557,11 @@ on_maximize_effect_complete (ClutterActor *actor, gpointer data)
|
||||
* (Something like a sound would be more appropriate.)
|
||||
*/
|
||||
static void
|
||||
maximize (MutterWindow *mc_window,
|
||||
maximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
@ -376,6 +570,10 @@ maximize (MutterWindow *mc_window,
|
||||
gint anchor_x = 0;
|
||||
gint anchor_y = 0;
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
maximize (plugin, mc_window, end_x, end_y, end_width, end_height);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
@ -404,18 +602,18 @@ maximize (MutterWindow *mc_window,
|
||||
clutter_actor_move_anchor_point (actor, anchor_x, anchor_y);
|
||||
|
||||
apriv->tml_maximize =
|
||||
clutter_effect_scale (plugin_state->maximize_effect,
|
||||
clutter_effect_scale (priv->maximize_effect,
|
||||
actor,
|
||||
scale_x,
|
||||
scale_y,
|
||||
(ClutterEffectCompleteFunc)
|
||||
on_maximize_effect_complete,
|
||||
NULL);
|
||||
plugin);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
@ -425,11 +623,16 @@ maximize (MutterWindow *mc_window,
|
||||
* (Just a skeleton code.)
|
||||
*/
|
||||
static void
|
||||
unmaximize (MutterWindow *mc_window,
|
||||
unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MetaCompWindowType type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
unmaximize (plugin, mc_window, end_x, end_y, end_width, end_height);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
@ -438,7 +641,7 @@ unmaximize (MutterWindow *mc_window,
|
||||
}
|
||||
|
||||
/* Do this conditionally, if the effect requires completion callback. */
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
}
|
||||
|
||||
@ -448,6 +651,7 @@ on_map_effect_complete (ClutterActor *actor, gpointer data)
|
||||
/*
|
||||
* Must reverse the effect of the effect.
|
||||
*/
|
||||
MutterPlugin *plugin = data;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
@ -457,7 +661,7 @@ on_map_effect_complete (ClutterActor *actor, gpointer data)
|
||||
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);
|
||||
mutter_plugin_effect_completed (plugin, mc_window, MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -465,11 +669,16 @@ on_map_effect_complete (ClutterActor *actor, gpointer data)
|
||||
* completion).
|
||||
*/
|
||||
static void
|
||||
map (MutterWindow *mc_window)
|
||||
map (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
map (plugin, mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
@ -482,19 +691,19 @@ map (MutterWindow *mc_window)
|
||||
clutter_actor_set_scale (actor, 0.0, 0.0);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
apriv->tml_map = clutter_effect_scale (plugin_state->map_effect,
|
||||
apriv->tml_map = clutter_effect_scale (priv->map_effect,
|
||||
actor,
|
||||
1.0,
|
||||
1.0,
|
||||
(ClutterEffectCompleteFunc)
|
||||
on_map_effect_complete,
|
||||
NULL);
|
||||
plugin);
|
||||
|
||||
apriv->is_minimized = FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
@ -505,7 +714,7 @@ map (MutterWindow *mc_window)
|
||||
static void
|
||||
on_destroy_effect_complete (ClutterActor *actor, gpointer data)
|
||||
{
|
||||
MutterPlugin *plugin = mutter_get_plugin();
|
||||
MutterPlugin *plugin = data;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
@ -519,11 +728,16 @@ on_destroy_effect_complete (ClutterActor *actor, gpointer data)
|
||||
* Simple TV-out like effect.
|
||||
*/
|
||||
static void
|
||||
destroy (MutterWindow *mc_window)
|
||||
destroy (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
/* Must chain up first */
|
||||
MUTTER_PLUGIN_CLASS (mutter_default_plugin_parent_class)->
|
||||
destroy (plugin, mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
@ -533,34 +747,34 @@ destroy (MutterWindow *mc_window)
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
apriv->tml_destroy = clutter_effect_scale (plugin_state->destroy_effect,
|
||||
apriv->tml_destroy = clutter_effect_scale (priv->destroy_effect,
|
||||
actor,
|
||||
1.0,
|
||||
0.0,
|
||||
(ClutterEffectCompleteFunc)
|
||||
on_destroy_effect_complete,
|
||||
NULL);
|
||||
plugin);
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (mutter_get_plugin(), mc_window,
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_effect (MutterWindow *mc_window, gulong event)
|
||||
kill_effect (MutterPlugin *plugin, MutterWindow *mc_window, gulong event)
|
||||
{
|
||||
ActorPrivate *apriv;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
if (event & MUTTER_PLUGIN_SWITCH_WORKSPACE)
|
||||
{
|
||||
PluginState *state = plugin_state;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
if (state->tml_switch_workspace1)
|
||||
if (priv->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);
|
||||
clutter_timeline_stop (priv->tml_switch_workspace1);
|
||||
clutter_timeline_stop (priv->tml_switch_workspace2);
|
||||
on_switch_workspace_effect_complete (priv->desktop1, priv->actors);
|
||||
}
|
||||
|
||||
if (!(event & ~MUTTER_PLUGIN_SWITCH_WORKSPACE))
|
||||
@ -597,144 +811,10 @@ kill_effect (MutterWindow *mc_window, gulong event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const gchar * g_module_check_init (GModule *module);
|
||||
const gchar *
|
||||
g_module_check_init (GModule *module)
|
||||
static const MutterPluginInfo *
|
||||
plugin_info (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPlugin *plugin = mutter_get_plugin ();
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
/* 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;
|
||||
return &priv->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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,8 @@ typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
@ -296,6 +298,11 @@ struct _MetaDisplay
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MetaDisplayClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||
* this into account. Here's a little macro to help out. If no wraparound
|
||||
* has occurred, this is equivalent to
|
||||
|
@ -127,6 +127,8 @@ typedef struct
|
||||
Window xwindow;
|
||||
} MetaAutoRaiseData;
|
||||
|
||||
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
|
||||
|
||||
/**
|
||||
* The display we're managing. This is a singleton object. (Historically,
|
||||
* this was a list of displays, but there was never any way to add more
|
||||
@ -163,6 +165,12 @@ static void sanity_check_timestamps (MetaDisplay *display,
|
||||
|
||||
MetaGroup* get_focussed_group (MetaDisplay *display);
|
||||
|
||||
static void
|
||||
meta_display_class_init (MetaDisplayClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for MetaPingData structs. Will destroy the
|
||||
* event source for the struct as well.
|
||||
@ -298,6 +306,13 @@ disable_compositor (MetaDisplay *display)
|
||||
display->compositor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_init (MetaDisplay *disp)
|
||||
{
|
||||
/* Some stuff could go in here that's currently in _open,
|
||||
* but it doesn't really matter. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new display, sets it up, initialises all the X extensions
|
||||
* we will need, and adds it to the list of displays.
|
||||
@ -340,7 +355,7 @@ meta_display_open (void)
|
||||
XSynchronize (xdisplay, True);
|
||||
|
||||
g_assert (the_display == NULL);
|
||||
the_display = g_new (MetaDisplay, 1);
|
||||
the_display = g_object_new (META_TYPE_DISPLAY, NULL);
|
||||
|
||||
the_display->closing = 0;
|
||||
|
||||
@ -903,7 +918,7 @@ meta_display_close (MetaDisplay *display,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Must be after all calls to meta_window_free() since they
|
||||
/* Must be after all calls to meta_window_unmanage() since they
|
||||
* unregister windows
|
||||
*/
|
||||
g_hash_table_destroy (display->window_ids);
|
||||
@ -1992,7 +2007,7 @@ event_callback (XEvent *event,
|
||||
else
|
||||
{
|
||||
/* Unmanage destroyed window */
|
||||
meta_window_free (window, timestamp);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
@ -2025,7 +2040,7 @@ event_callback (XEvent *event,
|
||||
|
||||
/* Unmanage withdrawn window */
|
||||
window->withdrawn = TRUE;
|
||||
meta_window_free (window, timestamp);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
window = NULL;
|
||||
}
|
||||
else
|
||||
@ -4828,7 +4843,7 @@ meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
tmp = winlist;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_free (tmp->data, timestamp);
|
||||
meta_window_unmanage (tmp->data, timestamp);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ typedef enum
|
||||
|
||||
struct _MetaScreen
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MetaDisplay *display;
|
||||
int number;
|
||||
char *screen_name;
|
||||
@ -139,6 +141,11 @@ struct _MetaScreen
|
||||
Window guard_window;
|
||||
};
|
||||
|
||||
struct _MetaScreenClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||
int number,
|
||||
guint32 timestamp);
|
||||
|
@ -69,6 +69,82 @@ static void meta_screen_sn_event (SnMonitorEvent *event,
|
||||
void *user_data);
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_N_WORKSPACES = 1
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaScreen, meta_screen, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
meta_screen_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
#if 0
|
||||
MetaScreen *screen = META_SCREEN (object);
|
||||
#endif
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaScreen *screen = META_SCREEN (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_WORKSPACES:
|
||||
g_value_set_int (value, meta_screen_get_n_workspaces (screen));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_finalize (GObject *object)
|
||||
{
|
||||
/* Actual freeing done in meta_screen_free() for now */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_class_init (MetaScreenClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->get_property = meta_screen_get_property;
|
||||
object_class->set_property = meta_screen_set_property;
|
||||
object_class->finalize = meta_screen_finalize;
|
||||
|
||||
pspec = g_param_spec_int ("n-workspaces",
|
||||
"N Workspaces",
|
||||
"Number of workspaces",
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WORKSPACES,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_init (MetaScreen *screen)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
set_wm_check_hint (MetaScreen *screen)
|
||||
{
|
||||
@ -488,7 +564,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen = g_new (MetaScreen, 1);
|
||||
screen = g_object_new (META_TYPE_SCREEN, NULL);
|
||||
screen->closing = 0;
|
||||
|
||||
screen->display = display;
|
||||
@ -718,7 +794,8 @@ meta_screen_free (MetaScreen *screen,
|
||||
g_free (screen->xinerama_infos);
|
||||
|
||||
g_free (screen->screen_name);
|
||||
g_free (screen);
|
||||
|
||||
g_object_unref (screen);
|
||||
|
||||
XFlush (display->xdisplay);
|
||||
meta_display_ungrab (display);
|
||||
@ -1110,11 +1187,13 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
meta_workspace_activate (neighbour, timestamp);
|
||||
|
||||
/* This also removes the workspace from the screens list */
|
||||
meta_workspace_free (workspace);
|
||||
meta_workspace_remove (workspace);
|
||||
|
||||
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
MetaWorkspace *
|
||||
@ -1136,6 +1215,8 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@ -1204,7 +1285,7 @@ update_num_workspaces (MetaScreen *screen,
|
||||
MetaWorkspace *w = tmp->data;
|
||||
|
||||
g_assert (w->windows == NULL);
|
||||
meta_workspace_free (w);
|
||||
meta_workspace_remove (w);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@ -1220,6 +1301,8 @@ update_num_workspaces (MetaScreen *screen,
|
||||
set_number_of_spaces_hint (screen, new_num);
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -66,6 +66,8 @@ typedef enum {
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
MetaWorkspace *workspace;
|
||||
@ -242,7 +244,7 @@ struct _MetaWindow
|
||||
/* Has this window not ever been shown yet? */
|
||||
guint showing_for_first_time : 1;
|
||||
|
||||
/* Are we in meta_window_free()? */
|
||||
/* Are we in meta_window_unmanage()? */
|
||||
guint unmanaging : 1;
|
||||
|
||||
/* Are we in meta_window_new()? */
|
||||
@ -363,6 +365,11 @@ struct _MetaWindow
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
* the dynamic window state such as "maximized", not just the
|
||||
* window's type
|
||||
@ -386,7 +393,7 @@ MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
XWindowAttributes *attrs);
|
||||
void meta_window_free (MetaWindow *window,
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
void meta_window_queue (MetaWindow *window,
|
||||
|
@ -384,6 +384,8 @@ set_window_title (MetaWindow *window,
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
if (modified)
|
||||
g_object_notify (G_OBJECT (window), "title");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -132,6 +132,118 @@ static gboolean idle_calc_showing (gpointer data);
|
||||
static gboolean idle_move_resize (gpointer data);
|
||||
static gboolean idle_update_icon (gpointer data);
|
||||
|
||||
G_DEFINE_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_TITLE,
|
||||
PROP_ICON,
|
||||
PROP_MINI_ICON,
|
||||
};
|
||||
|
||||
static void
|
||||
meta_window_finalize (GObject *object)
|
||||
{
|
||||
MetaWindow *window = META_WINDOW (object);
|
||||
|
||||
if (window->icon)
|
||||
g_object_unref (G_OBJECT (window->icon));
|
||||
|
||||
if (window->mini_icon)
|
||||
g_object_unref (G_OBJECT (window->mini_icon));
|
||||
|
||||
meta_icon_cache_free (&window->icon_cache);
|
||||
|
||||
g_free (window->sm_client_id);
|
||||
g_free (window->wm_client_machine);
|
||||
g_free (window->startup_id);
|
||||
g_free (window->role);
|
||||
g_free (window->res_class);
|
||||
g_free (window->res_name);
|
||||
g_free (window->title);
|
||||
g_free (window->icon_name);
|
||||
g_free (window->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaWindow *win = META_WINDOW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, win->title);
|
||||
break;
|
||||
case PROP_ICON:
|
||||
g_value_set_object (value, win->icon);
|
||||
break;
|
||||
case PROP_MINI_ICON:
|
||||
g_value_set_object (value, win->mini_icon);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_class_init (MetaWindowClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_window_finalize;
|
||||
|
||||
object_class->get_property = meta_window_get_property;
|
||||
object_class->set_property = meta_window_set_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_TITLE,
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"The title of the window",
|
||||
NULL,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ICON,
|
||||
g_param_spec_object ("icon",
|
||||
"Icon",
|
||||
"32 pixel sized icon",
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MINI_ICON,
|
||||
g_param_spec_object ("mini-icon",
|
||||
"Mini Icon",
|
||||
"16 pixel sized icon",
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_init (MetaWindow *self)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static const char*
|
||||
wm_state_to_string (int state)
|
||||
@ -422,7 +534,8 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
window = g_new (MetaWindow, 1);
|
||||
|
||||
window = g_object_new (META_TYPE_WINDOW, NULL);
|
||||
|
||||
window->constructing = TRUE;
|
||||
|
||||
@ -1015,7 +1128,7 @@ meta_window_apply_session_info (MetaWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_free (MetaWindow *window,
|
||||
meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GList *tmp;
|
||||
@ -1232,24 +1345,7 @@ meta_window_free (MetaWindow *window,
|
||||
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
|
||||
if (window->icon)
|
||||
g_object_unref (G_OBJECT (window->icon));
|
||||
|
||||
if (window->mini_icon)
|
||||
g_object_unref (G_OBJECT (window->mini_icon));
|
||||
|
||||
meta_icon_cache_free (&window->icon_cache);
|
||||
|
||||
g_free (window->sm_client_id);
|
||||
g_free (window->wm_client_machine);
|
||||
g_free (window->startup_id);
|
||||
g_free (window->role);
|
||||
g_free (window->res_class);
|
||||
g_free (window->res_name);
|
||||
g_free (window->title);
|
||||
g_free (window->icon_name);
|
||||
g_free (window->desc);
|
||||
g_free (window);
|
||||
g_object_unref (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6093,6 +6189,11 @@ meta_window_update_icon_now (MetaWindow *window)
|
||||
window->icon = icon;
|
||||
window->mini_icon = mini_icon;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (window));
|
||||
g_object_notify (G_OBJECT (window), "icon");
|
||||
g_object_notify (G_OBJECT (window), "mini-icon");
|
||||
g_object_thaw_notify (G_OBJECT (window));
|
||||
|
||||
redraw_icon (window);
|
||||
}
|
||||
|
||||
@ -8507,13 +8608,13 @@ meta_window_get_xwindow (MetaWindow *window)
|
||||
}
|
||||
|
||||
MetaWindowType
|
||||
meta_window_get_type (MetaWindow *window)
|
||||
meta_window_get_window_type (MetaWindow *window)
|
||||
{
|
||||
return window->type;
|
||||
}
|
||||
|
||||
Atom
|
||||
meta_window_get_type_atom (MetaWindow *window)
|
||||
meta_window_get_window_type_atom (MetaWindow *window)
|
||||
{
|
||||
return window->type_atom;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
struct _MetaWorkspace
|
||||
{
|
||||
GObject parent_instance;
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *windows;
|
||||
@ -49,6 +50,7 @@ struct _MetaWorkspace
|
||||
MetaRectangle *work_area_xinerama;
|
||||
GList *screen_region;
|
||||
GList **xinerama_region;
|
||||
gint n_xinerama_regions;
|
||||
GList *screen_edges;
|
||||
GList *xinerama_edges;
|
||||
GSList *all_struts;
|
||||
@ -57,8 +59,13 @@ struct _MetaWorkspace
|
||||
guint showing_desktop : 1;
|
||||
};
|
||||
|
||||
struct _MetaWorkspaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
MetaWorkspace* meta_workspace_new (MetaScreen *screen);
|
||||
void meta_workspace_free (MetaWorkspace *workspace);
|
||||
void meta_workspace_remove (MetaWorkspace *workspace);
|
||||
void meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
void meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
|
@ -45,6 +45,27 @@ static void free_this (gpointer candidate,
|
||||
gpointer dummy);
|
||||
static void workspace_free_struts (MetaWorkspace *workspace);
|
||||
|
||||
G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
meta_workspace_finalize (GObject *object)
|
||||
{
|
||||
/* Actual freeing done in meta_workspace_remove() for now */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_class_init (MetaWorkspaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_workspace_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_init (MetaWorkspace *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data)
|
||||
{
|
||||
@ -59,7 +80,7 @@ meta_workspace_new (MetaScreen *screen)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
workspace = g_new (MetaWorkspace, 1);
|
||||
workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
|
||||
|
||||
workspace->screen = screen;
|
||||
workspace->screen->workspaces =
|
||||
@ -112,7 +133,7 @@ workspace_free_struts (MetaWorkspace *workspace)
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_free (MetaWorkspace *workspace)
|
||||
meta_workspace_remove (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
MetaScreen *screen;
|
||||
@ -168,7 +189,7 @@ meta_workspace_free (MetaWorkspace *workspace)
|
||||
meta_rectangle_free_list_and_elements (workspace->xinerama_edges);
|
||||
}
|
||||
|
||||
g_free (workspace);
|
||||
g_object_unref (workspace);
|
||||
|
||||
/* don't bother to reset names, pagers can just ignore
|
||||
* extra ones
|
||||
|
@ -22,11 +22,22 @@
|
||||
#ifndef META_DISPLAY_H
|
||||
#define META_DISPLAY_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct _MetaDisplayClass MetaDisplayClass;
|
||||
|
||||
#define META_TYPE_DISPLAY (meta_display_get_type ())
|
||||
#define META_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), META_TYPE_DISPLAY, MetaDisplay))
|
||||
#define META_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DISPLAY, MetaDisplayClass))
|
||||
#define META_IS_DISPLAY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), META_TYPE_DISPLAY))
|
||||
#define META_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DISPLAY))
|
||||
#define META_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DISPLAY, MetaDisplayClass))
|
||||
|
||||
GType meta_display_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
|
||||
|
||||
typedef enum
|
||||
|
@ -33,20 +33,8 @@
|
||||
#include <gmodule.h>
|
||||
|
||||
/*
|
||||
* This file defines the plugin API.
|
||||
*
|
||||
* Effects plugin is shared library loaded via g_module_open(); it is
|
||||
* recommended that the GModule API is used (otherwise you are on your own to
|
||||
* do proper plugin clean up when the module is unloaded).
|
||||
*
|
||||
* The plugin interface is exported via the MutterPlugin struct.
|
||||
*/
|
||||
|
||||
typedef struct MutterPlugin MutterPlugin;
|
||||
|
||||
/*
|
||||
* Effect flags: identify events that the plugin can handle, used by kill_effect
|
||||
* function.
|
||||
* FIXME -- move these to a private include
|
||||
* Required by plugin manager.
|
||||
*/
|
||||
#define MUTTER_PLUGIN_MINIMIZE (1<<0)
|
||||
#define MUTTER_PLUGIN_MAXIMIZE (1<<1)
|
||||
@ -57,19 +45,96 @@ typedef struct MutterPlugin MutterPlugin;
|
||||
|
||||
#define MUTTER_PLUGIN_ALL_EFFECTS (~0)
|
||||
|
||||
#define MUTTER_DECLARE_PLUGIN() G_MODULE_EXPORT MutterPlugin mutter_plugin = \
|
||||
{ \
|
||||
METACITY_MAJOR_VERSION, \
|
||||
METACITY_MINOR_VERSION, \
|
||||
METACITY_MICRO_VERSION, \
|
||||
METACITY_CLUTTER_PLUGIN_API_VERSION \
|
||||
}; \
|
||||
static inline MutterPlugin * mutter_get_plugin () \
|
||||
{ \
|
||||
return &mutter_plugin; \
|
||||
}
|
||||
#define MUTTER_TYPE_PLUGIN (mutter_plugin_get_type ())
|
||||
#define MUTTER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_PLUGIN, MutterPlugin))
|
||||
#define MUTTER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_PLUGIN, MutterPluginClass))
|
||||
#define MUTTER_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_PLUGIN_TYPE))
|
||||
#define MUTTER_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_PLUGIN))
|
||||
#define MUTTER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_PLUGIN, MutterPluginClass))
|
||||
|
||||
struct MutterPlugin
|
||||
typedef struct _MutterPlugin MutterPlugin;
|
||||
typedef struct _MutterPluginClass MutterPluginClass;
|
||||
typedef struct _MutterPluginVersion MutterPluginVersion;
|
||||
typedef struct _MutterPluginInfo MutterPluginInfo;
|
||||
typedef struct _MutterPluginPrivate MutterPluginPrivate;
|
||||
|
||||
struct _MutterPlugin
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MutterPluginPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MutterPluginClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*minimize) (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void (*maximize) (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*unmaximize) (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*map) (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void (*destroy) (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
|
||||
void (*switch_workspace) (MutterPlugin *plugin,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
/*
|
||||
* Called if an effect should be killed prematurely; the plugin must
|
||||
* call the completed() callback as if the effect terminated naturally.
|
||||
* The events parameter is a bitmask indicating which effects are to be
|
||||
* killed.
|
||||
*/
|
||||
void (*kill_effect) (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gulong events);
|
||||
|
||||
/* General XEvent filter. This is fired *before* metacity itself handles
|
||||
* an event. Return TRUE to block any further processing.
|
||||
*/
|
||||
gboolean (*xevent_filter) (MutterPlugin *plugin,
|
||||
XEvent *event);
|
||||
|
||||
const MutterPluginInfo * (*plugin_info) (MutterPlugin *plugin);
|
||||
};
|
||||
|
||||
struct _MutterPluginInfo
|
||||
{
|
||||
const gchar *name;
|
||||
const gchar *version;
|
||||
const gchar *author;
|
||||
const gchar *license;
|
||||
const gchar *description;
|
||||
};
|
||||
|
||||
GType mutter_plugin_get_type (void);
|
||||
|
||||
gulong mutter_plugin_features (MutterPlugin *plugin);
|
||||
gboolean mutter_plugin_disabled (MutterPlugin *plugin);
|
||||
gboolean mutter_plugin_running (MutterPlugin *plugin);
|
||||
gboolean mutter_plugin_debug_mode (MutterPlugin *plugin);
|
||||
const MutterPluginInfo * mutter_plugin_get_info (MutterPlugin *plugin);
|
||||
|
||||
struct _MutterPluginVersion
|
||||
{
|
||||
/*
|
||||
* Version information; the first three numbers match the Metacity version
|
||||
@ -83,134 +148,81 @@ struct MutterPlugin
|
||||
/*
|
||||
* Version of the plugin API; this is unrelated to the matacity version
|
||||
* per se. The API version is checked by the plugin manager and must match
|
||||
* the one used by it (see clutter-plugins/simple.c for sample code).
|
||||
* the one used by it (see clutter-plugins/default.c for sample code).
|
||||
*/
|
||||
guint version_api;
|
||||
|
||||
#ifndef MUTTER_BUILDING_PLUGIN
|
||||
const
|
||||
#endif
|
||||
gchar *name; /* Human-readable name for UI */
|
||||
|
||||
/*
|
||||
* This function is called once the plugin has been loaded.
|
||||
*
|
||||
* @params is a string containing additional parameters for the plugin and is
|
||||
* specified after the plugin name in the gconf database, separated by a
|
||||
* colon.
|
||||
*
|
||||
* The following parameter tokens need to be handled by all
|
||||
* plugins:
|
||||
*
|
||||
* 'debug'
|
||||
* Indicates running in debug mode; the plugin
|
||||
* might want to print useful debug info, or
|
||||
* extend effect duration, etc.
|
||||
*
|
||||
* 'disable: ...;'
|
||||
*
|
||||
* The disable token indicates that the effects
|
||||
* listed after the colon should be disabled.
|
||||
*
|
||||
* The list is comma-separated, terminated by a
|
||||
* semicolon and consisting of the following
|
||||
* tokens:
|
||||
*
|
||||
* minimize
|
||||
* maximize
|
||||
* unmaximize
|
||||
* map
|
||||
* destroy
|
||||
* switch-workspace
|
||||
*
|
||||
* FIXME: ^^^ Instead of configuring in terms of what should be
|
||||
* disabled, and needing a mechanism for coping with the user
|
||||
* mistakenly not disabling the right things, it might be neater
|
||||
* if plugins were enabled on a per effect basis in the first
|
||||
* place. I.e. in gconf we could have effect:plugin key value
|
||||
* pairs.
|
||||
*/
|
||||
|
||||
gboolean (*do_init) (const char *params);
|
||||
|
||||
/*
|
||||
* Event handlers
|
||||
*
|
||||
* Plugins must not make any special assumptions about the nature of
|
||||
* ClutterActor, as the implementation details can change.
|
||||
*
|
||||
* Plugins must restore actor properties on completion (i.e., fade effects
|
||||
* must restore opacity back to the original value, scale effects scale,
|
||||
* etc.).
|
||||
*
|
||||
* On completion, each event handler must call the manager completed()
|
||||
* callback function.
|
||||
*/
|
||||
void (*minimize) (MutterWindow *actor);
|
||||
|
||||
void (*maximize) (MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*unmaximize) (MutterWindow *actor,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
void (*map) (MutterWindow *actor);
|
||||
|
||||
void (*destroy) (MutterWindow *actor);
|
||||
|
||||
/*
|
||||
* Each actor in the list has a workspace number attached to it using
|
||||
* g_object_set_data() with key MUTTER_PLUGIN_WORKSPACE_KEY;
|
||||
* workspace < 0 indicates the window is sticky (i.e., on all desktops).
|
||||
* TODO: Add accessor for sticky bit in new MutterWindow structure
|
||||
*/
|
||||
void (*switch_workspace) (const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
/*
|
||||
* Called if an effect should be killed prematurely; the plugin must
|
||||
* call the completed() callback as if the effect terminated naturally.
|
||||
* The events parameter is a bitmask indicating which effects are to be
|
||||
* killed.
|
||||
*/
|
||||
void (*kill_effect) (MutterWindow *actor,
|
||||
gulong events);
|
||||
|
||||
/*
|
||||
* The plugin manager will call this function when module should be reloaded.
|
||||
* This happens, for example, when the parameters for the plugin changed.
|
||||
*/
|
||||
gboolean (*reload) (const char *params);
|
||||
|
||||
/* General XEvent filter. This is fired *before* metacity itself handles
|
||||
* an event. Return TRUE to block any further processing.
|
||||
*/
|
||||
gboolean (*xevent_filter) (XEvent *event);
|
||||
|
||||
/* List of PluginWorkspaceRectangles defining the geometry of individual
|
||||
* workspaces. */
|
||||
GList *work_areas;
|
||||
|
||||
void *plugin_private; /* Plugin private data go here; use the plugin init
|
||||
* function to allocate and initialize any private
|
||||
* data.
|
||||
*/
|
||||
|
||||
/* Private; manager private data. */
|
||||
void *manager_private;
|
||||
};
|
||||
|
||||
#ifndef MUTTER_PLUGIN_FROM_MANAGER_
|
||||
static inline MutterPlugin *mutter_get_plugin ();
|
||||
#endif
|
||||
/*
|
||||
* Convenience macro to set up the plugin type. Based on GEdit.
|
||||
*/
|
||||
#define MUTTER_PLUGIN_DECLARE(ObjectName, object_name) \
|
||||
G_MODULE_EXPORT MutterPluginVersion mutter_plugin_version = \
|
||||
{ \
|
||||
METACITY_MAJOR_VERSION, \
|
||||
METACITY_MINOR_VERSION, \
|
||||
METACITY_MICRO_VERSION, \
|
||||
METACITY_CLUTTER_PLUGIN_API_VERSION \
|
||||
}; \
|
||||
\
|
||||
static GType g_define_type_id = 0; \
|
||||
\
|
||||
/* Prototypes */ \
|
||||
G_MODULE_EXPORT \
|
||||
GType object_name##_get_type (void); \
|
||||
\
|
||||
G_MODULE_EXPORT \
|
||||
GType object_name##_register_type (GTypeModule *type_module); \
|
||||
\
|
||||
G_MODULE_EXPORT \
|
||||
GType mutter_plugin_register_type (GTypeModule *type_module); \
|
||||
\
|
||||
GType \
|
||||
object_name##_get_type () \
|
||||
{ \
|
||||
return g_define_type_id; \
|
||||
} \
|
||||
\
|
||||
static void object_name##_init (ObjectName *self); \
|
||||
static void object_name##_class_init (ObjectName##Class *klass); \
|
||||
static gpointer object_name##_parent_class = NULL; \
|
||||
static void object_name##_class_intern_init (gpointer klass) \
|
||||
{ \
|
||||
object_name##_parent_class = g_type_class_peek_parent (klass); \
|
||||
object_name##_class_init ((ObjectName##Class *) klass); \
|
||||
} \
|
||||
\
|
||||
GType \
|
||||
object_name##_register_type (GTypeModule *type_module) \
|
||||
{ \
|
||||
static const GTypeInfo our_info = \
|
||||
{ \
|
||||
sizeof (ObjectName##Class), \
|
||||
NULL, /* base_init */ \
|
||||
NULL, /* base_finalize */ \
|
||||
(GClassInitFunc) object_name##_class_intern_init, \
|
||||
NULL, \
|
||||
NULL, /* class_data */ \
|
||||
sizeof (ObjectName), \
|
||||
0, /* n_preallocs */ \
|
||||
(GInstanceInitFunc) object_name##_init \
|
||||
}; \
|
||||
\
|
||||
g_define_type_id = g_type_module_register_type (type_module, \
|
||||
MUTTER_TYPE_PLUGIN, \
|
||||
#ObjectName, \
|
||||
&our_info, \
|
||||
0); \
|
||||
\
|
||||
\
|
||||
return g_define_type_id; \
|
||||
} \
|
||||
\
|
||||
G_MODULE_EXPORT GType \
|
||||
mutter_plugin_register_type (GTypeModule *type_module) \
|
||||
{ \
|
||||
return object_name##_register_type (type_module); \
|
||||
} \
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
|
@ -23,9 +23,20 @@
|
||||
#define META_SCREEN_H
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include "types.h"
|
||||
|
||||
#define META_TYPE_SCREEN (meta_screen_get_type ())
|
||||
#define META_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SCREEN, MetaScreen))
|
||||
#define META_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SCREEN, MetaScreenClass))
|
||||
#define META_IS_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_SCREEN_TYPE))
|
||||
#define META_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SCREEN))
|
||||
#define META_SCREEN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SCREEN, MetaScreenClass))
|
||||
|
||||
typedef struct _MetaScreenClass MetaScreenClass;
|
||||
|
||||
GType meta_screen_get_type (void);
|
||||
|
||||
int meta_screen_get_screen_number (MetaScreen *screen);
|
||||
MetaDisplay *meta_screen_get_display (MetaScreen *screen);
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef META_WINDOW_H
|
||||
#define META_WINDOW_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "boxes.h"
|
||||
@ -56,6 +56,17 @@ typedef enum
|
||||
META_MAXIMIZE_VERTICAL = 1 << 1
|
||||
} MetaMaximizeFlags;
|
||||
|
||||
#define META_TYPE_WINDOW (meta_window_get_type ())
|
||||
#define META_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW, MetaWindow))
|
||||
#define META_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW, MetaWindowClass))
|
||||
#define META_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_WINDOW_TYPE))
|
||||
#define META_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW))
|
||||
#define META_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW, MetaWindowClass))
|
||||
|
||||
typedef struct _MetaWindowClass MetaWindowClass;
|
||||
|
||||
GType meta_window_get_type (void);
|
||||
|
||||
MetaFrame *meta_window_get_frame (MetaWindow *window);
|
||||
gboolean meta_window_has_focus (MetaWindow *window);
|
||||
gboolean meta_window_is_shaded (MetaWindow *window);
|
||||
@ -63,8 +74,8 @@ MetaRectangle *meta_window_get_rect (MetaWindow *window);
|
||||
MetaScreen *meta_window_get_screen (MetaWindow *window);
|
||||
MetaDisplay *meta_window_get_display (MetaWindow *window);
|
||||
Window meta_window_get_xwindow (MetaWindow *window);
|
||||
MetaWindowType meta_window_get_type (MetaWindow *window);
|
||||
Atom meta_window_get_type_atom (MetaWindow *window);
|
||||
MetaWindowType meta_window_get_window_type (MetaWindow *window);
|
||||
Atom meta_window_get_window_type_atom (MetaWindow *window);
|
||||
MetaWorkspace *meta_window_get_workspace (MetaWindow *window);
|
||||
gboolean meta_window_is_on_all_workspaces (MetaWindow *window);
|
||||
gboolean meta_window_is_hidden (MetaWindow *window);
|
||||
|
@ -53,6 +53,17 @@ typedef enum
|
||||
META_MOTION_DOWN_RIGHT = -8
|
||||
} MetaMotionDirection;
|
||||
|
||||
#define META_TYPE_WORKSPACE (meta_workspace_get_type ())
|
||||
#define META_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WORKSPACE, MetaWorkspace))
|
||||
#define META_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
||||
#define META_IS_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_WORKSPACE_TYPE))
|
||||
#define META_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WORKSPACE))
|
||||
#define META_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WORKSPACE, MetaWorkspaceClass))
|
||||
|
||||
typedef struct _MetaWorkspaceClass MetaWorkspaceClass;
|
||||
|
||||
GType meta_workspace_get_type (void);
|
||||
|
||||
int meta_workspace_index (MetaWorkspace *workspace);
|
||||
MetaScreen *meta_workspace_get_screen (MetaWorkspace *workspace);
|
||||
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
|
||||
|
Loading…
Reference in New Issue
Block a user