Merge branch 'tab'

This commit is contained in:
Dan Winship
2009-05-04 13:01:22 -04:00
7 changed files with 529 additions and 1 deletions

View File

@ -49,6 +49,8 @@ CLEANFILES += $(SHELL_STAMP_FILES)
libgnome_shell_la_SOURCES = \
$(shell_built_sources) \
gnome-shell-plugin.c \
shell-alttab.c \
shell-alttab.h \
shell-app-monitor.c \
shell-app-monitor.h \
shell-app-system.c \

230
src/shell-alttab.c Normal file
View File

@ -0,0 +1,230 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "shell-alttab.h"
#include "shell-global.h"
#include "shell-wm.h"
#include <mutter-plugin.h>
/* Our MetaAltTabHandler implementation; ideally we would implement
* this directly from JavaScript, but for now we can't. So we register
* this glue class as our MetaAltTabHandler and then when mutter
* creates one, we pass it on to ShellWM, which emits a signal to hand
* it off to javascript code, which then connects to the signals on
* this object.
*/
static void shell_alt_tab_handler_interface_init (MetaAltTabHandlerInterface *handler_iface);
G_DEFINE_TYPE_WITH_CODE (ShellAltTabHandler, shell_alt_tab_handler, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (META_TYPE_ALT_TAB_HANDLER,
shell_alt_tab_handler_interface_init))
/* Signals */
enum
{
WINDOW_ADDED,
SHOW,
DESTROY,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0 };
enum
{
PROP_SELECTED = 1,
PROP_SCREEN,
PROP_IMMEDIATE
};
static void
shell_alt_tab_handler_init (ShellAltTabHandler *sth)
{
sth->windows = g_ptr_array_new ();
sth->selected = -1;
}
static void
shell_alt_tab_handler_constructed (GObject *object)
{
ShellGlobal *global = shell_global_get ();
ShellWM *wm;
g_object_get (G_OBJECT (global), "window-manager", &wm, NULL);
_shell_wm_begin_alt_tab (wm, SHELL_ALT_TAB_HANDLER (object));
g_object_unref (wm);
}
static void
shell_alt_tab_handler_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (object);
switch (prop_id)
{
case PROP_SCREEN:
/* We don't care */
break;
case PROP_IMMEDIATE:
sth->immediate_mode = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
shell_alt_tab_handler_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (object);
switch (prop_id)
{
case PROP_SELECTED:
g_value_set_int (value, sth->selected);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
shell_alt_tab_handler_finalize (GObject *object)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (object);
g_ptr_array_free (sth->windows, FALSE);
G_OBJECT_CLASS (shell_alt_tab_handler_parent_class)->finalize (object);
}
static void
shell_alt_tab_handler_add_window (MetaAltTabHandler *handler,
MetaWindow *window)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
g_ptr_array_add (sth->windows, window);
g_signal_emit (handler, signals[WINDOW_ADDED], 0,
meta_window_get_compositor_private (window));
}
static void
shell_alt_tab_handler_show (MetaAltTabHandler *handler,
MetaWindow *initial_selection)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
int i;
sth->selected = -1;
for (i = 0; i < sth->windows->len; i++)
{
if (sth->windows->pdata[i] == (gpointer)initial_selection)
{
sth->selected = i;
break;
}
}
g_signal_emit (handler, signals[SHOW], 0, sth->selected);
}
static void
shell_alt_tab_handler_destroy (MetaAltTabHandler *handler)
{
g_signal_emit (handler, signals[DESTROY], 0);
}
static void
shell_alt_tab_handler_forward (MetaAltTabHandler *handler)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
sth->selected = (sth->selected + 1) % sth->windows->len;
g_object_notify (G_OBJECT (handler), "selected");
}
static void
shell_alt_tab_handler_backward (MetaAltTabHandler *handler)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
sth->selected = (sth->selected - 1) % sth->windows->len;
g_object_notify (G_OBJECT (handler), "selected");
}
static MetaWindow *
shell_alt_tab_handler_get_selected (MetaAltTabHandler *handler)
{
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
if (sth->selected > -1)
return sth->windows->pdata[sth->selected];
else
return NULL;
}
static void
shell_alt_tab_handler_class_init (ShellAltTabHandlerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = shell_alt_tab_handler_constructed;
object_class->set_property = shell_alt_tab_handler_set_property;
object_class->get_property = shell_alt_tab_handler_get_property;
object_class->finalize = shell_alt_tab_handler_finalize;
g_object_class_override_property (object_class, PROP_SCREEN, "screen");
g_object_class_override_property (object_class, PROP_IMMEDIATE, "immediate");
g_object_class_install_property (object_class,
PROP_SELECTED,
g_param_spec_int ("selected",
"Selected",
"Selected window",
-1, G_MAXINT, -1,
G_PARAM_READABLE));
signals[WINDOW_ADDED] = g_signal_new ("window-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
MUTTER_TYPE_COMP_WINDOW);
signals[SHOW] = g_signal_new ("show",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
signals[DESTROY] = g_signal_new ("destroy",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
shell_alt_tab_handler_interface_init (MetaAltTabHandlerInterface *handler_iface)
{
handler_iface->add_window = shell_alt_tab_handler_add_window;
handler_iface->show = shell_alt_tab_handler_show;
handler_iface->destroy = shell_alt_tab_handler_destroy;
handler_iface->forward = shell_alt_tab_handler_forward;
handler_iface->backward = shell_alt_tab_handler_backward;
handler_iface->get_selected = shell_alt_tab_handler_get_selected;
}

34
src/shell-alttab.h Normal file
View File

@ -0,0 +1,34 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef SHELL_ALT_TAB_HANDLER_H
#define SHELL_ALT_TAB_HANDLER_H
#include <alttabhandler.h>
#define SHELL_TYPE_ALT_TAB_HANDLER (shell_alt_tab_handler_get_type ())
#define SHELL_ALT_TAB_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_ALT_TAB_HANDLER, ShellAltTabHandler))
#define SHELL_ALT_TAB_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_ALT_TAB_HANDLER, ShellAltTabHandlerClass))
#define SHELL_IS_ALT_TAB_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_ALT_TAB_HANDLER_TYPE))
#define SHELL_IS_ALT_TAB_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_ALT_TAB_HANDLER))
#define SHELL_ALT_TAB_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_ALT_TAB_HANDLER, ShellAltTabHandlerClass))
typedef struct _ShellAltTabHandler ShellAltTabHandler;
typedef struct _ShellAltTabHandlerClass ShellAltTabHandlerClass;
struct _ShellAltTabHandler {
GObject parent_instance;
GPtrArray *windows;
int selected;
gboolean immediate_mode;
};
struct _ShellAltTabHandlerClass {
GObjectClass parent_class;
};
GType shell_alt_tab_handler_get_type (void);
#endif

View File

@ -27,6 +27,8 @@ enum
SWITCH_WORKSPACE,
KILL_SWITCH_WORKSPACE,
BEGIN_ALT_TAB,
LAST_SIGNAL
};
@ -40,6 +42,7 @@ static guint shell_wm_signals [LAST_SIGNAL] = { 0 };
static void
shell_wm_init (ShellWM *wm)
{
meta_alt_tab_handler_register (SHELL_TYPE_ALT_TAB_HANDLER);
}
static void
@ -166,6 +169,15 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
shell_wm_signals[BEGIN_ALT_TAB] =
g_signal_new ("begin-alt-tab",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
META_TYPE_ALT_TAB_HANDLER);
}
void
@ -379,6 +391,14 @@ _shell_wm_destroy (ShellWM *wm,
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
}
/* Called from shell-alttab.c */
void
_shell_wm_begin_alt_tab (ShellWM *wm,
ShellAltTabHandler *handler)
{
g_signal_emit (wm, shell_wm_signals[BEGIN_ALT_TAB], 0, handler);
}
/**
* shell_wm_new:
* @plugin: the #MutterPlugin

View File

@ -4,6 +4,8 @@
#include <glib-object.h>
#include <mutter-plugin.h>
#include "shell-alttab.h"
G_BEGIN_DECLS
typedef struct _ShellWM ShellWM;
@ -71,6 +73,11 @@ void _shell_wm_kill_effect (ShellWM *wm,
MutterWindow *actor,
gulong events);
/* Called by ShellAltTabHandler */
void _shell_wm_begin_alt_tab (ShellWM *wm,
ShellAltTabHandler *handler);
G_END_DECLS
#endif /* __SHELL_WM_H__ */