diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
index 64cc612aa..c8c53d557 100644
--- a/data/theme/gnome-shell-sass/_common.scss
+++ b/data/theme/gnome-shell-sass/_common.scss
@@ -1159,6 +1159,15 @@ StScrollBar {
border: 1px solid $selected_bg_color;
}
+// Pointer location
+.ripple-pointer-location {
+ width: 50px;
+ height: 50px;
+ border-radius: 25px 25px 25px 25px; // radius the size of the box give us the curve
+ background-color: lighten(transparentize($selected_bg_color, 0.7), 30%);
+ box-shadow: 0 0 2px 2px lighten($selected_bg_color, 20%);
+}
+
// not really top bar only
.popup-menu-arrow { icon-size: 1.09em; }
.popup-menu-icon { icon-size: 1.09em; }
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index 135b8e885..7807cce9d 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -64,6 +64,7 @@
ui/keyboard.js
ui/layout.js
ui/lightbox.js
+ ui/locatePointer.js
ui/lookingGlass.js
ui/magnifier.js
ui/magnifierDBus.js
diff --git a/js/ui/locatePointer.js b/js/ui/locatePointer.js
new file mode 100644
index 000000000..52a0bc486
--- /dev/null
+++ b/js/ui/locatePointer.js
@@ -0,0 +1,24 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+const { Clutter, Gio, GLib, St } = imports.gi;
+const Ripples = imports.ui.ripples;
+const Main = imports.ui.main;
+
+const LOCATE_POINTER_KEY = "locate-pointer";
+const LOCATE_POINTER_SCHEMA = "org.gnome.desktop.interface"
+
+var locatePointer = class {
+ constructor() {
+ this._settings = new Gio.Settings({schema_id: LOCATE_POINTER_SCHEMA});
+ this._ripples = new Ripples.Ripples(0.5, 0.5, 'ripple-pointer-location');
+ this._ripples.addTo(Main.uiGroup);
+ }
+
+ show() {
+ if (!this._settings.get_boolean("locate-pointer"))
+ return;
+
+ let [x, y, mods] = global.get_pointer();
+ this._ripples.playAnimation(x, y);
+ }
+};
diff --git a/js/ui/main.js b/js/ui/main.js
index d9f287cd9..b3cd69283 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -37,6 +37,7 @@ const WindowManager = imports.ui.windowManager;
const Magnifier = imports.ui.magnifier;
const XdndHandler = imports.ui.xdndHandler;
const KbdA11yDialog = imports.ui.kbdA11yDialog;
+const LocatePointer = imports.ui.locatePointer;
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
const STICKY_KEYS_ENABLE = 'stickykeys-enable';
@@ -74,6 +75,7 @@ var layoutManager = null;
var kbdA11yDialog = null;
var inputMethod = null;
var introspectService = null;
+var locatePointer = null;
let _startDate;
let _defaultCssStylesheet = null;
let _cssStylesheet = null;
@@ -92,6 +94,8 @@ function _sessionUpdated() {
wm.allowKeybinding('overlay-key', Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW);
+ wm.allowKeybinding('locate-pointer-key', Shell.ActionMode.ALL);
+
wm.setCustomKeybindingHandler('panel-run-dialog',
Shell.ActionMode.NORMAL |
Shell.ActionMode.OVERVIEW,
@@ -165,6 +169,8 @@ function _initializeUI() {
kbdA11yDialog = new KbdA11yDialog.KbdA11yDialog();
wm = new WindowManager.WindowManager();
magnifier = new Magnifier.Magnifier();
+ locatePointer = new LocatePointer.locatePointer();
+
if (LoginManager.canLock())
screenShield = new ScreenShield.ScreenShield();
@@ -190,6 +196,10 @@ function _initializeUI() {
overview.toggle();
});
+ global.connect('locate-pointer', () => {
+ locatePointer.show();
+ });
+
global.display.connect('show-restart-message', (display, message) => {
showRestartMessage(message);
return true;
diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c
index 35a9a8bcb..2e491646c 100644
--- a/src/gnome-shell-plugin.c
+++ b/src/gnome-shell-plugin.c
@@ -346,6 +346,13 @@ gnome_shell_plugin_create_inhibit_shortcuts_dialog (MetaPlugin *plugin,
return _shell_wm_create_inhibit_shortcuts_dialog (get_shell_wm (), window);
}
+static void
+gnome_shell_plugin_locate_pointer (MetaPlugin *plugin)
+{
+ GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin);
+ _shell_global_locate_pointer (shell_plugin->global);
+}
+
static void
gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
{
@@ -378,6 +385,8 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
plugin_class->create_close_dialog = gnome_shell_plugin_create_close_dialog;
plugin_class->create_inhibit_shortcuts_dialog = gnome_shell_plugin_create_inhibit_shortcuts_dialog;
+
+ plugin_class->locate_pointer = gnome_shell_plugin_locate_pointer;
}
static void
diff --git a/src/shell-global-private.h b/src/shell-global-private.h
index df53236aa..9969691cb 100644
--- a/src/shell-global-private.h
+++ b/src/shell-global-private.h
@@ -18,4 +18,6 @@ GjsContext *_shell_global_get_gjs_context (ShellGlobal *global);
gboolean _shell_global_check_xdnd_event (ShellGlobal *global,
XEvent *xev);
+void _shell_global_locate_pointer (ShellGlobal *global);
+
#endif /* __SHELL_GLOBAL_PRIVATE_H__ */
diff --git a/src/shell-global.c b/src/shell-global.c
index 293053d0b..70120c2da 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -115,6 +115,7 @@ enum {
enum
{
NOTIFY_ERROR,
+ LOCATE_POINTER,
LAST_SIGNAL
};
@@ -357,6 +358,13 @@ shell_global_class_init (ShellGlobalClass *klass)
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_STRING);
+ shell_global_signals[LOCATE_POINTER] =
+ g_signal_new ("locate-pointer",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
g_object_class_install_property (gobject_class,
PROP_SESSION_MODE,
@@ -1732,3 +1740,9 @@ shell_global_get_persistent_state (ShellGlobal *global,
{
return load_variant (global->userdatadir_path, property_type, property_name);
}
+
+void
+_shell_global_locate_pointer (ShellGlobal *global)
+{
+ g_signal_emit (global, shell_global_signals[LOCATE_POINTER], 0);
+}