Emit signals when workspaces are added, removed or switched

The patch adds GLib marshalling code to Mutter, since it's required for the "workspace-switched" signal.
The definition of MetaMotionDirection enum is moved to common.h since it's now used in workspace.c.
A little cleaning is done in workspace.c:meta_workspace_activate_with_focus(), where compositor-specific code is merged with the rest of the function (required to emit signal), removing #ifdefs.
This commit is contained in:
Milan Bouchet-Valat 2009-07-02 17:19:02 +02:00
parent 32251dcf4e
commit 2c17ef4803
8 changed files with 186 additions and 67 deletions

View File

@ -46,6 +46,9 @@ AC_HEADER_STDC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0()
#### Integer sizes
AC_CHECK_SIZEOF(char)

View File

@ -4,6 +4,12 @@ SUBDIRS=wm-tester tools compositor/plugins
INCLUDES=@MUTTER_CFLAGS@ -I $(srcdir)/include -I$(srcdir)/compositor -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
mutter_built_sources = \
mutter-marshal.h \
mutter-marshal.c \
mutter-enum-types.h \
mutter-enum-types.c
mutter_SOURCES= \
core/async-getprop.c \
core/async-getprop.h \
@ -108,7 +114,8 @@ mutter_SOURCES= \
ui/themewidget.c \
ui/themewidget.h \
ui/ui.c \
include/all-keybindings.h
include/all-keybindings.h \
$(mutter_built_sources)
# by setting libmutter_private_la_CFLAGS, the files shared with
# mutter proper will be compiled with different names.
@ -267,5 +274,49 @@ EXTRA_DIST=$(desktopfiles_files) \
$(wmproperties_in_files) \
$(schema_in_files) \
libmutter-private.pc.in \
mutter-plugins.pc.in
mutter-plugins.pc.in \
mutter-marshal.list
BUILT_SOURCES += $(mutter_built_sources)
MUTTER_STAMP_FILES = stamp-mutter-marshal.h
CLEANFILES += $(MUTTER_STAMP_FILES)
mutter-marshal.h: stamp-mutter-marshal.h
@true
stamp-mutter-marshal.h: Makefile mutter-marshal.list
$(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--header \
$(srcdir)/mutter-marshal.list > xgen-tmh && \
(cmp -s xgen-tmh mutter-marshal.h || cp -f xgen-tmh mutter-marshal.h) && \
rm -f xgen-tmh && \
echo timestamp > $(@F)
mutter-marshal.c: Makefile mutter-marshal.list
(echo "#include \"mutter-marshal.h\"" ; \
$(GLIB_GENMARSHAL) \
--prefix=_mutter_marshal \
--body \
$(srcdir)/mutter-marshal.list ) > xgen-tmc && \
cp -f xgen-tmc mutter-marshal.c && \
rm -f xgen-tmc
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-mutter-enum-types.h: $(mutter_source_h) mutter-enum-types.h.in
( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
echo timestamp > $(@F)
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template $(srcdir)/mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc

View File

@ -246,4 +246,9 @@ void meta_screen_composite_all_windows (MetaScreen *screen);
void meta_screen_restacked (MetaScreen *screen);
void meta_screen_workspace_switched (MetaScreen *screen,
int from,
int to,
MetaMotionDirection direction);
#endif

View File

@ -39,6 +39,8 @@
#include "xprops.h"
#include "compositor.h"
#include "alttabhandlerdefault.h"
#include "mutter-marshal.h"
#include "mutter-enum-types.h"
#ifdef HAVE_SOLARIS_XINERAMA
#include <X11/extensions/xinerama.h>
@ -80,6 +82,9 @@ enum
{
RESTACKED,
TOGGLE_RECORDING,
WORKSPACE_ADDED,
WORKSPACE_REMOVED,
WORKSPACE_SWITCHED,
LAST_SIGNAL
};
@ -159,6 +164,41 @@ meta_screen_class_init (MetaScreenClass *klass)
1, G_MAXINT, 1,
G_PARAM_READABLE);
screen_signals[WORKSPACE_ADDED] =
g_signal_new ("workspace-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE,
1,
G_TYPE_INT);
screen_signals[WORKSPACE_REMOVED] =
g_signal_new ("workspace-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE,
1,
G_TYPE_INT);
screen_signals[WORKSPACE_SWITCHED] =
g_signal_new ("workspace-switched",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
_mutter_marshal_VOID__INT_INT_ENUM,
G_TYPE_NONE,
3,
G_TYPE_INT,
G_TYPE_INT,
MUTTER_TYPE_MOTION_DIRECTION);
screen_signals[TOGGLE_RECORDING] =
g_signal_new ("toggle-recording",
G_TYPE_FROM_CLASS (klass),
@ -1241,6 +1281,7 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
GList *l;
MetaWorkspace *neighbour = NULL;
GList *next = NULL;
int index;
l = screen->workspaces;
while (l)
@ -1276,6 +1317,9 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
if (workspace == screen->active_workspace)
meta_workspace_activate (neighbour, timestamp);
/* To emit the signal after removing the workspace */
index = meta_workspace_index (workspace);
/* This also removes the workspace from the screens list */
meta_workspace_remove (workspace);
@ -1293,6 +1337,7 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
meta_screen_queue_workarea_recalc (screen);
g_signal_emit (screen, screen_signals[WORKSPACE_REMOVED], 0, index);
g_object_notify (G_OBJECT (screen), "n-workspaces");
}
@ -1328,6 +1373,8 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
meta_screen_queue_workarea_recalc (screen);
g_signal_emit (screen, screen_signals[WORKSPACE_ADDED],
0, meta_workspace_index (w));
g_object_notify (G_OBJECT (screen), "n-workspaces");
return w;
@ -3012,3 +3059,14 @@ meta_screen_restacked (MetaScreen *screen)
{
g_signal_emit (screen, screen_signals[RESTACKED], 0);
}
void
meta_screen_workspace_switched (MetaScreen *screen,
int from,
int to,
MetaMotionDirection direction)
{
g_signal_emit (screen, screen_signals[WORKSPACE_SWITCHED], 0,
from, to, direction);
}

View File

@ -456,8 +456,14 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
MetaWindow *focus_this,
guint32 timestamp)
{
MetaWorkspace *old;
MetaWindow *move_window;
MetaWorkspace *old;
MetaWindow *move_window;
MetaScreen *screen;
MetaDisplay *display;
MetaCompositor *comp;
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction;
meta_verbose ("Activating workspace %d\n",
meta_workspace_index (workspace));
@ -467,7 +473,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
/* Note that old can be NULL; e.g. when starting up */
old = workspace->screen->active_workspace;
workspace->screen->active_workspace = workspace;
set_active_space_hint (workspace->screen);
@ -529,60 +535,55 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
meta_workspace_focus_default_window (workspace, NULL, timestamp);
}
{
/*
* Notify the compositor that the active workspace changed.
*/
MetaScreen *screen = workspace->screen;
MetaDisplay *display = meta_screen_get_display (screen);
MetaCompositor *comp = meta_display_get_compositor (display);
MetaWorkspaceLayout layout1, layout2;
gint num_workspaces, current_space, new_space;
MetaMotionDirection direction = 0;
/*
* Notify the compositor that the active workspace changed.
*/
screen = workspace->screen;
display = meta_screen_get_display (screen);
comp = meta_display_get_compositor (display);
direction = 0;
if (!comp)
return;
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
current_space, &layout1);
current_space = meta_workspace_index (old);
new_space = meta_workspace_index (workspace);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
new_space, &layout2);
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
current_space, &layout1);
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
new_space, &layout2);
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
if (layout1.current_col < layout2.current_col)
direction = META_MOTION_RIGHT;
if (layout1.current_col > layout2.current_col)
direction = META_MOTION_LEFT;
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
if (layout1.current_row < layout2.current_row)
{
if (!direction)
direction = META_MOTION_DOWN;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_DOWN_RIGHT;
else
direction = META_MOTION_DOWN_LEFT;
}
meta_screen_free_workspace_layout (&layout1);
meta_screen_free_workspace_layout (&layout2);
if (layout1.current_row > layout2.current_row)
{
if (!direction)
direction = META_MOTION_UP;
else if (direction == META_MOTION_RIGHT)
direction = META_MOTION_UP_RIGHT;
else
direction = META_MOTION_UP_LEFT;
}
meta_compositor_switch_workspace (comp, screen, old, workspace, direction);
meta_screen_free_workspace_layout (&layout1);
meta_screen_free_workspace_layout (&layout2);
meta_compositor_switch_workspace (comp, screen, old, workspace, direction);
}
/* Emit switched signal from screen.c */
meta_screen_workspace_switched (screen, current_space, new_space, direction);
}
void

View File

@ -233,6 +233,22 @@ typedef enum
META_DIRECTION_VERTICAL = META_DIRECTION_UP | META_DIRECTION_DOWN,
} MetaDirection;
/* Negative to avoid conflicting with real workspace
* numbers
*/
typedef enum
{
META_MOTION_UP = -1,
META_MOTION_DOWN = -2,
META_MOTION_LEFT = -3,
META_MOTION_RIGHT = -4,
/* These are only used for effects */
META_MOTION_UP_LEFT = -5,
META_MOTION_UP_RIGHT = -6,
META_MOTION_DOWN_LEFT = -7,
META_MOTION_DOWN_RIGHT = -8
} MetaMotionDirection;
/* Sometimes we want to talk about sides instead of directions; note
* that the values must be as follows or meta_window_update_struts()
* won't work. Using these values also is a safety blanket since

View File

@ -25,6 +25,7 @@
#include <X11/Xlib.h>
#include <glib-object.h>
#include "types.h"
#include "workspace.h"
#define META_TYPE_SCREEN (meta_screen_get_type ())
#define META_SCREEN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SCREEN, MetaScreen))

View File

@ -37,22 +37,6 @@
#include "boxes.h"
#include "screen.h"
/* Negative to avoid conflicting with real workspace
* numbers
*/
typedef enum
{
META_MOTION_UP = -1,
META_MOTION_DOWN = -2,
META_MOTION_LEFT = -3,
META_MOTION_RIGHT = -4,
/* These are only used for effects */
META_MOTION_UP_LEFT = -5,
META_MOTION_UP_RIGHT = -6,
META_MOTION_DOWN_LEFT = -7,
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))