[AppSwitcher] Port Alt-Tab switcher to custom_handler interface
https://bugzilla.gnome.org/show_bug.cgi?id=590563
This commit is contained in:
parent
24d42adc04
commit
11d884d724
@ -37,7 +37,9 @@ AltTabPopup.prototype = {
|
|||||||
corner_radius: POPUP_GRID_SPACING,
|
corner_radius: POPUP_GRID_SPACING,
|
||||||
padding: POPUP_GRID_SPACING,
|
padding: POPUP_GRID_SPACING,
|
||||||
spacing: POPUP_GRID_SPACING,
|
spacing: POPUP_GRID_SPACING,
|
||||||
orientation: Big.BoxOrientation.VERTICAL });
|
orientation: Big.BoxOrientation.VERTICAL,
|
||||||
|
reactive: true });
|
||||||
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
// Icon grid. TODO: Investigate Nbtk.Grid once that lands. Currently
|
// Icon grid. TODO: Investigate Nbtk.Grid once that lands. Currently
|
||||||
// just implemented using a chain of Big.Box.
|
// just implemented using a chain of Big.Box.
|
||||||
@ -70,11 +72,12 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.append(this._indicator, Big.BoxPackFlags.FIXED);
|
this.actor.append(this._indicator, Big.BoxPackFlags.FIXED);
|
||||||
|
|
||||||
this._items = [];
|
this._items = [];
|
||||||
|
this._haveModal = false;
|
||||||
|
|
||||||
global.stage.add_actor(this.actor);
|
global.stage.add_actor(this.actor);
|
||||||
},
|
},
|
||||||
|
|
||||||
addWindow : function(win) {
|
_addWindow : function(win) {
|
||||||
let item = { window: win,
|
let item = { window: win,
|
||||||
metaWindow: win.get_meta_window() };
|
metaWindow: win.get_meta_window() };
|
||||||
|
|
||||||
@ -100,6 +103,31 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
show : function(initialSelection) {
|
show : function(initialSelection) {
|
||||||
|
let appMonitor = Shell.AppMonitor.get_default();
|
||||||
|
let apps = appMonitor.get_running_apps ("");
|
||||||
|
|
||||||
|
if (!apps.length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Main.pushModal(this.actor))
|
||||||
|
return false;
|
||||||
|
this._haveModal = true;
|
||||||
|
|
||||||
|
this._keyPressEventId = global.stage.connect('key-press-event', Lang.bind(this, this._keyPressEvent));
|
||||||
|
this._keyReleaseEventId = global.stage.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent));
|
||||||
|
|
||||||
|
// Fill in the windows
|
||||||
|
let windows = [];
|
||||||
|
for (let i = 0; i < apps.length; i++) {
|
||||||
|
let appWindows = appMonitor.get_windows_for_app(apps[i].get_id());
|
||||||
|
windows = windows.concat(appWindows);
|
||||||
|
}
|
||||||
|
|
||||||
|
windows.sort(function(w1, w2) { return w2.get_user_time() - w1.get_user_time(); });
|
||||||
|
|
||||||
|
for (let i = 0; i < windows.length; i++)
|
||||||
|
this._addWindow(windows[i].get_compositor_private());
|
||||||
|
|
||||||
// Need to specify explicit width and height because the
|
// Need to specify explicit width and height because the
|
||||||
// window_group may not actually cover the whole screen
|
// window_group may not actually cover the whole screen
|
||||||
this._lightbox = new Lightbox.Lightbox(global.window_group,
|
this._lightbox = new Lightbox.Lightbox(global.window_group,
|
||||||
@ -110,15 +138,56 @@ AltTabPopup.prototype = {
|
|||||||
this.actor.x = Math.floor((global.screen_width - this.actor.width) / 2);
|
this.actor.x = Math.floor((global.screen_width - this.actor.width) / 2);
|
||||||
this.actor.y = Math.floor((global.screen_height - this.actor.height) / 2);
|
this.actor.y = Math.floor((global.screen_height - this.actor.height) / 2);
|
||||||
|
|
||||||
this.select(initialSelection);
|
this._updateSelection(initialSelection);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_keyPressEvent : function(actor, event) {
|
||||||
|
let keysym = event.get_key_symbol();
|
||||||
|
let backwards = (event.get_state() & Clutter.ModifierType.SHIFT_MASK);
|
||||||
|
|
||||||
|
if (keysym == Clutter.Tab)
|
||||||
|
this._updateSelection(backwards ? -1 : 1);
|
||||||
|
else if (keysym == Clutter.Escape)
|
||||||
|
this.destroy();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_keyReleaseEvent : function(actor, event) {
|
||||||
|
let keysym = event.get_key_symbol();
|
||||||
|
|
||||||
|
if (keysym == Clutter.Alt_L || keysym == Clutter.Alt_R) {
|
||||||
|
if (this._selected) {
|
||||||
|
Main.activateWindow(this._selected.metaWindow,
|
||||||
|
event.get_time());
|
||||||
|
}
|
||||||
|
this.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy : function() {
|
destroy : function() {
|
||||||
this.actor.destroy();
|
this.actor.destroy();
|
||||||
this._lightbox.destroy();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
select : function(n) {
|
_onDestroy : function() {
|
||||||
|
if (this._haveModal)
|
||||||
|
Main.popModal(this.actor);
|
||||||
|
|
||||||
|
if (this._lightbox)
|
||||||
|
this._lightbox.destroy();
|
||||||
|
|
||||||
|
if (this._keyPressEventId)
|
||||||
|
global.stage.disconnect(this._keyPressEventId);
|
||||||
|
if (this._keyReleaseEventId)
|
||||||
|
global.stage.disconnect(this._keyReleaseEventId);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSelection : function(delta) {
|
||||||
|
let n = ((this._selected ? this._selected.n : 0) + this._items.length + delta) % this._items.length;
|
||||||
|
|
||||||
if (this._selected) {
|
if (this._selected) {
|
||||||
// Unselect previous
|
// Unselect previous
|
||||||
|
|
||||||
@ -177,7 +246,6 @@ AltTabPopup.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_allocationChanged : function() {
|
_allocationChanged : function() {
|
||||||
if (this._selected)
|
this._updateSelection(0);
|
||||||
this.select(this._selected.n);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
const AltTab = imports.ui.altTab;
|
const AltTab = imports.ui.altTab;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
@ -39,7 +40,8 @@ WindowManager.prototype = {
|
|||||||
shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
||||||
shellwm.connect('kill-destroy', Lang.bind(this, this._destroyWindowDone));
|
shellwm.connect('kill-destroy', Lang.bind(this, this._destroyWindowDone));
|
||||||
|
|
||||||
shellwm.connect('begin-alt-tab', Lang.bind(this, this._beginAltTab));
|
shellwm.takeover_keybinding('switch_windows');
|
||||||
|
shellwm.connect('keybinding::switch_windows', Lang.bind(this, this._startAppSwitcher));
|
||||||
},
|
},
|
||||||
|
|
||||||
_shouldAnimate : function(actor) {
|
_shouldAnimate : function(actor) {
|
||||||
@ -300,12 +302,10 @@ WindowManager.prototype = {
|
|||||||
shellwm.completed_switch_workspace();
|
shellwm.completed_switch_workspace();
|
||||||
},
|
},
|
||||||
|
|
||||||
_beginAltTab : function(shellwm, handler) {
|
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
||||||
let popup = new AltTab.AltTabPopup();
|
let tabPopup = new AltTab.AltTabPopup();
|
||||||
|
|
||||||
handler.connect('window-added', function(handler, window) { popup.addWindow(window); });
|
if (!tabPopup.show(backwards ? -1 : 1))
|
||||||
handler.connect('show', function(handler, initialSelection) { popup.show(initialSelection); });
|
tabPopup.destroy();
|
||||||
handler.connect('destroy', function() { popup.destroy(); });
|
}
|
||||||
handler.connect('notify::selected', function() { popup.select(handler.selected); });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -52,8 +52,6 @@ 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 \
|
||||||
|
@ -1,236 +0,0 @@
|
|||||||
/* -*- 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);
|
|
||||||
|
|
||||||
if (sth->selected == sth->windows->len - 1)
|
|
||||||
sth->selected = 0;
|
|
||||||
else
|
|
||||||
sth->selected++;
|
|
||||||
g_object_notify (G_OBJECT (handler), "selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
shell_alt_tab_handler_backward (MetaAltTabHandler *handler)
|
|
||||||
{
|
|
||||||
ShellAltTabHandler *sth = SHELL_ALT_TAB_HANDLER (handler);
|
|
||||||
|
|
||||||
if (sth->selected == 0)
|
|
||||||
sth->selected = sth->windows->len - 1;
|
|
||||||
else
|
|
||||||
sth->selected--;
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/* -*- 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
|
|
||||||
|
|
@ -2,3 +2,4 @@ VOID:INT,INT,INT
|
|||||||
VOID:OBJECT,INT,INT,INT,INT
|
VOID:OBJECT,INT,INT,INT,INT
|
||||||
VOID:BOXED
|
VOID:BOXED
|
||||||
VOID:BOXED,OBJECT
|
VOID:BOXED,OBJECT
|
||||||
|
VOID:STRING,OBJECT,BOOLEAN
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "shell-wm.h"
|
#include "shell-wm.h"
|
||||||
#include "shell-global.h"
|
#include "shell-global.h"
|
||||||
#include "shell-marshal.h"
|
#include "shell-marshal.h"
|
||||||
|
|
||||||
|
#include <keybindings.h>
|
||||||
|
|
||||||
struct _ShellWM {
|
struct _ShellWM {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
@ -27,7 +31,7 @@ enum
|
|||||||
SWITCH_WORKSPACE,
|
SWITCH_WORKSPACE,
|
||||||
KILL_SWITCH_WORKSPACE,
|
KILL_SWITCH_WORKSPACE,
|
||||||
|
|
||||||
BEGIN_ALT_TAB,
|
KEYBINDING,
|
||||||
|
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
@ -42,7 +46,6 @@ 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
|
||||||
@ -169,15 +172,32 @@ 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",
|
/**
|
||||||
|
* ShellWM::keybinding:
|
||||||
|
* @shellwm: the #ShellWM
|
||||||
|
* @binding: the keybinding name
|
||||||
|
* @window: for window keybindings, the #MetaWindow
|
||||||
|
* @backwards: for "reversible" keybindings, whether or not
|
||||||
|
* the backwards (Shifted) variant was invoked
|
||||||
|
*
|
||||||
|
* Emitted when a keybinding captured via
|
||||||
|
* shell_wm_takeover_keybinding() is invoked. The keybinding name
|
||||||
|
* (which has underscores, not hyphens) is also included as the
|
||||||
|
* detail of the signal name, so you can connect just specific
|
||||||
|
* keybindings.
|
||||||
|
*/
|
||||||
|
shell_wm_signals[KEYBINDING] =
|
||||||
|
g_signal_new ("keybinding",
|
||||||
G_TYPE_FROM_CLASS (klass),
|
G_TYPE_FROM_CLASS (klass),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
|
||||||
0,
|
0,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__OBJECT,
|
_shell_marshal_VOID__STRING_OBJECT_BOOLEAN,
|
||||||
G_TYPE_NONE, 1,
|
G_TYPE_NONE, 3,
|
||||||
META_TYPE_ALT_TAB_HANDLER);
|
G_TYPE_STRING,
|
||||||
|
META_TYPE_WINDOW,
|
||||||
|
G_TYPE_BOOLEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -391,14 +411,6 @@ _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
|
||||||
@ -417,3 +429,37 @@ shell_wm_new (MutterPlugin *plugin)
|
|||||||
|
|
||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_wm_key_handler (MetaDisplay *display,
|
||||||
|
MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
XEvent *event,
|
||||||
|
MetaKeyBinding *binding,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
ShellWM *wm = data;
|
||||||
|
gboolean backwards = (event->xkey.state & ShiftMask);
|
||||||
|
|
||||||
|
g_signal_emit (wm, shell_wm_signals[KEYBINDING],
|
||||||
|
g_quark_from_string (binding->name),
|
||||||
|
binding->name, window, backwards);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_wm_takeover_keybinding:
|
||||||
|
* @wm: the #ShellWM
|
||||||
|
* @binding_name: a mutter keybinding name
|
||||||
|
*
|
||||||
|
* Tells mutter to forward keypresses for @binding_name to the shell
|
||||||
|
* rather than processing them internally. This will cause a
|
||||||
|
* #ShellWM::keybinding signal to be emitted when that key is pressed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_wm_takeover_keybinding (ShellWM *wm,
|
||||||
|
const char *binding_name)
|
||||||
|
{
|
||||||
|
meta_keybindings_set_custom_handler (binding_name,
|
||||||
|
shell_wm_key_handler,
|
||||||
|
wm, NULL);
|
||||||
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
#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;
|
||||||
@ -73,10 +71,9 @@ void _shell_wm_kill_effect (ShellWM *wm,
|
|||||||
MutterWindow *actor,
|
MutterWindow *actor,
|
||||||
gulong events);
|
gulong events);
|
||||||
|
|
||||||
/* Called by ShellAltTabHandler */
|
/* Keybinding stuff */
|
||||||
|
void shell_wm_takeover_keybinding (ShellWM *wm,
|
||||||
void _shell_wm_begin_alt_tab (ShellWM *wm,
|
const char *binding_name);
|
||||||
ShellAltTabHandler *handler);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user