Implement MetaAltTabHandler
This is a fairly simple implementation, not all that different from plain metacity's. Further improvements could be made to js/ui/altTab.js in the future. http://bugzilla.gnome.org/show_bug.cgi?id=580917
This commit is contained in:
parent
4a5873dd22
commit
81dbf5118f
221
js/ui/altTab.js
Normal file
221
js/ui/altTab.js
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
const Big = imports.gi.Big;
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Pango = imports.gi.Pango;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Overlay = imports.ui.overlay;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const POPUP_BG_COLOR = new Clutter.Color();
|
||||||
|
POPUP_BG_COLOR.from_pixel(0x00000080);
|
||||||
|
const POPUP_INDICATOR_COLOR = new Clutter.Color();
|
||||||
|
POPUP_INDICATOR_COLOR.from_pixel(0xf0f0f0ff);
|
||||||
|
const POPUP_TRANSPARENT = new Clutter.Color();
|
||||||
|
POPUP_TRANSPARENT.from_pixel(0x00000000);
|
||||||
|
|
||||||
|
const RED = new Clutter.Color();
|
||||||
|
RED.from_pixel(0xff0000ff);
|
||||||
|
const GREEN = new Clutter.Color();
|
||||||
|
GREEN.from_pixel(0x00ff00ff);
|
||||||
|
const BLUE = new Clutter.Color();
|
||||||
|
BLUE.from_pixel(0x0000ffff);
|
||||||
|
|
||||||
|
const POPUP_INDICATOR_WIDTH = 4;
|
||||||
|
const POPUP_GRID_SPACING = 8;
|
||||||
|
const POPUP_ICON_SIZE = 48;
|
||||||
|
const POPUP_NUM_COLUMNS = 5;
|
||||||
|
|
||||||
|
const POPUP_LABEL_MAX_WIDTH = POPUP_NUM_COLUMNS * (POPUP_ICON_SIZE + POPUP_GRID_SPACING);
|
||||||
|
|
||||||
|
const OVERLAY_COLOR = new Clutter.Color();
|
||||||
|
OVERLAY_COLOR.from_pixel(0x00000044);
|
||||||
|
|
||||||
|
function AltTabPopup() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
AltTabPopup.prototype = {
|
||||||
|
_init : function() {
|
||||||
|
let global = Shell.Global.get();
|
||||||
|
|
||||||
|
this.actor = new Big.Box({ background_color : POPUP_BG_COLOR,
|
||||||
|
corner_radius: POPUP_GRID_SPACING,
|
||||||
|
padding: POPUP_GRID_SPACING,
|
||||||
|
spacing: POPUP_GRID_SPACING,
|
||||||
|
orientation: Big.BoxOrientation.VERTICAL });
|
||||||
|
|
||||||
|
// Icon grid. It would be nice to use Tidy.Grid for the this,
|
||||||
|
// but Tidy.Grid is lame in various ways. (Eg, it seems to
|
||||||
|
// have a minimum size of 200x200.) So we create a vertical
|
||||||
|
// Big.Box containing multiple horizontal Big.Boxes.
|
||||||
|
this._grid = new Big.Box({ spacing: POPUP_GRID_SPACING,
|
||||||
|
orientation: Big.BoxOrientation.VERTICAL });
|
||||||
|
let gcenterbox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||||
|
x_align: Big.BoxAlignment.CENTER });
|
||||||
|
gcenterbox.append(this._grid, Big.BoxPackFlags.NONE);
|
||||||
|
this.actor.append(gcenterbox, Big.BoxPackFlags.NONE);
|
||||||
|
|
||||||
|
// Selected-window label
|
||||||
|
this._label = new Clutter.Text({ font_name: "Sans 12",
|
||||||
|
ellipsize: Pango.EllipsizeMode.END });
|
||||||
|
|
||||||
|
let labelbox = new Big.Box({ background_color: POPUP_INDICATOR_COLOR,
|
||||||
|
corner_radius: POPUP_GRID_SPACING / 2,
|
||||||
|
padding: POPUP_GRID_SPACING / 2 });
|
||||||
|
labelbox.append(this._label, Big.BoxPackFlags.EXPAND);
|
||||||
|
let lcenterbox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||||
|
x_align: Big.BoxAlignment.CENTER,
|
||||||
|
width: POPUP_LABEL_MAX_WIDTH + POPUP_GRID_SPACING });
|
||||||
|
lcenterbox.append(labelbox, Big.BoxPackFlags.NONE);
|
||||||
|
this.actor.append(lcenterbox, Big.BoxPackFlags.NONE);
|
||||||
|
|
||||||
|
// Indicator around selected icon
|
||||||
|
this._indicator = new Big.Rectangle({ border_width: POPUP_INDICATOR_WIDTH,
|
||||||
|
corner_radius: POPUP_INDICATOR_WIDTH / 2,
|
||||||
|
border_color: POPUP_INDICATOR_COLOR,
|
||||||
|
color: POPUP_TRANSPARENT });
|
||||||
|
this.actor.append(this._indicator, Big.BoxPackFlags.FIXED);
|
||||||
|
|
||||||
|
this._items = [];
|
||||||
|
this._toplevels = global.window_group.get_children();
|
||||||
|
|
||||||
|
global.stage.add_actor(this.actor);
|
||||||
|
|
||||||
|
// Dark translucent window used to cover all but the
|
||||||
|
// currently-selected window while Alt-Tabbing.
|
||||||
|
// FIXME: share overlay code with runDialog.js
|
||||||
|
this._overlay = new Clutter.Rectangle({ color: OVERLAY_COLOR,
|
||||||
|
width: global.screen_width,
|
||||||
|
height: global.screen_height,
|
||||||
|
border_width: 0,
|
||||||
|
reactive: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
addWindow : function(win) {
|
||||||
|
let item = { window: win,
|
||||||
|
metaWindow: win.get_meta_window() };
|
||||||
|
|
||||||
|
let pixbuf = item.metaWindow.icon;
|
||||||
|
item.icon = new Clutter.Texture({ width: POPUP_ICON_SIZE,
|
||||||
|
height: POPUP_ICON_SIZE,
|
||||||
|
keep_aspect_ratio: true });
|
||||||
|
Shell.clutter_texture_set_from_pixbuf(item.icon, pixbuf);
|
||||||
|
|
||||||
|
item.box = new Big.Box({ padding: POPUP_INDICATOR_WIDTH * 2 });
|
||||||
|
item.box.append(item.icon, Big.BoxPackFlags.NONE);
|
||||||
|
|
||||||
|
item.above = null;
|
||||||
|
for (let i = 1; i < this._toplevels.length; i++) {
|
||||||
|
if (this._toplevels[i] == win) {
|
||||||
|
item.above = this._toplevels[i - 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.n = this._items.length;
|
||||||
|
this._items.push(item);
|
||||||
|
|
||||||
|
// Add it to the grid
|
||||||
|
if (!this._gridRow || this._gridRow.get_children().length == POPUP_NUM_COLUMNS) {
|
||||||
|
this._gridRow = new Big.Box({ spacing: POPUP_GRID_SPACING,
|
||||||
|
orientation: Big.BoxOrientation.HORIZONTAL });
|
||||||
|
this._grid.append(this._gridRow, Big.BoxPackFlags.NONE);
|
||||||
|
}
|
||||||
|
this._gridRow.append(item.box, Big.BoxPackFlags.NONE);
|
||||||
|
},
|
||||||
|
|
||||||
|
show : function(initialSelection) {
|
||||||
|
let global = Shell.Global.get();
|
||||||
|
|
||||||
|
Main.startModal();
|
||||||
|
|
||||||
|
global.window_group.add_actor(this._overlay);
|
||||||
|
this._overlay.raise_top();
|
||||||
|
this._overlay.show();
|
||||||
|
|
||||||
|
this.actor.show_all();
|
||||||
|
this.actor.x = (global.screen_width - this.actor.width) / 2;
|
||||||
|
this.actor.y = (global.screen_height - this.actor.height) / 2;
|
||||||
|
|
||||||
|
this.select(initialSelection);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy : function() {
|
||||||
|
this.actor.hide();
|
||||||
|
this._overlay.hide();
|
||||||
|
this._overlay.unparent();
|
||||||
|
|
||||||
|
Main.endModal();
|
||||||
|
},
|
||||||
|
|
||||||
|
select : function(n) {
|
||||||
|
if (this._selected) {
|
||||||
|
// Unselect previous
|
||||||
|
|
||||||
|
if (this._allocationChangedId) {
|
||||||
|
this._selected.box.disconnect(this._allocationChangedId);
|
||||||
|
delete this._allocationChangedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._selected.above)
|
||||||
|
this._selected.window.raise(this._selected.above);
|
||||||
|
else
|
||||||
|
this._selected.window.lower_bottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = this._items[n];
|
||||||
|
let changed = this._selected && item != this._selected;
|
||||||
|
this._selected = item;
|
||||||
|
|
||||||
|
if (this._selected) {
|
||||||
|
this._label.set_size(-1, -1);
|
||||||
|
this._label.text = this._selected.metaWindow.title;
|
||||||
|
if (this._label.width > POPUP_LABEL_MAX_WIDTH)
|
||||||
|
this._label.width = POPUP_LABEL_MAX_WIDTH;
|
||||||
|
|
||||||
|
// Figure out this._selected.box's coordinates in terms of
|
||||||
|
// this.actor
|
||||||
|
let bx = this._selected.box.x, by = this._selected.box.y;
|
||||||
|
let actor = this._selected.box.get_parent();
|
||||||
|
while (actor != this.actor) {
|
||||||
|
bx += actor.x;
|
||||||
|
by += actor.y;
|
||||||
|
actor = actor.get_parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
Tweener.addTween(this._indicator,
|
||||||
|
{ x: bx,
|
||||||
|
y: by,
|
||||||
|
width: this._selected.box.width,
|
||||||
|
height: this._selected.box.height,
|
||||||
|
time: Overlay.ANIMATION_TIME });
|
||||||
|
} else {
|
||||||
|
Tweener.removeTweens(this.indicator);
|
||||||
|
this._indicator.set_position(bx, by);
|
||||||
|
this._indicator.set_size(this._selected.box.width,
|
||||||
|
this._selected.box.height);
|
||||||
|
}
|
||||||
|
this._indicator.show();
|
||||||
|
|
||||||
|
if (this._overlay.visible)
|
||||||
|
this._selected.window.raise(this._overlay);
|
||||||
|
|
||||||
|
this._allocationChangedId =
|
||||||
|
this._selected.box.connect('notify::allocation',
|
||||||
|
Lang.bind(this, this._allocationChanged));
|
||||||
|
} else {
|
||||||
|
this._label.text = "";
|
||||||
|
this._indicator.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_allocationChanged : function() {
|
||||||
|
if (this._selected)
|
||||||
|
this.select(this._selected.n);
|
||||||
|
}
|
||||||
|
};
|
@ -5,6 +5,7 @@ const Mainloop = imports.mainloop;
|
|||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const AltTab = imports.ui.altTab;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
@ -77,6 +78,11 @@ WindowManager.prototype = {
|
|||||||
function(o, actor) {
|
function(o, actor) {
|
||||||
me._destroyWindowDone(actor);
|
me._destroyWindowDone(actor);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._shellwm.connect('begin-alt-tab',
|
||||||
|
function(o, handler) {
|
||||||
|
me._beginAltTab(handler);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldAnimate : function(actor) {
|
_shouldAnimate : function(actor) {
|
||||||
@ -365,6 +371,14 @@ WindowManager.prototype = {
|
|||||||
switchData.outGroup.destroy();
|
switchData.outGroup.destroy();
|
||||||
|
|
||||||
this._shellwm.completed_switch_workspace();
|
this._shellwm.completed_switch_workspace();
|
||||||
}
|
},
|
||||||
|
|
||||||
|
_beginAltTab : function(handler) {
|
||||||
|
let popup = new AltTab.AltTabPopup();
|
||||||
|
|
||||||
|
handler.connect('window-added', function(handler, window) { popup.addWindow(window); });
|
||||||
|
handler.connect('show', function(handler, initialSelection) { popup.show(initialSelection); });
|
||||||
|
handler.connect('destroy', function() { popup.destroy(); });
|
||||||
|
handler.connect('notify::selected', function() { popup.select(handler.selected); });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -49,6 +49,8 @@ CLEANFILES += $(SHELL_STAMP_FILES)
|
|||||||
libgnome_shell_la_SOURCES = \
|
libgnome_shell_la_SOURCES = \
|
||||||
$(shell_built_sources) \
|
$(shell_built_sources) \
|
||||||
gnome-shell-plugin.c \
|
gnome-shell-plugin.c \
|
||||||
|
shell-alttab.c \
|
||||||
|
shell-alttab.h \
|
||||||
shell-app-monitor.c \
|
shell-app-monitor.c \
|
||||||
shell-app-monitor.h \
|
shell-app-monitor.h \
|
||||||
shell-app-system.c \
|
shell-app-system.c \
|
||||||
|
230
src/shell-alttab.c
Normal file
230
src/shell-alttab.c
Normal 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
34
src/shell-alttab.h
Normal 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
|
||||||
|
|
@ -27,6 +27,8 @@ enum
|
|||||||
SWITCH_WORKSPACE,
|
SWITCH_WORKSPACE,
|
||||||
KILL_SWITCH_WORKSPACE,
|
KILL_SWITCH_WORKSPACE,
|
||||||
|
|
||||||
|
BEGIN_ALT_TAB,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,6 +42,7 @@ static guint shell_wm_signals [LAST_SIGNAL] = { 0 };
|
|||||||
static void
|
static void
|
||||||
shell_wm_init (ShellWM *wm)
|
shell_wm_init (ShellWM *wm)
|
||||||
{
|
{
|
||||||
|
meta_alt_tab_handler_register (SHELL_TYPE_ALT_TAB_HANDLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -166,6 +169,15 @@ shell_wm_class_init (ShellWMClass *klass)
|
|||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE, 0);
|
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
|
void
|
||||||
@ -379,6 +391,14 @@ _shell_wm_destroy (ShellWM *wm,
|
|||||||
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
|
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:
|
* shell_wm_new:
|
||||||
* @plugin: the #MutterPlugin
|
* @plugin: the #MutterPlugin
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <mutter-plugin.h>
|
#include <mutter-plugin.h>
|
||||||
|
|
||||||
|
#include "shell-alttab.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _ShellWM ShellWM;
|
typedef struct _ShellWM ShellWM;
|
||||||
@ -71,6 +73,11 @@ void _shell_wm_kill_effect (ShellWM *wm,
|
|||||||
MutterWindow *actor,
|
MutterWindow *actor,
|
||||||
gulong events);
|
gulong events);
|
||||||
|
|
||||||
|
/* Called by ShellAltTabHandler */
|
||||||
|
|
||||||
|
void _shell_wm_begin_alt_tab (ShellWM *wm,
|
||||||
|
ShellAltTabHandler *handler);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_WM_H__ */
|
#endif /* __SHELL_WM_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user