From 2c17ef480340be0e0bef27eb44dcaef363868413 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Thu, 2 Jul 2009 17:19:02 +0200 Subject: [PATCH] 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. --- configure.in | 3 ++ src/Makefile.am | 55 +++++++++++++++++++++- src/core/screen-private.h | 5 ++ src/core/screen.c | 58 +++++++++++++++++++++++ src/core/workspace.c | 99 ++++++++++++++++++++------------------- src/include/common.h | 16 +++++++ src/include/screen.h | 1 + src/include/workspace.h | 16 ------- 8 files changed, 186 insertions(+), 67 deletions(-) diff --git a/configure.in b/configure.in index 0c933b915..6b647c617 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/src/Makefile.am b/src/Makefile.am index 50cbac889..3c69c17a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 51a430da3..66adf7dec 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -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 diff --git a/src/core/screen.c b/src/core/screen.c index b0c633060..c6d6109c8 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -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 @@ -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); +} + diff --git a/src/core/workspace.c b/src/core/workspace.c index d13735f98..b270e200f 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -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 diff --git a/src/include/common.h b/src/include/common.h index 87a91ee83..1b89c62b6 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -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 diff --git a/src/include/screen.h b/src/include/screen.h index ccaac18ed..600afd5d5 100644 --- a/src/include/screen.h +++ b/src/include/screen.h @@ -25,6 +25,7 @@ #include #include #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)) diff --git a/src/include/workspace.h b/src/include/workspace.h index 972b80b6f..f44aa09d7 100644 --- a/src/include/workspace.h +++ b/src/include/workspace.h @@ -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))