import gnome-shell-3.28.3-10.el8
This commit is contained in:
commit
4360abc774
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
SOURCES/gnome-shell-3.28.3.tar.xz
|
1
.gnome-shell.metadata
Normal file
1
.gnome-shell.metadata
Normal file
@ -0,0 +1 @@
|
||||
767bea7e4715fb951c74a02c26d4b4d8ddecaaaf SOURCES/gnome-shell-3.28.3.tar.xz
|
264
SOURCES/0001-Add-app-introspection-API.patch
Normal file
264
SOURCES/0001-Add-app-introspection-API.patch
Normal file
@ -0,0 +1,264 @@
|
||||
From e9130f3502e36262743a8c1a423a6740b64bcf7f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 5 Sep 2018 11:15:30 +0200
|
||||
Subject: [PATCH 1/2] Add app introspection API
|
||||
|
||||
Add a D-Bus API that allows the API user to introspect the application
|
||||
state of the shell. Currently the only exposed information is list of
|
||||
running applications and which one is active (i.e. has focus).
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/326
|
||||
(cherry picked from commit 10c68c6b952959d105c3126fc61f22a199e8e848)
|
||||
---
|
||||
data/meson.build | 3 +-
|
||||
data/org.gnome.Shell.Introspect.xml | 37 +++++++++
|
||||
data/org.gnome.shell.gschema.xml.in | 8 ++
|
||||
js/js-resources.gresource.xml | 1 +
|
||||
js/misc/introspect.js | 116 ++++++++++++++++++++++++++++
|
||||
js/ui/main.js | 4 +
|
||||
6 files changed, 168 insertions(+), 1 deletion(-)
|
||||
create mode 100644 data/org.gnome.Shell.Introspect.xml
|
||||
create mode 100644 js/misc/introspect.js
|
||||
|
||||
diff --git a/data/meson.build b/data/meson.build
|
||||
index 7c9807721..fee44f02e 100644
|
||||
--- a/data/meson.build
|
||||
+++ b/data/meson.build
|
||||
@@ -46,7 +46,8 @@ dbus_interfaces = [
|
||||
'org.gnome.Shell.Screencast.xml',
|
||||
'org.gnome.Shell.Screenshot.xml',
|
||||
'org.gnome.ShellSearchProvider.xml',
|
||||
- 'org.gnome.ShellSearchProvider2.xml'
|
||||
+ 'org.gnome.ShellSearchProvider2.xml',
|
||||
+ 'org.gnome.Shell.Introspect.xml'
|
||||
]
|
||||
install_data(dbus_interfaces, install_dir: ifacedir)
|
||||
|
||||
diff --git a/data/org.gnome.Shell.Introspect.xml b/data/org.gnome.Shell.Introspect.xml
|
||||
new file mode 100644
|
||||
index 000000000..10c48d635
|
||||
--- /dev/null
|
||||
+++ b/data/org.gnome.Shell.Introspect.xml
|
||||
@@ -0,0 +1,37 @@
|
||||
+<!DOCTYPE node PUBLIC
|
||||
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||
+<node>
|
||||
+
|
||||
+ <!--
|
||||
+ org.gnome.Shell.Introspect:
|
||||
+ @short_description: Introspection interface
|
||||
+
|
||||
+ The interface used to introspect the state of Shell, such as running
|
||||
+ applications, currently active application, etc.
|
||||
+ -->
|
||||
+ <interface name="org.gnome.Shell.Introspect">
|
||||
+
|
||||
+ <!--
|
||||
+ RunningApplicationsChanged:
|
||||
+ @short_description: Notifies when the running applications changes
|
||||
+ -->
|
||||
+ <signal name="RunningApplicationsChanged" />
|
||||
+
|
||||
+ <!--
|
||||
+ GetRunningApplications:
|
||||
+ @short_description: Retrieves the description of all running applications
|
||||
+
|
||||
+ Each application is associated by an application ID. The details of
|
||||
+ each application consists of a varlist of keys and values. Available
|
||||
+ keys are listed below.
|
||||
+
|
||||
+ 'active-on-seats' - (as) list of seats the application is active on
|
||||
+ (a seat only has at most one active
|
||||
+ application)
|
||||
+ -->
|
||||
+ <method name="GetRunningApplications">
|
||||
+ <arg name="apps" direction="out" type="a{sa{sv}}" />
|
||||
+ </method>
|
||||
+ </interface>
|
||||
+</node>
|
||||
diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in
|
||||
index 63a19032d..6917d753d 100644
|
||||
--- a/data/org.gnome.shell.gschema.xml.in
|
||||
+++ b/data/org.gnome.shell.gschema.xml.in
|
||||
@@ -90,6 +90,14 @@
|
||||
adapter is ever seen not to have devices associated to it.
|
||||
</description>
|
||||
</key>
|
||||
+ <key name="introspect" type="b">
|
||||
+ <default>false</default>
|
||||
+ <summary>Enable introspection API</summary>
|
||||
+ <description>
|
||||
+ Enables a D-Bus API that allows to introspect the application state of
|
||||
+ the shell.
|
||||
+ </description>
|
||||
+ </key>
|
||||
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
|
||||
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
|
||||
</schema>
|
||||
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
|
||||
index 883b62d66..77c2c2abb 100644
|
||||
--- a/js/js-resources.gresource.xml
|
||||
+++ b/js/js-resources.gresource.xml
|
||||
@@ -18,6 +18,7 @@
|
||||
<file>misc/history.js</file>
|
||||
<file>misc/ibusManager.js</file>
|
||||
<file>misc/inputMethod.js</file>
|
||||
+ <file>misc/introspect.js</file>
|
||||
<file>misc/jsParse.js</file>
|
||||
<file>misc/keyboardManager.js</file>
|
||||
<file>misc/loginManager.js</file>
|
||||
diff --git a/js/misc/introspect.js b/js/misc/introspect.js
|
||||
new file mode 100644
|
||||
index 000000000..05ef9e637
|
||||
--- /dev/null
|
||||
+++ b/js/misc/introspect.js
|
||||
@@ -0,0 +1,116 @@
|
||||
+const Gio = imports.gi.Gio;
|
||||
+const GLib = imports.gi.GLib;
|
||||
+const Lang = imports.lang;
|
||||
+const Meta = imports.gi.Meta;
|
||||
+const Shell = imports.gi.Shell;
|
||||
+
|
||||
+const INTROSPECT_SCHEMA = 'org.gnome.shell';
|
||||
+const INTROSPECT_KEY = 'introspect';
|
||||
+const APP_WHITELIST = ['org.freedesktop.impl.portal.desktop.gtk'];
|
||||
+
|
||||
+const IntrospectDBusIface = '<node> \
|
||||
+ <interface name="org.gnome.Shell.Introspect"> \
|
||||
+ <signal name="RunningApplicationsChanged" /> \
|
||||
+ <method name="GetRunningApplications"> \
|
||||
+ <arg name="apps" direction="out" type="a{sa{sv}}" /> \
|
||||
+ </method> \
|
||||
+ </interface> \
|
||||
+</node>';
|
||||
+
|
||||
+var IntrospectService = new Lang.Class({
|
||||
+ Name: 'IntrospectService',
|
||||
+
|
||||
+ _init() {
|
||||
+ this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
|
||||
+ this);
|
||||
+ this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Introspect');
|
||||
+ Gio.DBus.session.own_name('org.gnome.Shell.Introspect',
|
||||
+ Gio.BusNameOwnerFlags.REPLACE,
|
||||
+ null, null);
|
||||
+
|
||||
+ this._runningApplications = {};
|
||||
+ this._runningApplicationsDirty = true;
|
||||
+ this._activeApplication = null;
|
||||
+ this._activeApplicationDirty = true;
|
||||
+
|
||||
+ this._appSystem = Shell.AppSystem.get_default();
|
||||
+ this._appSystem.connect('app-state-changed',
|
||||
+ () => {
|
||||
+ this._runningApplicationsDirty = true;
|
||||
+ this._syncRunningApplications();
|
||||
+ });
|
||||
+
|
||||
+ this._settings = new Gio.Settings({ schema_id: INTROSPECT_SCHEMA });
|
||||
+
|
||||
+ let tracker = Shell.WindowTracker.get_default();
|
||||
+ tracker.connect('notify::focus-app',
|
||||
+ () => {
|
||||
+ this._activeApplicationDirty = true;
|
||||
+ this._syncRunningApplications();
|
||||
+ });
|
||||
+
|
||||
+ this._syncRunningApplications();
|
||||
+ },
|
||||
+
|
||||
+ _isStandaloneApp(app) {
|
||||
+ let windows = app.get_windows();
|
||||
+
|
||||
+ return app.get_windows().some(w => w.transient_for == null);
|
||||
+ },
|
||||
+
|
||||
+ _isIntrospectEnabled() {
|
||||
+ return this._settings.get_boolean(INTROSPECT_KEY);
|
||||
+ },
|
||||
+
|
||||
+ _isSenderWhitelisted(sender) {
|
||||
+ return APP_WHITELIST.includes(sender);
|
||||
+ },
|
||||
+
|
||||
+ _syncRunningApplications() {
|
||||
+ let tracker = Shell.WindowTracker.get_default();
|
||||
+ let apps = this._appSystem.get_running();
|
||||
+ let seatName = "seat0";
|
||||
+ let newRunningApplications = {};
|
||||
+
|
||||
+ let newActiveApplication = null;
|
||||
+ let focusedApp = tracker.focus_app;
|
||||
+
|
||||
+ for (let app of apps) {
|
||||
+ let appInfo = {};
|
||||
+ let isAppActive = (focusedApp == app);
|
||||
+
|
||||
+ if (!this._isStandaloneApp(app))
|
||||
+ continue;
|
||||
+
|
||||
+ if (isAppActive) {
|
||||
+ appInfo['active-on-seats'] = new GLib.Variant('as', [seatName]);
|
||||
+ newActiveApplication = app.get_id();
|
||||
+ }
|
||||
+
|
||||
+ newRunningApplications[app.get_id()] = appInfo;
|
||||
+ }
|
||||
+
|
||||
+ if (this._runningApplicationsDirty ||
|
||||
+ (this._activeApplicationDirty &&
|
||||
+ this._activeApplication != newActiveApplication)) {
|
||||
+ this._runningApplications = newRunningApplications;
|
||||
+ this._activeApplication = newActiveApplication;
|
||||
+
|
||||
+ this._dbusImpl.emit_signal('RunningApplicationsChanged', null);
|
||||
+ }
|
||||
+ this._runningApplicationsDirty = false;
|
||||
+ this._activeApplicationDirty = false;
|
||||
+ },
|
||||
+
|
||||
+ GetRunningApplicationsAsync(params, invocation) {
|
||||
+ if (!this._isIntrospectEnabled() &&
|
||||
+ !this._isSenderWhitelisted(invocation.get_sender())) {
|
||||
+ invocation.return_error_literal(Gio.DBusError,
|
||||
+ Gio.DBusError.ACCESS_DENIED,
|
||||
+ 'App introspection not allowed');
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
|
||||
+ }
|
||||
+});
|
||||
diff --git a/js/ui/main.js b/js/ui/main.js
|
||||
index 2c54bb680..0639b5e7d 100644
|
||||
--- a/js/ui/main.js
|
||||
+++ b/js/ui/main.js
|
||||
@@ -20,6 +20,7 @@ const Environment = imports.ui.environment;
|
||||
const ExtensionSystem = imports.ui.extensionSystem;
|
||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||
const InputMethod = imports.misc.inputMethod;
|
||||
+const Introspect = imports.misc.introspect;
|
||||
const Keyboard = imports.ui.keyboard;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@@ -82,6 +83,7 @@ var keyboard = null;
|
||||
var layoutManager = null;
|
||||
var kbdA11yDialog = null;
|
||||
var inputMethod = null;
|
||||
+var introspectService = null;
|
||||
let _startDate;
|
||||
let _defaultCssStylesheet = null;
|
||||
let _cssStylesheet = null;
|
||||
@@ -187,6 +189,8 @@ function _initializeUI() {
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
componentManager = new Components.ComponentManager();
|
||||
|
||||
+ introspectService = new Introspect.IntrospectService();
|
||||
+
|
||||
layoutManager.init();
|
||||
overview.init();
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
153
SOURCES/0001-Add-remote-access-indication-and-control.patch
Normal file
153
SOURCES/0001-Add-remote-access-indication-and-control.patch
Normal file
@ -0,0 +1,153 @@
|
||||
From 8b916620e32ee0b42734dd7896fe5058c8591d81 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 20 Jul 2018 16:50:50 +0200
|
||||
Subject: [PATCH 1/2] Add remote access indication and control
|
||||
|
||||
Add an indicator for when there is something access the display server
|
||||
remotely. This could be 1) remote desktop, 2) screen cast or 3) remote
|
||||
control, but all effectively applications using
|
||||
org.freedesktop.portal.ScreenCast or org.gnome.portal.RemoteDesktop as
|
||||
well as gnome-remote-desktop using the corresponding org.gnome.Mutter
|
||||
APIs directly.
|
||||
|
||||
As it is now, it'll simply show a single icon for when anything is
|
||||
having an active session, and a single action "Turn off" that'll close
|
||||
every active session.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/160
|
||||
---
|
||||
js/js-resources.gresource.xml | 1 +
|
||||
js/ui/panel.js | 3 ++
|
||||
js/ui/status/remoteAccess.js | 80 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 84 insertions(+)
|
||||
create mode 100644 js/ui/status/remoteAccess.js
|
||||
|
||||
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
|
||||
index 883b62d66..cc1da4461 100644
|
||||
--- a/js/js-resources.gresource.xml
|
||||
+++ b/js/js-resources.gresource.xml
|
||||
@@ -130,6 +130,7 @@
|
||||
<file>ui/status/rfkill.js</file>
|
||||
<file>ui/status/volume.js</file>
|
||||
<file>ui/status/bluetooth.js</file>
|
||||
+ <file>ui/status/remoteAccess.js</file>
|
||||
<file>ui/status/screencast.js</file>
|
||||
<file>ui/status/system.js</file>
|
||||
<file>ui/status/thunderbolt.js</file>
|
||||
diff --git a/js/ui/panel.js b/js/ui/panel.js
|
||||
index d44ed9fec..53cc445f8 100644
|
||||
--- a/js/ui/panel.js
|
||||
+++ b/js/ui/panel.js
|
||||
@@ -709,6 +709,7 @@ var AggregateMenu = new Lang.Class({
|
||||
this._bluetooth = null;
|
||||
}
|
||||
|
||||
+ this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet();
|
||||
this._power = new imports.ui.status.power.Indicator();
|
||||
this._rfkill = new imports.ui.status.rfkill.Indicator();
|
||||
this._volume = new imports.ui.status.volume.Indicator();
|
||||
@@ -729,6 +730,7 @@ var AggregateMenu = new Lang.Class({
|
||||
if (this._bluetooth) {
|
||||
this._indicators.add_child(this._bluetooth.indicators);
|
||||
}
|
||||
+ this._indicators.add_child(this._remoteAccess.indicators);
|
||||
this._indicators.add_child(this._rfkill.indicators);
|
||||
this._indicators.add_child(this._volume.indicators);
|
||||
this._indicators.add_child(this._power.indicators);
|
||||
@@ -743,6 +745,7 @@ var AggregateMenu = new Lang.Class({
|
||||
if (this._bluetooth) {
|
||||
this.menu.addMenuItem(this._bluetooth.menu);
|
||||
}
|
||||
+ this.menu.addMenuItem(this._remoteAccess.menu);
|
||||
this.menu.addMenuItem(this._location.menu);
|
||||
this.menu.addMenuItem(this._rfkill.menu);
|
||||
this.menu.addMenuItem(this._power.menu);
|
||||
diff --git a/js/ui/status/remoteAccess.js b/js/ui/status/remoteAccess.js
|
||||
new file mode 100644
|
||||
index 000000000..ffa334001
|
||||
--- /dev/null
|
||||
+++ b/js/ui/status/remoteAccess.js
|
||||
@@ -0,0 +1,80 @@
|
||||
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
+
|
||||
+const Lang = imports.lang;
|
||||
+const Meta = imports.gi.Meta;
|
||||
+
|
||||
+const PanelMenu = imports.ui.panelMenu;
|
||||
+const PopupMenu = imports.ui.popupMenu;
|
||||
+
|
||||
+var RemoteAccessApplet = new Lang.Class({
|
||||
+ Name: 'RemoteAccessApplet',
|
||||
+ Extends: PanelMenu.SystemIndicator,
|
||||
+
|
||||
+ _init() {
|
||||
+ this.parent();
|
||||
+
|
||||
+ let backend = Meta.get_backend();
|
||||
+ let controller = backend.get_remote_access_controller();
|
||||
+
|
||||
+ if (!controller)
|
||||
+ return;
|
||||
+
|
||||
+ // We can't possibly know about all types of screen sharing on X11, so
|
||||
+ // showing these controls on X11 might give a false sense of security.
|
||||
+ // Thus, only enable these controls when using Wayland, where we are
|
||||
+ // in control of sharing.
|
||||
+ if (!Meta.is_wayland_compositor())
|
||||
+ return;
|
||||
+
|
||||
+ this._handles = new Set();
|
||||
+ this._indicator = null;
|
||||
+ this._menuSection = null;
|
||||
+
|
||||
+ controller.connect('new-handle', (controller, handle) => {
|
||||
+ this._onNewHandle(handle);
|
||||
+ });
|
||||
+ },
|
||||
+
|
||||
+ _ensureControls() {
|
||||
+ if (this._indicator)
|
||||
+ return;
|
||||
+
|
||||
+ this._indicator = this._addIndicator();
|
||||
+ this._indicator.icon_name = 'screen-shared-symbolic';
|
||||
+ this._item =
|
||||
+ new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
|
||||
+ true);
|
||||
+ this._item.menu.addAction(_("Turn off"),
|
||||
+ () => {
|
||||
+ for (let handle of this._handles)
|
||||
+ handle.stop();
|
||||
+ });
|
||||
+ this._item.icon.icon_name = 'screen-shared-symbolic';
|
||||
+ this.menu.addMenuItem(this._item);
|
||||
+ },
|
||||
+
|
||||
+ _sync() {
|
||||
+ if (this._handles.size == 0) {
|
||||
+ this._indicator.visible = false;
|
||||
+ this._item.actor.visible = false;
|
||||
+ } else {
|
||||
+ this._indicator.visible = true;
|
||||
+ this._item.actor.visible = true;
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ _onStopped(handle) {
|
||||
+ this._handles.delete(handle);
|
||||
+ this._sync();
|
||||
+ },
|
||||
+
|
||||
+ _onNewHandle(handle) {
|
||||
+ this._handles.add(handle);
|
||||
+ handle.connect('stopped', this._onStopped.bind(this));
|
||||
+
|
||||
+ if (this._handles.size == 1) {
|
||||
+ this._ensureControls();
|
||||
+ this._sync();
|
||||
+ }
|
||||
+ },
|
||||
+});
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,39 @@
|
||||
From 8f66d508bad63412f61d2162bb05224ee1637ab1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Fri, 16 Nov 2018 11:39:08 +0100
|
||||
Subject: [PATCH] altSwitcher: Fix error when all alternatives are disabled
|
||||
|
||||
While we do consider the case that we don't have a child to show for the
|
||||
visibility, we are still trying to move the click action unconditionally.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/783
|
||||
---
|
||||
js/ui/status/system.js | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/ui/status/system.js b/js/ui/status/system.js
|
||||
index 68a0b4b5b..cd6f3d8b0 100644
|
||||
--- a/js/ui/status/system.js
|
||||
+++ b/js/ui/status/system.js
|
||||
@@ -58,6 +58,9 @@ var AltSwitcher = new Lang.Class({
|
||||
childToShow = this._standard;
|
||||
} else if (this._alternate.visible) {
|
||||
childToShow = this._alternate;
|
||||
+ } else {
|
||||
+ this.actor.hide();
|
||||
+ return;
|
||||
}
|
||||
|
||||
let childShown = this.actor.get_child();
|
||||
@@ -79,7 +82,7 @@ var AltSwitcher = new Lang.Class({
|
||||
global.sync_pointer();
|
||||
}
|
||||
|
||||
- this.actor.visible = (childToShow != null);
|
||||
+ this.actor.show();
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
--
|
||||
2.20.1
|
||||
|
34
SOURCES/0001-app-Close-all-closable-windows-from-quit.patch
Normal file
34
SOURCES/0001-app-Close-all-closable-windows-from-quit.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 9b8a85d42d1c74f6a0815d23a484af3883284538 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 3 Sep 2018 17:10:27 +0200
|
||||
Subject: [PATCH] app: Close all closable windows from quit()
|
||||
|
||||
There's no relation between a window being hidden from overview/taskbars
|
||||
and a window not being closable - currently we effectively disable the
|
||||
fallback quit action for any application with open transients, which
|
||||
simply doesn't make sense.
|
||||
|
||||
Instead, only exclude windows for which the close action has been
|
||||
explicitly disabled.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/217
|
||||
---
|
||||
src/shell-app.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shell-app.c b/src/shell-app.c
|
||||
index 84fcc97bf..1a6d5888d 100644
|
||||
--- a/src/shell-app.c
|
||||
+++ b/src/shell-app.c
|
||||
@@ -1159,7 +1159,7 @@ shell_app_request_quit (ShellApp *app)
|
||||
{
|
||||
MetaWindow *win = iter->data;
|
||||
|
||||
- if (meta_window_is_skip_taskbar (win))
|
||||
+ if (!meta_window_can_close (win))
|
||||
continue;
|
||||
|
||||
meta_window_delete (win, shell_global_get_current_time (shell_global_get ()));
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,28 @@
|
||||
From e4049af3ca6fa37b5d8b09e6bdcbb32e3d9b0849 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Wed, 20 May 2015 16:44:00 +0200
|
||||
Subject: [PATCH] app: Fall back to window title instead of WM_CLASS
|
||||
|
||||
It's a bad fallback as it's clearly window-specific (rather than
|
||||
app-specific), but it likely looks prettier when we fail to associate
|
||||
a .desktop file ...
|
||||
---
|
||||
src/shell-app.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/shell-app.c b/src/shell-app.c
|
||||
index dbf537ce9..84fcc97bf 100644
|
||||
--- a/src/shell-app.c
|
||||
+++ b/src/shell-app.c
|
||||
@@ -265,7 +265,7 @@ shell_app_get_name (ShellApp *app)
|
||||
const char *name = NULL;
|
||||
|
||||
if (window)
|
||||
- name = meta_window_get_wm_class (window);
|
||||
+ name = meta_window_get_title (window);
|
||||
if (!name)
|
||||
name = C_("program", "Unknown");
|
||||
return name;
|
||||
--
|
||||
2.20.1
|
||||
|
111
SOURCES/0001-appDisplay-Show-full-app-name-on-hover.patch
Normal file
111
SOURCES/0001-appDisplay-Show-full-app-name-on-hover.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From fb3165447d4dac048d0b085bf0266027da66df2c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Thu, 21 Jun 2018 18:03:31 +0200
|
||||
Subject: [PATCH] appDisplay: Show full app name on hover
|
||||
|
||||
---
|
||||
data/theme/gnome-shell-sass/_common.scss | 8 ++++
|
||||
js/ui/appDisplay.js | 48 ++++++++++++++++++++++++
|
||||
2 files changed, 56 insertions(+)
|
||||
|
||||
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
|
||||
index f1aaea689..5bf01a540 100644
|
||||
--- a/data/theme/gnome-shell-sass/_common.scss
|
||||
+++ b/data/theme/gnome-shell-sass/_common.scss
|
||||
@@ -1402,6 +1402,14 @@ StScrollBar {
|
||||
|
||||
}
|
||||
|
||||
+ .app-well-hover-text {
|
||||
+ text-align: center;
|
||||
+ color: $osd_fg_color;
|
||||
+ background-color: $osd_bg_color;
|
||||
+ border-radius: 5px;
|
||||
+ padding: 3px;
|
||||
+ }
|
||||
+
|
||||
.app-well-app-running-dot { //running apps indicator
|
||||
width: 10px; height: 3px;
|
||||
background-color: $selected_bg_color;
|
||||
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
|
||||
index 74c772d50..070057c69 100644
|
||||
--- a/js/ui/appDisplay.js
|
||||
+++ b/js/ui/appDisplay.js
|
||||
@@ -1628,6 +1628,20 @@ var AppIcon = new Lang.Class({
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
this.actor.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
|
||||
|
||||
+ this._hoverText = null;
|
||||
+ this._hoverTimeoutId = 0;
|
||||
+
|
||||
+ if (this.icon.label) {
|
||||
+ this._hoverText = new St.Label({ style_class: 'app-well-hover-text',
|
||||
+ text: this.icon.label.text,
|
||||
+ visible: false });
|
||||
+ this._hoverText.clutter_text.line_wrap = true;
|
||||
+ Main.layoutManager.addChrome(this._hoverText);
|
||||
+
|
||||
+ this.actor.connect('notify::hover', this._syncHoverText.bind(this));
|
||||
+ this.connect('sync-tooltip', this._syncHoverText.bind(this));
|
||||
+ }
|
||||
+
|
||||
this._menu = null;
|
||||
this._menuManager = new PopupMenu.PopupMenuManager(this);
|
||||
|
||||
@@ -1659,12 +1673,39 @@ var AppIcon = new Lang.Class({
|
||||
this.app.disconnect(this._stateChangedId);
|
||||
this._stateChangedId = 0;
|
||||
this._removeMenuTimeout();
|
||||
+ this._removeHoverTimeout();
|
||||
+ if (this._hoverText)
|
||||
+ this._hoverText.destroy();
|
||||
+ this._hoverText = null;
|
||||
},
|
||||
|
||||
_createIcon(iconSize) {
|
||||
return this.app.create_icon_texture(iconSize);
|
||||
},
|
||||
|
||||
+ _syncHoverText() {
|
||||
+ if (this.shouldShowTooltip()) {
|
||||
+ if (this._hoverTimeoutId)
|
||||
+ return;
|
||||
+
|
||||
+ this._hoverTimeoutId = Mainloop.timeout_add(300, () => {
|
||||
+ this._hoverText.style = `max-width: ${2 * this.icon.iconSize}px;`;
|
||||
+ this._hoverText.ensure_style();
|
||||
+
|
||||
+ let [x, y] = this.icon.label.get_transformed_position();
|
||||
+ let offset = (this._hoverText.width - this.icon.label.width) / 2;
|
||||
+ this._hoverText.set_position(Math.floor(x - offset), Math.floor(y));
|
||||
+ this._hoverText.show();
|
||||
+
|
||||
+ this._hoverTimeoutId = 0;
|
||||
+ return GLib.SOURCE_REMOVE;
|
||||
+ });
|
||||
+ } else {
|
||||
+ this._removeHoverTimeout();
|
||||
+ this._hoverText.hide();
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
_removeMenuTimeout() {
|
||||
if (this._menuTimeoutId > 0) {
|
||||
Mainloop.source_remove(this._menuTimeoutId);
|
||||
@@ -1672,6 +1713,13 @@ var AppIcon = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
+ _removeHoverTimeout() {
|
||||
+ if (this._hoverTimeoutId > 0) {
|
||||
+ Mainloop.source_remove(this._hoverTimeoutId);
|
||||
+ this._hoverTimeoutId = 0;
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
_updateRunningStyle() {
|
||||
if (this.app.state != Shell.AppState.STOPPED)
|
||||
this._dot.show();
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,83 @@
|
||||
From 2d63749878c1afa7d83a44c4d5e6c1aec3414b71 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 15 Jan 2019 12:51:16 -0500
|
||||
Subject: [PATCH 1/4] background: refresh after suspend on wayland
|
||||
|
||||
At the moment we only refresh after suspend on Xorg.
|
||||
|
||||
We need to do it on wayland, too.
|
||||
---
|
||||
src/shell-util.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/src/shell-util.c b/src/shell-util.c
|
||||
index 70b8c0611..c43bf4cc5 100644
|
||||
--- a/src/shell-util.c
|
||||
+++ b/src/shell-util.c
|
||||
@@ -372,63 +372,60 @@ shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
|
||||
clutter_actor_show (CLUTTER_ACTOR (texture));
|
||||
clutter_texture_set_cogl_texture (texture, sprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_hide (CLUTTER_ACTOR (texture));
|
||||
}
|
||||
}
|
||||
|
||||
typedef const gchar *(*ShellGLGetString) (GLenum);
|
||||
|
||||
static const gchar *
|
||||
get_gl_vendor (void)
|
||||
{
|
||||
static const gchar *vendor = NULL;
|
||||
|
||||
if (!vendor)
|
||||
{
|
||||
ShellGLGetString gl_get_string;
|
||||
gl_get_string = (ShellGLGetString) cogl_get_proc_address ("glGetString");
|
||||
if (gl_get_string)
|
||||
vendor = gl_get_string (GL_VENDOR);
|
||||
}
|
||||
|
||||
return vendor;
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_util_need_background_refresh (void)
|
||||
{
|
||||
- if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
- return FALSE;
|
||||
-
|
||||
if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
canvas_draw_cb (ClutterContent *content,
|
||||
cairo_t *cr,
|
||||
gint width,
|
||||
gint height,
|
||||
gpointer user_data)
|
||||
{
|
||||
cairo_surface_t *surface = user_data;
|
||||
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_util_get_content_for_window_actor:
|
||||
* @window_actor: a #MetaWindowActor
|
||||
* @window_rect: a #MetaRectangle
|
||||
*
|
||||
* Returns: (transfer full): a new #ClutterContent
|
||||
*/
|
||||
ClutterContent *
|
||||
shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
|
||||
--
|
||||
2.18.1
|
||||
|
@ -0,0 +1,37 @@
|
||||
From 23a06b9b965f6de4d58d3addf2a73dd7b6c15e29 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Thu, 8 Jun 2017 12:04:31 -0400
|
||||
Subject: [PATCH] data: install process-working.svg to filesystem
|
||||
|
||||
This helps prevent unlock failure on inplace upgrades between
|
||||
7.3 and 7.4
|
||||
---
|
||||
data/theme/meson.build | 2 ++
|
||||
meson.build | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/data/theme/meson.build b/data/theme/meson.build
|
||||
index 22bae3dd2..d5acb8d10 100644
|
||||
--- a/data/theme/meson.build
|
||||
+++ b/data/theme/meson.build
|
||||
@@ -23,3 +23,5 @@ foreach style: styles
|
||||
],
|
||||
depend_files: theme_sources)
|
||||
endforeach
|
||||
+
|
||||
+install_data('process-working.svg', install_dir: themedir)
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 663a4d06f..353eff05a 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -56,6 +56,7 @@ mozplugindir = join_paths(libdir, 'mozilla', 'plugins')
|
||||
portaldir = join_paths(datadir, 'xdg-desktop-portal', 'portals')
|
||||
schemadir = join_paths(datadir, 'glib-2.0', 'schemas')
|
||||
servicedir = join_paths(datadir, 'dbus-1', 'services')
|
||||
+themedir = join_paths(pkgdatadir, 'theme')
|
||||
|
||||
plugindir = get_variable('BROWSER_PLUGIN_DIR', mozplugindir)
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,69 @@
|
||||
From 45730de08bf34ac5e3e55eeac843bf640af031bb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 21 Sep 2015 20:18:12 +0200
|
||||
Subject: [PATCH] extensionSystem: Notify about extension issues on update
|
||||
|
||||
---
|
||||
js/ui/extensionSystem.js | 32 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 32 insertions(+)
|
||||
|
||||
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
|
||||
index a013a3ee7..9b6fcb60b 100644
|
||||
--- a/js/ui/extensionSystem.js
|
||||
+++ b/js/ui/extensionSystem.js
|
||||
@@ -7,6 +7,7 @@ const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const St = imports.gi.St;
|
||||
|
||||
+const Config = imports.misc.config;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
@@ -306,6 +307,36 @@ function _onVersionValidationChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
+function _doUpdateCheck() {
|
||||
+ let version = Config.PACKAGE_VERSION.split('.');
|
||||
+ if (parseInt(version[1]) % 2 == 0)
|
||||
+ version.pop();
|
||||
+
|
||||
+ let pkgCacheDir = GLib.get_user_cache_dir() + '/gnome-shell/';
|
||||
+ let updateStamp = Gio.file_new_for_path(pkgCacheDir +
|
||||
+ 'update-check-' + version.join('.'));
|
||||
+ if (updateStamp.query_exists(null))
|
||||
+ return;
|
||||
+
|
||||
+ GLib.mkdir_with_parents (pkgCacheDir, 0o755);
|
||||
+ updateStamp.create(0, null).close(null);
|
||||
+
|
||||
+ let nOutdated = enabledExtensions.reduce(function(n, uuid) {
|
||||
+ let extension = ExtensionUtils.extensions[uuid];
|
||||
+ if (extension && extension.state == ExtensionState.OUT_OF_DATE)
|
||||
+ n++;
|
||||
+ return n;
|
||||
+ }, 0);
|
||||
+
|
||||
+ if (nOutdated == 0)
|
||||
+ return;
|
||||
+
|
||||
+ Main.notify(ngettext("%d extension is out of date",
|
||||
+ "%d extensions are out of date",
|
||||
+ nOutdated).format(nOutdated),
|
||||
+ _("You can visit http://extensions.gnome.org for updates"));
|
||||
+}
|
||||
+
|
||||
function _loadExtensions() {
|
||||
global.settings.connect('changed::' + ENABLED_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||
global.settings.connect('changed::' + DISABLE_USER_EXTENSIONS_KEY, onEnabledExtensionsChanged);
|
||||
@@ -320,6 +351,7 @@ function _loadExtensions() {
|
||||
extension.type = ExtensionUtils.ExtensionType.SESSION_MODE;
|
||||
});
|
||||
finder.scanExtensions();
|
||||
+ _doUpdateCheck();
|
||||
}
|
||||
|
||||
function enableAllExtensions() {
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 55bd98676e92f181c85813b1d16e92a9769c901f Mon Sep 17 00:00:00 2001
|
||||
From: Rui Matos <tiagomatos@gmail.com>
|
||||
Date: Fri, 8 Nov 2013 13:58:09 +0100
|
||||
Subject: [PATCH] extensions: Add a SESSION_MODE extension type
|
||||
|
||||
This allows e.g. gnome-tweak-tool to present these extensions in a
|
||||
different way since they can't be disabled.
|
||||
---
|
||||
js/misc/extensionUtils.js | 3 ++-
|
||||
js/ui/extensionSystem.js | 2 ++
|
||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/misc/extensionUtils.js b/js/misc/extensionUtils.js
|
||||
index 9f77b4c40..1e25da335 100644
|
||||
--- a/js/misc/extensionUtils.js
|
||||
+++ b/js/misc/extensionUtils.js
|
||||
@@ -13,7 +13,8 @@ const FileUtils = imports.misc.fileUtils;
|
||||
|
||||
var ExtensionType = {
|
||||
SYSTEM: 1,
|
||||
- PER_USER: 2
|
||||
+ PER_USER: 2,
|
||||
+ SESSION_MODE: 3
|
||||
};
|
||||
|
||||
// Maps uuid -> metadata object
|
||||
diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js
|
||||
index e35c01ab8..a013a3ee7 100644
|
||||
--- a/js/ui/extensionSystem.js
|
||||
+++ b/js/ui/extensionSystem.js
|
||||
@@ -316,6 +316,8 @@ function _loadExtensions() {
|
||||
let finder = new ExtensionUtils.ExtensionFinder();
|
||||
finder.connect('extension-found', (finder, extension) => {
|
||||
loadExtension(extension);
|
||||
+ if (Main.sessionMode.enabledExtensions.indexOf(extension.uuid) != -1)
|
||||
+ extension.type = ExtensionUtils.ExtensionType.SESSION_MODE;
|
||||
});
|
||||
finder.scanExtensions();
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
237
SOURCES/0001-gdm-add-AuthList-control.patch
Normal file
237
SOURCES/0001-gdm-add-AuthList-control.patch
Normal file
@ -0,0 +1,237 @@
|
||||
From e2e03a9e78b63712fd2c322d4f1aaab6ba1fdc7f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 18 Jul 2017 12:58:14 -0400
|
||||
Subject: [PATCH 1/2] gdm: add AuthList control
|
||||
|
||||
Ultimately, we want to add support for GDM's new ChoiceList
|
||||
PAM extension. That extension allows PAM modules to present
|
||||
a list of choices to the user. Before we can support that
|
||||
extension, however, we need to have a list control in the
|
||||
login-screen/unlock screen. This commit adds that control.
|
||||
|
||||
For the most part, it's a copy-and-paste of the gdm userlist,
|
||||
but with less features. It lacks API specific to the users,
|
||||
lacks the built in timed login indicator, etc. It does feature
|
||||
a label heading.
|
||||
---
|
||||
js/gdm/authList.js | 195 ++++++++++++++++++++++++++++++++++
|
||||
js/js-resources.gresource.xml | 1 +
|
||||
2 files changed, 196 insertions(+)
|
||||
create mode 100644 js/gdm/authList.js
|
||||
|
||||
diff --git a/js/gdm/authList.js b/js/gdm/authList.js
|
||||
new file mode 100644
|
||||
index 000000000..fc1c3d6e4
|
||||
--- /dev/null
|
||||
+++ b/js/gdm/authList.js
|
||||
@@ -0,0 +1,195 @@
|
||||
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
+/*
|
||||
+ * Copyright 2017 Red Hat, Inc
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2, or (at your option)
|
||||
+ * any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+const Clutter = imports.gi.Clutter;
|
||||
+const GObject = imports.gi.GObject;
|
||||
+const Gtk = imports.gi.Gtk;
|
||||
+const Lang = imports.lang;
|
||||
+const Meta = imports.gi.Meta;
|
||||
+const Signals = imports.signals;
|
||||
+const St = imports.gi.St;
|
||||
+
|
||||
+const Tweener = imports.ui.tweener;
|
||||
+
|
||||
+const _SCROLL_ANIMATION_TIME = 0.5;
|
||||
+
|
||||
+const AuthListItem = new Lang.Class({
|
||||
+ Name: 'AuthListItem',
|
||||
+
|
||||
+ _init(key, text) {
|
||||
+ this.key = key;
|
||||
+ let label = new St.Label({ style_class: 'auth-list-item-label',
|
||||
+ y_align: Clutter.ActorAlign.CENTER });
|
||||
+ label.text = text;
|
||||
+
|
||||
+ this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
||||
+ button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||
+ can_focus: true,
|
||||
+ child: label,
|
||||
+ reactive: true,
|
||||
+ x_align: St.Align.START,
|
||||
+ x_fill: true });
|
||||
+
|
||||
+ this.actor.connect('key-focus-in', () => {
|
||||
+ this._setSelected(true);
|
||||
+ });
|
||||
+ this.actor.connect('key-focus-out', () => {
|
||||
+ this._setSelected(false);
|
||||
+ });
|
||||
+ this.actor.connect('notify::hover', () => {
|
||||
+ this._setSelected(this.actor.hover);
|
||||
+ });
|
||||
+
|
||||
+ this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
+ },
|
||||
+
|
||||
+ _onClicked() {
|
||||
+ this.emit('activate');
|
||||
+ },
|
||||
+
|
||||
+ _setSelected(selected) {
|
||||
+ if (selected) {
|
||||
+ this.actor.add_style_pseudo_class('selected');
|
||||
+ this.actor.grab_key_focus();
|
||||
+ } else {
|
||||
+ this.actor.remove_style_pseudo_class('selected');
|
||||
+ }
|
||||
+ }
|
||||
+});
|
||||
+Signals.addSignalMethods(AuthListItem.prototype);
|
||||
+
|
||||
+const AuthList = new Lang.Class({
|
||||
+ Name: 'AuthList',
|
||||
+
|
||||
+ _init() {
|
||||
+ this.actor = new St.BoxLayout({ vertical: true,
|
||||
+ style_class: 'login-dialog-auth-list-layout' });
|
||||
+
|
||||
+ this.label = new St.Label({ style_class: 'prompt-dialog-headline' });
|
||||
+ this.actor.add_actor(this.label);
|
||||
+
|
||||
+ this._scrollView = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
||||
+ this._scrollView.set_policy(Gtk.PolicyType.NEVER,
|
||||
+ Gtk.PolicyType.AUTOMATIC);
|
||||
+ this.actor.add_actor(this._scrollView);
|
||||
+
|
||||
+ this._box = new St.BoxLayout({ vertical: true,
|
||||
+ style_class: 'login-dialog-user-list',
|
||||
+ pseudo_class: 'expanded' });
|
||||
+
|
||||
+ this._scrollView.add_actor(this._box);
|
||||
+ this._items = {};
|
||||
+
|
||||
+ this.actor.connect('key-focus-in', this._moveFocusToItems.bind(this));
|
||||
+ },
|
||||
+
|
||||
+ _moveFocusToItems() {
|
||||
+ let hasItems = Object.keys(this._items).length > 0;
|
||||
+
|
||||
+ if (!hasItems)
|
||||
+ return;
|
||||
+
|
||||
+ if (global.stage.get_key_focus() != this.actor)
|
||||
+ return;
|
||||
+
|
||||
+ let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||
+ if (!focusSet) {
|
||||
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
||||
+ this._moveFocusToItems();
|
||||
+ return false;
|
||||
+ });
|
||||
+ }
|
||||
+ },
|
||||
+
|
||||
+ _onItemActivated(activatedItem) {
|
||||
+ this.emit('activate', activatedItem.key);
|
||||
+ },
|
||||
+
|
||||
+ scrollToItem(item) {
|
||||
+ let box = item.actor.get_allocation_box();
|
||||
+
|
||||
+ let adjustment = this._scrollView.get_vscroll_bar().get_adjustment();
|
||||
+
|
||||
+ let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
+ Tweener.removeTweens(adjustment);
|
||||
+ Tweener.addTween (adjustment,
|
||||
+ { value: value,
|
||||
+ time: _SCROLL_ANIMATION_TIME,
|
||||
+ transition: 'easeOutQuad' });
|
||||
+ },
|
||||
+
|
||||
+ jumpToItem(item) {
|
||||
+ let box = item.actor.get_allocation_box();
|
||||
+
|
||||
+ let adjustment = this._scrollView.get_vscroll_bar().get_adjustment();
|
||||
+
|
||||
+ let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
||||
+
|
||||
+ adjustment.set_value(value);
|
||||
+ },
|
||||
+
|
||||
+ getItem(key) {
|
||||
+ let item = this._items[key];
|
||||
+
|
||||
+ if (!item)
|
||||
+ return null;
|
||||
+
|
||||
+ return item;
|
||||
+ },
|
||||
+
|
||||
+ addItem(key, text) {
|
||||
+ this.removeItem(key);
|
||||
+
|
||||
+ let item = new AuthListItem(key, text);
|
||||
+ this._box.add(item.actor, { x_fill: true });
|
||||
+
|
||||
+ this._items[key] = item;
|
||||
+
|
||||
+ item.connect('activate',
|
||||
+ this._onItemActivated.bind(this));
|
||||
+
|
||||
+ // Try to keep the focused item front-and-center
|
||||
+ item.actor.connect('key-focus-in',
|
||||
+ () => { this.scrollToItem(item); });
|
||||
+
|
||||
+ this._moveFocusToItems();
|
||||
+
|
||||
+ this.emit('item-added', item);
|
||||
+ },
|
||||
+
|
||||
+ removeItem(key) {
|
||||
+ let item = this._items[key];
|
||||
+
|
||||
+ if (!item)
|
||||
+ return;
|
||||
+
|
||||
+ item.actor.destroy();
|
||||
+ delete this._items[key];
|
||||
+ },
|
||||
+
|
||||
+ numItems() {
|
||||
+ return Object.keys(this._items).length;
|
||||
+ },
|
||||
+
|
||||
+ clear() {
|
||||
+ this.label.text = "";
|
||||
+ this._box.destroy_all_children();
|
||||
+ this._items = {};
|
||||
+ }
|
||||
+});
|
||||
+Signals.addSignalMethods(AuthList.prototype);
|
||||
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
|
||||
index 883b62d66..58035d303 100644
|
||||
--- a/js/js-resources.gresource.xml
|
||||
+++ b/js/js-resources.gresource.xml
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gnome/shell">
|
||||
+ <file>gdm/authList.js</file>
|
||||
<file>gdm/authPrompt.js</file>
|
||||
<file>gdm/batch.js</file>
|
||||
<file>gdm/fingerprint.js</file>
|
||||
--
|
||||
2.20.1
|
||||
|
115
SOURCES/0001-global-Allow-overriding-the-override-schema.patch
Normal file
115
SOURCES/0001-global-Allow-overriding-the-override-schema.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 1a614826eea7ba5da2796e0eb3b62a6bb7609040 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Wed, 11 Oct 2017 00:36:18 +0200
|
||||
Subject: [PATCH] global: Allow overriding the override schema
|
||||
|
||||
---
|
||||
src/main.c | 11 ++++++++++-
|
||||
src/shell-global.c | 20 +++++++++++++++++++-
|
||||
2 files changed, 29 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/main.c b/src/main.c
|
||||
index 857877b0b..6ebea4809 100644
|
||||
--- a/src/main.c
|
||||
+++ b/src/main.c
|
||||
@@ -38,6 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
|
||||
|
||||
static gboolean is_gdm_mode = FALSE;
|
||||
static char *session_mode = NULL;
|
||||
+static char *override_schema = NULL;
|
||||
static int caught_signal = 0;
|
||||
|
||||
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||
@@ -450,6 +451,12 @@ GOptionEntry gnome_shell_options[] = {
|
||||
N_("List possible modes"),
|
||||
NULL
|
||||
},
|
||||
+ {
|
||||
+ "override-schema", 0, 0, G_OPTION_ARG_STRING,
|
||||
+ &override_schema,
|
||||
+ N_("Override the override schema"),
|
||||
+ "SCHEMA"
|
||||
+ },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -507,7 +514,9 @@ main (int argc, char **argv)
|
||||
if (session_mode == NULL)
|
||||
session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user";
|
||||
|
||||
- _shell_global_init ("session-mode", session_mode, NULL);
|
||||
+ _shell_global_init ("session-mode", session_mode,
|
||||
+ "override-schema", override_schema,
|
||||
+ NULL);
|
||||
|
||||
shell_prefs_init ();
|
||||
|
||||
diff --git a/src/shell-global.c b/src/shell-global.c
|
||||
index c67ac4e4a..961fd3a70 100644
|
||||
--- a/src/shell-global.c
|
||||
+++ b/src/shell-global.c
|
||||
@@ -65,6 +65,7 @@ struct _ShellGlobal {
|
||||
MetaScreen *meta_screen;
|
||||
|
||||
char *session_mode;
|
||||
+ char *override_schema;
|
||||
|
||||
XserverRegion input_region;
|
||||
|
||||
@@ -96,6 +97,7 @@ enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_SESSION_MODE,
|
||||
+ PROP_OVERRIDE_SCHEMA,
|
||||
PROP_SCREEN,
|
||||
PROP_DISPLAY,
|
||||
PROP_SCREEN_WIDTH,
|
||||
@@ -138,6 +140,10 @@ shell_global_set_property(GObject *object,
|
||||
g_clear_pointer (&global->session_mode, g_free);
|
||||
global->session_mode = g_ascii_strdown (g_value_get_string (value), -1);
|
||||
break;
|
||||
+ case PROP_OVERRIDE_SCHEMA:
|
||||
+ g_clear_pointer (&global->override_schema, g_free);
|
||||
+ global->override_schema = g_value_dup_string (value);
|
||||
+ break;
|
||||
case PROP_FRAME_TIMESTAMPS:
|
||||
global->frame_timestamps = g_value_get_boolean (value);
|
||||
break;
|
||||
@@ -163,6 +169,9 @@ shell_global_get_property(GObject *object,
|
||||
case PROP_SESSION_MODE:
|
||||
g_value_set_string (value, shell_global_get_session_mode (global));
|
||||
break;
|
||||
+ case PROP_OVERRIDE_SCHEMA:
|
||||
+ g_value_set_string (value, global->override_schema);
|
||||
+ break;
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, global->meta_screen);
|
||||
break;
|
||||
@@ -368,6 +377,13 @@ shell_global_class_init (ShellGlobalClass *klass)
|
||||
g_param_spec_string ("session-mode",
|
||||
"Session Mode",
|
||||
"The session mode to use",
|
||||
+ NULL,
|
||||
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
+ g_object_class_install_property (gobject_class,
|
||||
+ PROP_OVERRIDE_SCHEMA,
|
||||
+ g_param_spec_string ("override-schema",
|
||||
+ "Override Schema",
|
||||
+ "The override schema to use",
|
||||
"user",
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (gobject_class,
|
||||
@@ -1360,7 +1376,9 @@ shell_global_get_overrides_settings (ShellGlobal *global)
|
||||
|
||||
if (!settings)
|
||||
{
|
||||
- if (strcmp (global->session_mode, "classic") == 0)
|
||||
+ if (global->override_schema != NULL)
|
||||
+ schema = global->override_schema;
|
||||
+ else if (strcmp (global->session_mode, "classic") == 0)
|
||||
schema = "org.gnome.shell.extensions.classic-overrides";
|
||||
else if (strcmp (global->session_mode, "user") == 0)
|
||||
schema = "org.gnome.shell.overrides";
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,65 @@
|
||||
From d9f64462b40125d5b1728c6d276811d6c4bbfb80 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Tue, 23 Oct 2018 00:06:36 +0200
|
||||
Subject: [PATCH] keyboardManager: Avoid idempotent calls to
|
||||
meta_backend_set_keymap()
|
||||
|
||||
But still try to apply the keymap whenever the input sources changed. This
|
||||
is a different approach to gnome-shell#240 that still avoid redundant
|
||||
changes to the current keymap, but actually trigger one when input sources
|
||||
are added.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1637418
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/691
|
||||
---
|
||||
js/misc/keyboardManager.js | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/js/misc/keyboardManager.js b/js/misc/keyboardManager.js
|
||||
index ae59f0014..f4001f130 100644
|
||||
--- a/js/misc/keyboardManager.js
|
||||
+++ b/js/misc/keyboardManager.js
|
||||
@@ -52,11 +52,20 @@ var KeyboardManager = new Lang.Class({
|
||||
this._current = null;
|
||||
this._localeLayoutInfo = this._getLocaleLayout();
|
||||
this._layoutInfos = {};
|
||||
+ this._currentKeymap = null;
|
||||
},
|
||||
|
||||
_applyLayoutGroup(group) {
|
||||
let options = this._buildOptionsString();
|
||||
let [layouts, variants] = this._buildGroupStrings(group);
|
||||
+
|
||||
+ if (this._currentKeymap &&
|
||||
+ this._currentKeymap.layouts == layouts &&
|
||||
+ this._currentKeymap.variants == variants &&
|
||||
+ this._currentKeymap.options == options)
|
||||
+ return;
|
||||
+
|
||||
+ this._currentKeymap = {layouts, variants, options};
|
||||
Meta.get_backend().set_keymap(layouts, variants, options);
|
||||
},
|
||||
|
||||
@@ -89,8 +98,6 @@ var KeyboardManager = new Lang.Class({
|
||||
},
|
||||
|
||||
setUserLayouts(ids) {
|
||||
- let currentId = this._current ? this._current.id : null;
|
||||
- let currentGroupIndex = this._current ? this._current.groupIndex : null;
|
||||
this._current = null;
|
||||
this._layoutInfos = {};
|
||||
|
||||
@@ -117,9 +124,6 @@ var KeyboardManager = new Lang.Class({
|
||||
info.group = group;
|
||||
info.groupIndex = groupIndex;
|
||||
|
||||
- if (currentId == id && currentGroupIndex == groupIndex)
|
||||
- this._current = info;
|
||||
-
|
||||
i += 1;
|
||||
}
|
||||
},
|
||||
--
|
||||
2.20.1
|
||||
|
32
SOURCES/0001-loginDialog-make-info-messages-themed.patch
Normal file
32
SOURCES/0001-loginDialog-make-info-messages-themed.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 297959c1a7bcf5e0b24c5215cfc94042da490d4f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 26 Jun 2017 14:35:05 -0400
|
||||
Subject: [PATCH] loginDialog: make info messages themed
|
||||
|
||||
They were lacking a definition before leading them to
|
||||
show up invisible.
|
||||
---
|
||||
data/theme/gnome-shell-sass/_common.scss | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
|
||||
index 4e82ef58b..ee643c440 100644
|
||||
--- a/data/theme/gnome-shell-sass/_common.scss
|
||||
+++ b/data/theme/gnome-shell-sass/_common.scss
|
||||
@@ -1769,7 +1769,12 @@ StScrollBar {
|
||||
.login-dialog-banner { color: darken($osd_fg_color,10%); }
|
||||
.login-dialog-button-box { spacing: 5px; }
|
||||
.login-dialog-message-warning { color: $warning_color; }
|
||||
- .login-dialog-message-hint { padding-top: 0; padding-bottom: 20px; }
|
||||
+ .login-dialog-message-hint, .login-dialog-message {
|
||||
+ color: darken($osd_fg_color, 20%);
|
||||
+ padding-top: 0;
|
||||
+ padding-bottom: 20px;
|
||||
+ min-height: 2.75em;
|
||||
+ }
|
||||
.login-dialog-user-selection-box { padding: 100px 0px; }
|
||||
.login-dialog-not-listed-label {
|
||||
padding-left: 2px;
|
||||
--
|
||||
2.20.1
|
||||
|
58
SOURCES/0001-osdWindow-Disconnect-signals-on-destroy.patch
Normal file
58
SOURCES/0001-osdWindow-Disconnect-signals-on-destroy.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 952ad185cc54eea2e9915b8d93dded1ac0ddf8ac Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Sun, 23 Sep 2018 03:06:21 +0200
|
||||
Subject: [PATCH] osdWindow: Disconnect signals on destroy
|
||||
|
||||
Since we started to show OSD windows on all monitors, OSD windows are
|
||||
destroyed when the corresponding monitor is disconnected. We shouldn't
|
||||
leave any signal handlers around in that case - they prevent the object
|
||||
from being garbage collected, and trigger warnings for accessing proper-
|
||||
ties of invalidated GObjects.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/602
|
||||
---
|
||||
js/ui/osdWindow.js | 23 +++++++++++++++++++----
|
||||
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/js/ui/osdWindow.js b/js/ui/osdWindow.js
|
||||
index a73912413..97e0498a7 100644
|
||||
--- a/js/ui/osdWindow.js
|
||||
+++ b/js/ui/osdWindow.js
|
||||
@@ -108,15 +108,30 @@ var OsdWindow = new Lang.Class({
|
||||
this._hideTimeoutId = 0;
|
||||
this._reset();
|
||||
|
||||
- Main.layoutManager.connect('monitors-changed',
|
||||
- this._relayout.bind(this));
|
||||
+ this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
+
|
||||
+ this._monitorsChangedId =
|
||||
+ Main.layoutManager.connect('monitors-changed',
|
||||
+ this._relayout.bind(this));
|
||||
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
- themeContext.connect('notify::scale-factor',
|
||||
- this._relayout.bind(this));
|
||||
+ this._scaleChangedId =
|
||||
+ themeContext.connect('notify::scale-factor',
|
||||
+ this._relayout.bind(this));
|
||||
this._relayout();
|
||||
Main.uiGroup.add_child(this.actor);
|
||||
},
|
||||
|
||||
+ _onDestroy() {
|
||||
+ if (this._monitorsChangedId)
|
||||
+ Main.layoutManager.disconnect(this._monitorsChangedId);
|
||||
+ this._monitorsChangedId = 0;
|
||||
+
|
||||
+ let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
+ if (this._scaleChangedId)
|
||||
+ themeContext.disconnect(this._scaleChangedId);
|
||||
+ this._scaleChangedId = 0;
|
||||
+ },
|
||||
+
|
||||
setIcon(icon) {
|
||||
this._icon.gicon = icon;
|
||||
},
|
||||
--
|
||||
2.20.1
|
||||
|
54
SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch
Normal file
54
SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 2fbce93b61f2a59871910c46f1e99ef28146a6db Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 15 Jan 2014 16:45:34 -0500
|
||||
Subject: [PATCH] panel: add an icon to the ActivitiesButton
|
||||
|
||||
Requested by brand
|
||||
---
|
||||
data/theme/gnome-shell-sass/_common.scss | 5 +++++
|
||||
js/ui/panel.js | 9 ++++++++-
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
|
||||
index ee643c440..f1aaea689 100644
|
||||
--- a/data/theme/gnome-shell-sass/_common.scss
|
||||
+++ b/data/theme/gnome-shell-sass/_common.scss
|
||||
@@ -776,6 +776,11 @@ StScrollBar {
|
||||
//dimensions of the icon are hardcoded
|
||||
}
|
||||
|
||||
+ .panel-logo-icon {
|
||||
+ padding-right: .4em;
|
||||
+ icon-size: 1em;
|
||||
+ }
|
||||
+
|
||||
.system-status-icon,
|
||||
.app-menu-icon > StIcon,
|
||||
.popup-menu-arrow {
|
||||
diff --git a/js/ui/panel.js b/js/ui/panel.js
|
||||
index 2f593247d..d1a572503 100644
|
||||
--- a/js/ui/panel.js
|
||||
+++ b/js/ui/panel.js
|
||||
@@ -406,11 +406,18 @@ var ActivitiesButton = new Lang.Class({
|
||||
|
||||
this.actor.name = 'panelActivities';
|
||||
|
||||
+ let box = new St.BoxLayout();
|
||||
+ this.actor.add_actor(box);
|
||||
+ let iconFile = Gio.File.new_for_path('/usr/share/icons/hicolor/scalable/apps/start-here.svg');
|
||||
+ this._icon = new St.Icon({ gicon: new Gio.FileIcon({ file: iconFile }),
|
||||
+ style_class: 'panel-logo-icon' });
|
||||
+ box.add_actor(this._icon);
|
||||
+
|
||||
/* Translators: If there is no suitable word for "Activities"
|
||||
in your language, you can use the word for "Overview". */
|
||||
this._label = new St.Label({ text: _("Activities"),
|
||||
y_align: Clutter.ActorAlign.CENTER });
|
||||
- this.actor.add_actor(this._label);
|
||||
+ box.add_actor(this._label);
|
||||
|
||||
this.actor.label_actor = this._label;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 7d34369b7a011a3a0377f19d342e1663a04d6027 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Fri, 3 Jul 2015 13:54:36 -0400
|
||||
Subject: [PATCH] screenShield: unblank when inserting smartcard
|
||||
|
||||
If a user inserts the smartcard when the screen is locked/blanked
|
||||
we should ask them their pin right away.
|
||||
|
||||
At the moment they have to wiggle the mouse or do some other
|
||||
action to get the screen to unblank.
|
||||
---
|
||||
js/ui/screenShield.js | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
|
||||
index 2d8d9b3f6..ebba6c82a 100644
|
||||
--- a/js/ui/screenShield.js
|
||||
+++ b/js/ui/screenShield.js
|
||||
@@ -515,8 +515,10 @@ var ScreenShield = new Lang.Class({
|
||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||
this._smartcardManager.connect('smartcard-inserted',
|
||||
(manager, token) => {
|
||||
- if (this._isLocked && token.UsedToLogin)
|
||||
+ if (this._isLocked && token.UsedToLogin) {
|
||||
+ this._wakeUpScreen();
|
||||
this._liftShield(true, 0);
|
||||
+ }
|
||||
});
|
||||
|
||||
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,52 @@
|
||||
From f6023e2f4ae939a03bb9285e32444be909340bcf Mon Sep 17 00:00:00 2001
|
||||
From: Rui Matos <tiagomatos@gmail.com>
|
||||
Date: Fri, 8 Nov 2013 11:36:04 +0100
|
||||
Subject: [PATCH] shellDBus: Add a DBus method to load a single extension
|
||||
|
||||
This allows e.g. gnome-tweak-tool to install an extension from a zip
|
||||
file and load it into the running shell.
|
||||
---
|
||||
js/ui/shellDBus.js | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
|
||||
index c35e7f19c..3a095ae5c 100644
|
||||
--- a/js/ui/shellDBus.js
|
||||
+++ b/js/ui/shellDBus.js
|
||||
@@ -322,6 +322,10 @@ const GnomeShellExtensionsIface = '<node> \
|
||||
</method> \
|
||||
<method name="CheckForUpdates"> \
|
||||
</method> \
|
||||
+<method name="LoadUserExtension"> \
|
||||
+ <arg type="s" direction="in" name="uuid"/> \
|
||||
+ <arg type="b" direction="out" name="success"/> \
|
||||
+</method> \
|
||||
<property name="ShellVersion" type="s" access="read" /> \
|
||||
</interface> \
|
||||
</node>';
|
||||
@@ -424,6 +428,22 @@ var GnomeShellExtensions = new Lang.Class({
|
||||
ExtensionDownloader.checkForUpdates();
|
||||
},
|
||||
|
||||
+ LoadUserExtension(uuid) {
|
||||
+ let extension = ExtensionUtils.extensions[uuid];
|
||||
+ if (extension)
|
||||
+ return true;
|
||||
+
|
||||
+ let dir = Gio.File.new_for_path(GLib.build_filenamev([global.userdatadir, 'extensions', uuid]));
|
||||
+ try {
|
||||
+ extension = ExtensionUtils.createExtensionObject(uuid, dir, ExtensionUtils.ExtensionType.PER_USER);
|
||||
+ ExtensionSystem.loadExtension(extension);
|
||||
+ } catch (e) {
|
||||
+ log('Could not load user extension from %s'.format(dir.get_path()));
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ },
|
||||
+
|
||||
ShellVersion: Config.PACKAGE_VERSION,
|
||||
|
||||
_extensionStateChanged(_, newState) {
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,44 @@
|
||||
From fc6c039871827fb7ec26362b39b515f438122af5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Tue, 14 Mar 2017 17:04:36 +0100
|
||||
Subject: [PATCH] windowMenu: Bring back workspaces submenu for static
|
||||
workspaces
|
||||
|
||||
When the titlebar context menu was moved to the shell, the submenu for
|
||||
moving to a specific workspace was intentionally left out; some people
|
||||
are quite attached to it though, so bring it back when static workspaces
|
||||
are used.
|
||||
---
|
||||
js/ui/windowMenu.js | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/js/ui/windowMenu.js b/js/ui/windowMenu.js
|
||||
index f0e564b7e..8c97a1eec 100644
|
||||
--- a/js/ui/windowMenu.js
|
||||
+++ b/js/ui/windowMenu.js
|
||||
@@ -123,6 +123,22 @@ var WindowMenu = new Lang.Class({
|
||||
window.change_workspace(workspace.get_neighbor(dir));
|
||||
});
|
||||
}
|
||||
+
|
||||
+ let nWorkspaces = global.screen.n_workspaces;
|
||||
+ if (nWorkspaces > 1 && !Meta.prefs_get_dynamic_workspaces()) {
|
||||
+ item = new PopupMenu.PopupSubMenuMenuItem(_("Move to another workspace"));
|
||||
+ this.addMenuItem(item);
|
||||
+
|
||||
+ let currentIndex = global.screen.get_active_workspace_index();
|
||||
+ for (let i = 0; i < nWorkspaces; i++) {
|
||||
+ let index = i;
|
||||
+ let name = Meta.prefs_get_workspace_name(i);
|
||||
+ let subitem = item.menu.addAction(name, () => {
|
||||
+ window.change_workspace_by_index(index, false);
|
||||
+ });
|
||||
+ subitem.setSensitive(currentIndex != i);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
@ -0,0 +1,85 @@
|
||||
From 2b3f696c8cde01f23bd16b8671de536ae0e001e4 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 15 Jan 2019 12:52:49 -0500
|
||||
Subject: [PATCH 2/4] background: rebuild background, not just animation on
|
||||
resume
|
||||
|
||||
Previously, we would only refresh the animation on resume
|
||||
(to handle clock skew).
|
||||
|
||||
But we actually need to rebuild the background, too, on nvidia,
|
||||
so we should just do a full background change.
|
||||
---
|
||||
js/ui/background.js | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/ui/background.js b/js/ui/background.js
|
||||
index b24f82536..c61d946a4 100644
|
||||
--- a/js/ui/background.js
|
||||
+++ b/js/ui/background.js
|
||||
@@ -237,61 +237,61 @@ var Background = new Lang.Class({
|
||||
params = Params.parse(params, { monitorIndex: 0,
|
||||
layoutManager: Main.layoutManager,
|
||||
settings: null,
|
||||
file: null,
|
||||
style: null });
|
||||
|
||||
this.background = new Meta.Background({ meta_screen: global.screen });
|
||||
this.background._delegate = this;
|
||||
|
||||
this._settings = params.settings;
|
||||
this._file = params.file;
|
||||
this._style = params.style;
|
||||
this._monitorIndex = params.monitorIndex;
|
||||
this._layoutManager = params.layoutManager;
|
||||
this._fileWatches = {};
|
||||
this._cancellable = new Gio.Cancellable();
|
||||
this.isLoaded = false;
|
||||
|
||||
this._clock = new GnomeDesktop.WallClock();
|
||||
this._timezoneChangedId = this._clock.connect('notify::timezone',
|
||||
() => {
|
||||
if (this._animation)
|
||||
this._loadAnimation(this._animation.file);
|
||||
});
|
||||
|
||||
let loginManager = LoginManager.getLoginManager();
|
||||
this._prepareForSleepId = loginManager.connect('prepare-for-sleep',
|
||||
(lm, aboutToSuspend) => {
|
||||
if (aboutToSuspend)
|
||||
return;
|
||||
- this._refreshAnimation();
|
||||
+ this.emit('changed');
|
||||
});
|
||||
|
||||
this._settingsChangedSignalId = this._settings.connect('changed', () => {
|
||||
this.emit('changed');
|
||||
});
|
||||
|
||||
this._load();
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this._cancellable.cancel();
|
||||
this._removeAnimationTimeout();
|
||||
|
||||
let i;
|
||||
let keys = Object.keys(this._fileWatches);
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
this._cache.disconnect(this._fileWatches[keys[i]]);
|
||||
}
|
||||
this._fileWatches = null;
|
||||
|
||||
if (this._timezoneChangedId != 0)
|
||||
this._clock.disconnect(this._timezoneChangedId);
|
||||
this._timezoneChangedId = 0;
|
||||
|
||||
this._clock = null;
|
||||
|
||||
if (this._prepareForSleepId != 0)
|
||||
LoginManager.getLoginManager().disconnect(this._prepareForSleepId);
|
||||
this._prepareForSleepId = 0;
|
||||
|
||||
--
|
||||
2.18.1
|
||||
|
@ -0,0 +1,267 @@
|
||||
From 87e7f4ea023cac3b4573ea0c7012b77c588f35ae Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 17 Jul 2017 16:48:03 -0400
|
||||
Subject: [PATCH 2/2] gdmUtil: enable support for GDM's ChoiceList PAM
|
||||
extension
|
||||
|
||||
This commit hooks up support for GDM's ChoiceList PAM extension.
|
||||
---
|
||||
js/gdm/authPrompt.js | 74 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
js/gdm/loginDialog.js | 5 +++
|
||||
js/gdm/util.js | 28 ++++++++++++++++
|
||||
js/ui/unlockDialog.js | 9 +++++-
|
||||
4 files changed, 114 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
|
||||
index e44281117..27a55246a 100644
|
||||
--- a/js/gdm/authPrompt.js
|
||||
+++ b/js/gdm/authPrompt.js
|
||||
@@ -9,6 +9,7 @@ const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
+const AuthList = imports.gdm.authList;
|
||||
const Batch = imports.gdm.batch;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
const Meta = imports.gi.Meta;
|
||||
@@ -61,6 +62,7 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._userVerifier.connect('ask-question', this._onAskQuestion.bind(this));
|
||||
this._userVerifier.connect('show-message', this._onShowMessage.bind(this));
|
||||
+ this._userVerifier.connect('show-choice-list', this._onShowChoiceList.bind(this));
|
||||
this._userVerifier.connect('verification-failed', this._onVerificationFailed.bind(this));
|
||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||
@@ -123,6 +125,28 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this.actor.add(this._timedLoginIndicator);
|
||||
|
||||
+ this._authList = new AuthList.AuthList();
|
||||
+ this._authList.connect('activate', (list, key) => {
|
||||
+ this._authList.actor.reactive = false;
|
||||
+ Tweener.addTween(this._authList.actor,
|
||||
+ { opacity: 0,
|
||||
+ time: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||
+ transition: 'easeOutQuad',
|
||||
+ onComplete: () => {
|
||||
+ this._authList.clear();
|
||||
+ this._authList.actor.hide();
|
||||
+ this._userVerifier.selectChoice(this._queryingService, key);
|
||||
+
|
||||
+ }
|
||||
+ });
|
||||
+ });
|
||||
+ this._authList.actor.hide();
|
||||
+ this.actor.add(this._authList.actor,
|
||||
+ { expand: true,
|
||||
+ x_fill: true,
|
||||
+ y_fill: false,
|
||||
+ x_align: St.Align.START });
|
||||
+
|
||||
this._message = new St.Label({ opacity: 0,
|
||||
styleClass: 'login-dialog-message' });
|
||||
this._message.clutter_text.line_wrap = true;
|
||||
@@ -266,6 +290,21 @@ var AuthPrompt = new Lang.Class({
|
||||
this.emit('prompted');
|
||||
},
|
||||
|
||||
+ _onShowChoiceList(userVerifier, serviceName, promptMessage, choiceList) {
|
||||
+ if (this._queryingService)
|
||||
+ this.clear();
|
||||
+
|
||||
+ this._queryingService = serviceName;
|
||||
+
|
||||
+ if (this._preemptiveAnswer)
|
||||
+ this._preemptiveAnswer = null;
|
||||
+
|
||||
+ this.nextButton.label = _("Next");
|
||||
+ this.setChoiceList(promptMessage, choiceList);
|
||||
+ this.updateSensitivity(true);
|
||||
+ this.emit('prompted');
|
||||
+ },
|
||||
+
|
||||
_onOVirtUserAuthenticated() {
|
||||
if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
|
||||
this.reset();
|
||||
@@ -394,6 +433,8 @@ var AuthPrompt = new Lang.Class({
|
||||
clear() {
|
||||
this._entry.text = '';
|
||||
this.stopSpinning();
|
||||
+ this._authList.clear();
|
||||
+ this._authList.actor.hide();
|
||||
},
|
||||
|
||||
setPasswordChar(passwordChar) {
|
||||
@@ -409,12 +450,42 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._label.set_text(question);
|
||||
|
||||
+ this._authList.actor.hide();
|
||||
this._label.show();
|
||||
this._entry.show();
|
||||
|
||||
this._entry.grab_key_focus();
|
||||
},
|
||||
|
||||
+ _fadeInChoiceList() {
|
||||
+ this._authList.actor.opacity = 0;
|
||||
+ this._authList.actor.show();
|
||||
+ this._authList.actor.reactive = false;
|
||||
+ Tweener.addTween(this._authList.actor,
|
||||
+ { opacity: 255,
|
||||
+ time: MESSAGE_FADE_OUT_ANIMATION_TIME,
|
||||
+ transition: 'easeOutQuad',
|
||||
+ onComplete: () => {
|
||||
+ this._authList.actor.reactive = true;
|
||||
+ }
|
||||
+ });
|
||||
+ },
|
||||
+
|
||||
+ setChoiceList(promptMessage, choiceList) {
|
||||
+ this._authList.clear();
|
||||
+ this._authList.label.text = promptMessage;
|
||||
+ for (let key in choiceList) {
|
||||
+ let text = choiceList[key];
|
||||
+ this._authList.addItem(key, text);
|
||||
+ }
|
||||
+
|
||||
+ this._label.hide();
|
||||
+ this._entry.hide();
|
||||
+ if (this._message.text == "")
|
||||
+ this._message.hide();
|
||||
+ this._fadeInChoiceList();
|
||||
+ },
|
||||
+
|
||||
getAnswer() {
|
||||
let text;
|
||||
|
||||
@@ -450,6 +521,7 @@ var AuthPrompt = new Lang.Class({
|
||||
else
|
||||
this._message.remove_style_class_name('login-dialog-message-hint');
|
||||
|
||||
+ this._message.show();
|
||||
if (message) {
|
||||
Tweener.removeTweens(this._message);
|
||||
this._message.text = message;
|
||||
@@ -465,7 +537,7 @@ var AuthPrompt = new Lang.Class({
|
||||
},
|
||||
|
||||
updateSensitivity(sensitive) {
|
||||
- this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
||||
+ this._updateNextButtonSensitivity(sensitive && !this._authList.actor.visible && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING));
|
||||
this._entry.reactive = sensitive;
|
||||
this._entry.clutter_text.editable = sensitive;
|
||||
},
|
||||
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
||||
index 65d9edf1a..912c0e0ca 100644
|
||||
--- a/js/gdm/loginDialog.js
|
||||
+++ b/js/gdm/loginDialog.js
|
||||
@@ -418,6 +418,11 @@ var LoginDialog = new Lang.Class({
|
||||
this._userManager = AccountsService.UserManager.get_default()
|
||||
this._gdmClient = new Gdm.Client();
|
||||
|
||||
+ try {
|
||||
+ this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]);
|
||||
+ } catch(e) {
|
||||
+ }
|
||||
+
|
||||
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
||||
|
||||
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
||||
diff --git a/js/gdm/util.js b/js/gdm/util.js
|
||||
index f5f9d5e5d..04a0cb9bf 100644
|
||||
--- a/js/gdm/util.js
|
||||
+++ b/js/gdm/util.js
|
||||
@@ -200,6 +200,10 @@ var ShellUserVerifier = new Lang.Class({
|
||||
if (this._userVerifier) {
|
||||
this._userVerifier.run_dispose();
|
||||
this._userVerifier = null;
|
||||
+ if (this._userVerifierChoiceList) {
|
||||
+ this._userVerifierChoiceList.run_dispose();
|
||||
+ this._userVerifierChoiceList = null;
|
||||
+ }
|
||||
}
|
||||
},
|
||||
|
||||
@@ -227,6 +231,10 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._oVirtCredentialsManager = null;
|
||||
},
|
||||
|
||||
+ selectChoice(serviceName, key) {
|
||||
+ this._userVerifierChoiceList.call_select_choice(serviceName, key, this._cancellable, null);
|
||||
+ },
|
||||
+
|
||||
answerQuery(serviceName, answer) {
|
||||
if (!this.hasPendingMessages) {
|
||||
this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null);
|
||||
@@ -367,6 +375,11 @@ var ShellUserVerifier = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (client.get_user_verifier_choice_list)
|
||||
+ this._userVerifierChoiceList = client.get_user_verifier_choice_list();
|
||||
+ else
|
||||
+ this._userVerifierChoiceList = null;
|
||||
+
|
||||
this.reauthenticating = true;
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
@@ -384,6 +397,11 @@ var ShellUserVerifier = new Lang.Class({
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (client.get_user_verifier_choice_list)
|
||||
+ this._userVerifierChoiceList = client.get_user_verifier_choice_list();
|
||||
+ else
|
||||
+ this._userVerifierChoiceList = null;
|
||||
+
|
||||
this._connectSignals();
|
||||
this._beginVerification();
|
||||
this._hold.release();
|
||||
@@ -397,6 +415,9 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this));
|
||||
this._userVerifier.connect('reset', this._onReset.bind(this));
|
||||
this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this));
|
||||
+
|
||||
+ if (this._userVerifierChoiceList)
|
||||
+ this._userVerifierChoiceList.connect('choice-query', this._onChoiceListQuery.bind(this));
|
||||
},
|
||||
|
||||
_getForegroundService() {
|
||||
@@ -473,6 +494,13 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._startService(FINGERPRINT_SERVICE_NAME);
|
||||
},
|
||||
|
||||
+ _onChoiceListQuery(client, serviceName, promptMessage, list) {
|
||||
+ if (!this.serviceIsForeground(serviceName))
|
||||
+ return;
|
||||
+
|
||||
+ this.emit('show-choice-list', serviceName, promptMessage, list.deep_unpack());
|
||||
+ },
|
||||
+
|
||||
_onInfo(client, serviceName, info) {
|
||||
if (this.serviceIsForeground(serviceName)) {
|
||||
this._queueMessage(info, MessageType.INFO);
|
||||
diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js
|
||||
index 1adaf417e..b5272be20 100644
|
||||
--- a/js/ui/unlockDialog.js
|
||||
+++ b/js/ui/unlockDialog.js
|
||||
@@ -51,7 +51,14 @@ var UnlockDialog = new Lang.Class({
|
||||
y_expand: true });
|
||||
this.actor.add_child(this._promptBox);
|
||||
|
||||
- this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
||||
+ this._gdmClient = new Gdm.Client();
|
||||
+
|
||||
+ try {
|
||||
+ this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]);
|
||||
+ } catch(e) {
|
||||
+ }
|
||||
+
|
||||
+ this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
|
||||
this._authPrompt.connect('failed', this._fail.bind(this));
|
||||
this._authPrompt.connect('cancelled', this._fail.bind(this));
|
||||
this._authPrompt.connect('reset', this._onReset.bind(this));
|
||||
--
|
||||
2.20.1
|
||||
|
136
SOURCES/0002-introspect-Add-GetWindows-method.patch
Normal file
136
SOURCES/0002-introspect-Add-GetWindows-method.patch
Normal file
@ -0,0 +1,136 @@
|
||||
From 13afa15130a50aab36e7a61dea5f6d595cd978a1 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 12 Dec 2018 16:02:29 +0100
|
||||
Subject: [PATCH 2/2] introspect: Add GetWindows method
|
||||
|
||||
The `GetWindows` method gives access to the list of windows for each
|
||||
application with some of their properties, so utilities such as dogtail
|
||||
can pick the window of their choice to interfere with using the provided
|
||||
window id.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/326
|
||||
(cherry picked from commit 0f45b438e2b956d3cf52622db875dedab45e49b9)
|
||||
---
|
||||
data/org.gnome.Shell.Introspect.xml | 24 ++++++++++++
|
||||
js/misc/introspect.js | 58 +++++++++++++++++++++++++++++
|
||||
2 files changed, 82 insertions(+)
|
||||
|
||||
diff --git a/data/org.gnome.Shell.Introspect.xml b/data/org.gnome.Shell.Introspect.xml
|
||||
index 10c48d635..9508681af 100644
|
||||
--- a/data/org.gnome.Shell.Introspect.xml
|
||||
+++ b/data/org.gnome.Shell.Introspect.xml
|
||||
@@ -33,5 +33,29 @@
|
||||
<method name="GetRunningApplications">
|
||||
<arg name="apps" direction="out" type="a{sa{sv}}" />
|
||||
</method>
|
||||
+
|
||||
+ <!--
|
||||
+ GetWindows:
|
||||
+ @short_description: Retrieves the current list of windows and their properties
|
||||
+
|
||||
+ A window is exposed as:
|
||||
+ * t ID: unique ID of the window
|
||||
+ * a{sv} properties: high-level properties
|
||||
+
|
||||
+ Known properties:
|
||||
+
|
||||
+ - "title" (s): (readonly) title of the window
|
||||
+ - "app-id" (s): (readonly) application ID of the window
|
||||
+ - "wm-class" (s): (readonly) class of the window
|
||||
+ - "client-type" (u): (readonly) 0 for Wayland, 1 for X11
|
||||
+ - "is-hidden" (b): (readonly) if the window is currently hidden
|
||||
+ - "has-focus" (b): (readonly) if the window currently have
|
||||
+ keyboard focus
|
||||
+ - "width" (u): (readonly) width of the window
|
||||
+ - "height" (u): (readonly) height of the window
|
||||
+ -->
|
||||
+ <method name="GetWindows">
|
||||
+ <arg name="windows" direction="out" type="a{ta{sv}}" />
|
||||
+ </method>
|
||||
</interface>
|
||||
</node>
|
||||
diff --git a/js/misc/introspect.js b/js/misc/introspect.js
|
||||
index 05ef9e637..5999fc1f0 100644
|
||||
--- a/js/misc/introspect.js
|
||||
+++ b/js/misc/introspect.js
|
||||
@@ -14,6 +14,9 @@ const IntrospectDBusIface = '<node> \
|
||||
<method name="GetRunningApplications"> \
|
||||
<arg name="apps" direction="out" type="a{sa{sv}}" /> \
|
||||
</method> \
|
||||
+ <method name="GetWindows"> \
|
||||
+ <arg name="windows" direction="out" type="a{ta{sv}}" /> \
|
||||
+ </method> \
|
||||
</interface> \
|
||||
</node>';
|
||||
|
||||
@@ -102,6 +105,17 @@ var IntrospectService = new Lang.Class({
|
||||
this._activeApplicationDirty = false;
|
||||
},
|
||||
|
||||
+ _isEligibleWindow(window) {
|
||||
+ if (window.is_override_redirect())
|
||||
+ return false;
|
||||
+
|
||||
+ let type = window.get_window_type();
|
||||
+ return (type == Meta.WindowType.NORMAL ||
|
||||
+ type == Meta.WindowType.DIALOG ||
|
||||
+ type == Meta.WindowType.MODAL_DIALOG ||
|
||||
+ type == Meta.WindowType.UTILITY);
|
||||
+ },
|
||||
+
|
||||
GetRunningApplicationsAsync(params, invocation) {
|
||||
if (!this._isIntrospectEnabled() &&
|
||||
!this._isSenderWhitelisted(invocation.get_sender())) {
|
||||
@@ -112,5 +126,49 @@ var IntrospectService = new Lang.Class({
|
||||
}
|
||||
|
||||
invocation.return_value(new GLib.Variant('(a{sa{sv}})', [this._runningApplications]));
|
||||
+ },
|
||||
+
|
||||
+ GetWindowsAsync(params, invocation) {
|
||||
+ let focusWindow = global.display.get_focus_window();
|
||||
+ let apps = this._appSystem.get_running();
|
||||
+ let windowsList = {};
|
||||
+
|
||||
+ if (!this._isIntrospectEnabled()) {
|
||||
+ invocation.return_error_literal(Gio.DBusError,
|
||||
+ Gio.DBusError.ACCESS_DENIED,
|
||||
+ 'App introspection not allowed');
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (let app of apps) {
|
||||
+ let windows = app.get_windows();
|
||||
+ for (let window of windows) {
|
||||
+
|
||||
+ if (!this._isEligibleWindow(window))
|
||||
+ continue;
|
||||
+
|
||||
+ let windowId = window.get_id();
|
||||
+ let frameRect = window.get_frame_rect();
|
||||
+ let title = window.get_title();
|
||||
+ let wmClass = window.get_wm_class();
|
||||
+
|
||||
+ windowsList[windowId] = {
|
||||
+ 'app-id': GLib.Variant.new('s', app.get_id()),
|
||||
+ 'client-type': GLib.Variant.new('u', window.get_client_type()),
|
||||
+ 'is-hidden': GLib.Variant.new('b', window.is_hidden()),
|
||||
+ 'has-focus': GLib.Variant.new('b', (window == focusWindow)),
|
||||
+ 'width': GLib.Variant.new('u', frameRect.width),
|
||||
+ 'height': GLib.Variant.new('u', frameRect.height)
|
||||
+ };
|
||||
+
|
||||
+ // These properties may not be available for all windows:
|
||||
+ if (title != null)
|
||||
+ windowsList[windowId]['title'] = GLib.Variant.new('s', title);
|
||||
+
|
||||
+ if (wmClass != null)
|
||||
+ windowsList[windowId]['wm-class'] = GLib.Variant.new('s', wmClass);
|
||||
+ }
|
||||
+ }
|
||||
+ invocation.return_value(new GLib.Variant('(a{ta{sv}})', [windowsList]));
|
||||
}
|
||||
});
|
||||
--
|
||||
2.20.1
|
||||
|
43
SOURCES/0002-remoteAccess-Make-indicator-orange.patch
Normal file
43
SOURCES/0002-remoteAccess-Make-indicator-orange.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 31da6717085567c044322d722df5b735925583ce Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Fri, 27 Jul 2018 18:07:52 +0200
|
||||
Subject: [PATCH 2/2] remoteAccess: Make indicator orange
|
||||
|
||||
Make the indicator for active remote access use the warning color, to
|
||||
indicate the severity of allowing remote access.
|
||||
|
||||
This only makes the indicator icon orange; the icon in the system menu
|
||||
is still white.
|
||||
---
|
||||
data/theme/gnome-shell-sass/_common.scss | 2 ++
|
||||
js/ui/status/remoteAccess.js | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
|
||||
index 2f05098df..24ac2c974 100644
|
||||
--- a/data/theme/gnome-shell-sass/_common.scss
|
||||
+++ b/data/theme/gnome-shell-sass/_common.scss
|
||||
@@ -824,6 +824,8 @@ StScrollBar {
|
||||
|
||||
.screencast-indicator { color: $warning_color; }
|
||||
|
||||
+ .remote-access-indicator { color: $warning_color; }
|
||||
+
|
||||
&.solid {
|
||||
background-color: black;
|
||||
/* transition from transparent to solid */
|
||||
diff --git a/js/ui/status/remoteAccess.js b/js/ui/status/remoteAccess.js
|
||||
index ffa334001..db94d130d 100644
|
||||
--- a/js/ui/status/remoteAccess.js
|
||||
+++ b/js/ui/status/remoteAccess.js
|
||||
@@ -41,6 +41,7 @@ var RemoteAccessApplet = new Lang.Class({
|
||||
|
||||
this._indicator = this._addIndicator();
|
||||
this._indicator.icon_name = 'screen-shared-symbolic';
|
||||
+ this._indicator.add_style_class_name('remote-access-indicator');
|
||||
this._item =
|
||||
new PopupMenu.PopupSubMenuMenuItem(_("Screen is Being Shared"),
|
||||
true);
|
||||
--
|
||||
2.17.1
|
||||
|
230
SOURCES/0003-st-texture-cache-purge-on-resume.patch
Normal file
230
SOURCES/0003-st-texture-cache-purge-on-resume.patch
Normal file
@ -0,0 +1,230 @@
|
||||
From fd9a803159ca7e7fbe6bee1842cc78deff0da7fa Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 15 Jan 2019 12:54:32 -0500
|
||||
Subject: [PATCH 3/4] st-texture-cache: purge on resume
|
||||
|
||||
With the proprietary nvidia driver, textures get garbled on suspend,
|
||||
so the texture cache needs to evict all textures in that situation.
|
||||
---
|
||||
js/ui/main.js | 6 +++++-
|
||||
src/st/st-texture-cache.c | 12 ++++++++++++
|
||||
src/st/st-texture-cache.h | 1 +
|
||||
3 files changed, 18 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/ui/main.js b/js/ui/main.js
|
||||
index a8779bf09..faaf07399 100644
|
||||
--- a/js/ui/main.js
|
||||
+++ b/js/ui/main.js
|
||||
@@ -184,61 +184,65 @@ function _initializeUI() {
|
||||
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
panel = new Panel.Panel();
|
||||
keyboard = new Keyboard.Keyboard();
|
||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
componentManager = new Components.ComponentManager();
|
||||
|
||||
introspectService = new Introspect.IntrospectService();
|
||||
|
||||
layoutManager.init();
|
||||
overview.init();
|
||||
|
||||
_a11ySettings = new Gio.Settings({ schema_id: A11Y_SCHEMA });
|
||||
|
||||
global.display.connect('overlay-key', () => {
|
||||
if (!_a11ySettings.get_boolean (STICKY_KEYS_ENABLE))
|
||||
overview.toggle();
|
||||
});
|
||||
|
||||
global.display.connect('show-restart-message', (display, message) => {
|
||||
showRestartMessage(message);
|
||||
return true;
|
||||
});
|
||||
|
||||
global.display.connect('restart', () => {
|
||||
global.reexec_self();
|
||||
return true;
|
||||
});
|
||||
|
||||
- global.display.connect('gl-video-memory-purged', loadTheme);
|
||||
+ global.display.connect('gl-video-memory-purged', () => {
|
||||
+ let cache = St.TextureCache.get_default();
|
||||
+ cache.clear();
|
||||
+ loadTheme();
|
||||
+ });
|
||||
|
||||
// Provide the bus object for gnome-session to
|
||||
// initiate logouts.
|
||||
EndSessionDialog.init();
|
||||
|
||||
// We're ready for the session manager to move to the next phase
|
||||
Meta.register_with_session();
|
||||
|
||||
_startDate = new Date();
|
||||
|
||||
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
||||
if (perfModuleName) {
|
||||
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
|
||||
let module = eval('imports.perf.' + perfModuleName + ';');
|
||||
Scripting.runPerfScript(module, perfOutput);
|
||||
}
|
||||
|
||||
ExtensionDownloader.init();
|
||||
ExtensionSystem.init();
|
||||
|
||||
if (sessionMode.isGreeter && screenShield) {
|
||||
layoutManager.connect('startup-prepared', () => {
|
||||
screenShield.showDialog();
|
||||
});
|
||||
}
|
||||
|
||||
layoutManager.connect('startup-complete', () => {
|
||||
if (actionMode == Shell.ActionMode.NONE) {
|
||||
actionMode = Shell.ActionMode.NORMAL;
|
||||
}
|
||||
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
|
||||
index 0c794a3ab..5a3dcd81f 100644
|
||||
--- a/src/st/st-texture-cache.c
|
||||
+++ b/src/st/st-texture-cache.c
|
||||
@@ -78,60 +78,72 @@ set_texture_cogl_texture (ClutterTexture *clutter_texture, CoglTexture *cogl_tex
|
||||
{
|
||||
clutter_texture_set_cogl_texture (clutter_texture, cogl_texture);
|
||||
g_object_set (clutter_texture, "opacity", 255, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
st_texture_cache_class_init (StTextureCacheClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *)klass;
|
||||
|
||||
gobject_class->dispose = st_texture_cache_dispose;
|
||||
gobject_class->finalize = st_texture_cache_finalize;
|
||||
|
||||
signals[ICON_THEME_CHANGED] =
|
||||
g_signal_new ("icon-theme-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, /* no default handler slot */
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[TEXTURE_FILE_CHANGED] =
|
||||
g_signal_new ("texture-file-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, /* no default handler slot */
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_FILE);
|
||||
}
|
||||
|
||||
+/* Evicts all cached textures */
|
||||
+void
|
||||
+st_texture_cache_clear (StTextureCache *cache)
|
||||
+{
|
||||
+ GHashTableIter iter;
|
||||
+ gpointer key;
|
||||
+ gpointer value;
|
||||
+
|
||||
+ g_hash_table_remove_all (cache->priv->keyed_cache);
|
||||
+ g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0);
|
||||
+}
|
||||
+
|
||||
/* Evicts all cached textures for named icons */
|
||||
static void
|
||||
st_texture_cache_evict_icons (StTextureCache *cache)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gpointer value;
|
||||
|
||||
g_hash_table_iter_init (&iter, cache->priv->keyed_cache);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
const char *cache_key = key;
|
||||
|
||||
/* This is too conservative - it takes out all cached textures
|
||||
* for GIcons even when they aren't named icons, but it's not
|
||||
* worth the complexity of parsing the key and calling
|
||||
* g_icon_new_for_string(); icon theme changes aren't normal */
|
||||
if (g_str_has_prefix (cache_key, CACHE_PREFIX_ICON))
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_icon_theme_changed (GtkIconTheme *icon_theme,
|
||||
StTextureCache *cache)
|
||||
{
|
||||
st_texture_cache_evict_icons (cache);
|
||||
g_signal_emit (cache, signals[ICON_THEME_CHANGED], 0);
|
||||
}
|
||||
|
||||
diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h
|
||||
index 26f9c30ac..b87adc4d5 100644
|
||||
--- a/src/st/st-texture-cache.h
|
||||
+++ b/src/st/st-texture-cache.h
|
||||
@@ -25,60 +25,61 @@
|
||||
#if !defined(ST_H_INSIDE) && !defined(ST_COMPILATION)
|
||||
#error "Only <st/st.h> can be included directly.h"
|
||||
#endif
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <st/st-types.h>
|
||||
#include <st/st-theme-node.h>
|
||||
|
||||
#define ST_TYPE_TEXTURE_CACHE (st_texture_cache_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (StTextureCache, st_texture_cache,
|
||||
ST, TEXTURE_CACHE, GObject)
|
||||
|
||||
typedef struct _StTextureCachePrivate StTextureCachePrivate;
|
||||
|
||||
struct _StTextureCache
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
StTextureCachePrivate *priv;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
ST_TEXTURE_CACHE_POLICY_NONE,
|
||||
ST_TEXTURE_CACHE_POLICY_FOREVER
|
||||
} StTextureCachePolicy;
|
||||
|
||||
StTextureCache* st_texture_cache_get_default (void);
|
||||
+void st_texture_cache_clear (StTextureCache *cache);
|
||||
|
||||
ClutterActor *
|
||||
st_texture_cache_load_sliced_image (StTextureCache *cache,
|
||||
GFile *file,
|
||||
gint grid_width,
|
||||
gint grid_height,
|
||||
gint scale,
|
||||
GFunc load_callback,
|
||||
gpointer user_data);
|
||||
|
||||
ClutterActor *st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
||||
GObject *object,
|
||||
const char *property_name);
|
||||
|
||||
ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
|
||||
StThemeNode *theme_node,
|
||||
GIcon *icon,
|
||||
gint size,
|
||||
gint scale);
|
||||
|
||||
ClutterActor *st_texture_cache_load_file_async (StTextureCache *cache,
|
||||
GFile *file,
|
||||
int available_width,
|
||||
int available_height,
|
||||
int scale);
|
||||
|
||||
CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
|
||||
GFile *file,
|
||||
gint scale);
|
||||
|
||||
--
|
||||
2.18.1
|
||||
|
@ -0,0 +1,245 @@
|
||||
From b440c4c529aee18ecc36a7b8a24809bc684cfe5b Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 21 Jan 2019 15:07:15 -0500
|
||||
Subject: [PATCH 4/4] background: refresh background on gl-video-memory-purged
|
||||
signal
|
||||
|
||||
Right now we refresh the background when resuming and when NVIDIA.
|
||||
But mutter has a signal to tell us specifically when to refresh,
|
||||
and the signal is only emitted for NVIDIA, so use that instead.
|
||||
---
|
||||
js/ui/background.js | 9 +++++++--
|
||||
js/ui/layout.js | 12 ------------
|
||||
src/shell-util.c | 9 ---------
|
||||
3 files changed, 7 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/js/ui/background.js b/js/ui/background.js
|
||||
index c61d946a4..ae7ef275e 100644
|
||||
--- a/js/ui/background.js
|
||||
+++ b/js/ui/background.js
|
||||
@@ -512,64 +512,69 @@ var SystemBackground = new Lang.Class({
|
||||
let image = cache.load(file);
|
||||
if (image.is_loaded()) {
|
||||
image = null;
|
||||
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
||||
this.emit('loaded');
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] SystemBackground.loaded');
|
||||
} else {
|
||||
let id = image.connect('loaded', () => {
|
||||
this.emit('loaded');
|
||||
image.disconnect(id);
|
||||
image = null;
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
Signals.addSignalMethods(SystemBackground.prototype);
|
||||
|
||||
var BackgroundSource = new Lang.Class({
|
||||
Name: 'BackgroundSource',
|
||||
|
||||
_init(layoutManager, settingsSchema) {
|
||||
// Allow override the background image setting for performance testing
|
||||
this._layoutManager = layoutManager;
|
||||
this._overrideImage = GLib.getenv('SHELL_BACKGROUND_IMAGE');
|
||||
this._settings = new Gio.Settings({ schema_id: settingsSchema });
|
||||
this._backgrounds = [];
|
||||
|
||||
this._monitorsChangedId = global.screen.connect('monitors-changed',
|
||||
- this._onMonitorsChanged.bind(this));
|
||||
+ this._refresh.bind(this));
|
||||
+
|
||||
+ global.display.connect('gl-video-memory-purged', () => {
|
||||
+ Meta.Background.refresh_all();
|
||||
+ this._refresh();
|
||||
+ });
|
||||
},
|
||||
|
||||
- _onMonitorsChanged() {
|
||||
+ _refresh() {
|
||||
for (let monitorIndex in this._backgrounds) {
|
||||
let background = this._backgrounds[monitorIndex];
|
||||
|
||||
if (monitorIndex < this._layoutManager.monitors.length) {
|
||||
background.updateResolution();
|
||||
} else {
|
||||
background.disconnect(background._changedId);
|
||||
background.destroy();
|
||||
delete this._backgrounds[monitorIndex];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getBackground(monitorIndex) {
|
||||
let file = null;
|
||||
let style;
|
||||
|
||||
// We don't watch changes to settings here,
|
||||
// instead we rely on Background to watch those
|
||||
// and emit 'changed' at the right time
|
||||
|
||||
if (this._overrideImage != null) {
|
||||
file = Gio.File.new_for_path(this._overrideImage);
|
||||
style = GDesktopEnums.BackgroundStyle.ZOOM; // Hardcode
|
||||
} else {
|
||||
style = this._settings.get_enum(BACKGROUND_STYLE_KEY);
|
||||
if (style != GDesktopEnums.BackgroundStyle.NONE) {
|
||||
let uri = this._settings.get_string(PICTURE_URI_KEY);
|
||||
file = Gio.File.new_for_commandline_arg(uri);
|
||||
}
|
||||
diff --git a/js/ui/layout.js b/js/ui/layout.js
|
||||
index 6f810395d..2cd1e5bd3 100644
|
||||
--- a/js/ui/layout.js
|
||||
+++ b/js/ui/layout.js
|
||||
@@ -251,72 +251,60 @@ var LayoutManager = new Lang.Class({
|
||||
this.addChrome(this.keyboardBox);
|
||||
this._keyboardHeightNotifyId = 0;
|
||||
|
||||
// A dummy actor that tracks the mouse or text cursor, based on the
|
||||
// position and size set in setDummyCursorGeometry.
|
||||
this.dummyCursor = new St.Widget({ width: 0, height: 0, visible: false });
|
||||
this.uiGroup.add_actor(this.dummyCursor);
|
||||
|
||||
global.stage.remove_actor(global.top_window_group);
|
||||
this.uiGroup.add_actor(global.top_window_group);
|
||||
|
||||
let feedbackGroup = Meta.get_feedback_group_for_screen(global.screen);
|
||||
global.stage.remove_actor(feedbackGroup);
|
||||
this.uiGroup.add_actor(feedbackGroup);
|
||||
|
||||
this._backgroundGroup = new Meta.BackgroundGroup();
|
||||
global.window_group.add_child(this._backgroundGroup);
|
||||
this._backgroundGroup.lower_bottom();
|
||||
this._bgManagers = [];
|
||||
|
||||
// Need to update struts on new workspaces when they are added
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
this._queueUpdateRegions.bind(this));
|
||||
global.screen.connect('restacked',
|
||||
this._windowsRestacked.bind(this));
|
||||
global.screen.connect('monitors-changed',
|
||||
this._monitorsChanged.bind(this));
|
||||
global.screen.connect('in-fullscreen-changed',
|
||||
this._updateFullscreen.bind(this));
|
||||
this._monitorsChanged();
|
||||
-
|
||||
- // NVIDIA drivers don't preserve FBO contents across
|
||||
- // suspend/resume, see
|
||||
- // https://bugzilla.gnome.org/show_bug.cgi?id=739178
|
||||
- if (Shell.util_need_background_refresh()) {
|
||||
- LoginManager.getLoginManager().connect('prepare-for-sleep',
|
||||
- (lm, suspending) => {
|
||||
- if (suspending)
|
||||
- return;
|
||||
- Meta.Background.refresh_all();
|
||||
- });
|
||||
- }
|
||||
},
|
||||
|
||||
// This is called by Main after everything else is constructed
|
||||
init() {
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
|
||||
this._loadBackground();
|
||||
},
|
||||
|
||||
showOverview() {
|
||||
this.overviewGroup.show();
|
||||
|
||||
this._inOverview = true;
|
||||
this._updateVisibility();
|
||||
},
|
||||
|
||||
hideOverview() {
|
||||
this.overviewGroup.hide();
|
||||
|
||||
this._inOverview = false;
|
||||
this._updateVisibility();
|
||||
},
|
||||
|
||||
_sessionUpdated() {
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_updateMonitors() {
|
||||
let screen = global.screen;
|
||||
diff --git a/src/shell-util.c b/src/shell-util.c
|
||||
index c43bf4cc5..c63c6efb7 100644
|
||||
--- a/src/shell-util.c
|
||||
+++ b/src/shell-util.c
|
||||
@@ -369,69 +369,60 @@ shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
|
||||
sprite = meta_cursor_tracker_get_sprite (tracker);
|
||||
if (sprite)
|
||||
{
|
||||
clutter_actor_show (CLUTTER_ACTOR (texture));
|
||||
clutter_texture_set_cogl_texture (texture, sprite);
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_hide (CLUTTER_ACTOR (texture));
|
||||
}
|
||||
}
|
||||
|
||||
typedef const gchar *(*ShellGLGetString) (GLenum);
|
||||
|
||||
static const gchar *
|
||||
get_gl_vendor (void)
|
||||
{
|
||||
static const gchar *vendor = NULL;
|
||||
|
||||
if (!vendor)
|
||||
{
|
||||
ShellGLGetString gl_get_string;
|
||||
gl_get_string = (ShellGLGetString) cogl_get_proc_address ("glGetString");
|
||||
if (gl_get_string)
|
||||
vendor = gl_get_string (GL_VENDOR);
|
||||
}
|
||||
|
||||
return vendor;
|
||||
}
|
||||
|
||||
-gboolean
|
||||
-shell_util_need_background_refresh (void)
|
||||
-{
|
||||
- if (g_strcmp0 (get_gl_vendor (), "NVIDIA Corporation") == 0)
|
||||
- return TRUE;
|
||||
-
|
||||
- return FALSE;
|
||||
-}
|
||||
-
|
||||
static gboolean
|
||||
canvas_draw_cb (ClutterContent *content,
|
||||
cairo_t *cr,
|
||||
gint width,
|
||||
gint height,
|
||||
gpointer user_data)
|
||||
{
|
||||
cairo_surface_t *surface = user_data;
|
||||
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_util_get_content_for_window_actor:
|
||||
* @window_actor: a #MetaWindowActor
|
||||
* @window_rect: a #MetaRectangle
|
||||
*
|
||||
* Returns: (transfer full): a new #ClutterContent
|
||||
*/
|
||||
ClutterContent *
|
||||
shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
|
||||
MetaRectangle *window_rect)
|
||||
{
|
||||
ClutterActor *texture;
|
||||
ClutterContent *content;
|
||||
cairo_surface_t *surface;
|
||||
cairo_rectangle_int_t clip;
|
||||
--
|
||||
2.18.1
|
||||
|
171
SOURCES/allow-timed-login-with-no-user-list.patch
Normal file
171
SOURCES/allow-timed-login-with-no-user-list.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From ca59b5fa9e089177676c0590924e734910377102 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Tue, 19 Apr 2016 13:12:46 -0400
|
||||
Subject: [PATCH] loginDialog: allow timed login with disabled user list
|
||||
|
||||
At the moment the timed login feature is implemented in the user list.
|
||||
If there's no user list, we don't show the indicator anywhere and
|
||||
don't proceed with timed login.
|
||||
|
||||
This commit allows timed login to work when the user list is disabled.
|
||||
It accomplishes this by putting the timed login indicator on the
|
||||
auth prompt, in that scenario.
|
||||
---
|
||||
data/theme/gnome-shell-sass/_common.scss | 4 +++
|
||||
js/gdm/authPrompt.js | 40 ++++++++++++++++++++++++
|
||||
js/gdm/loginDialog.js | 28 +++++++++++++++--
|
||||
3 files changed, 70 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
|
||||
index 2f05098df..4e82ef58b 100644
|
||||
--- a/data/theme/gnome-shell-sass/_common.scss
|
||||
+++ b/data/theme/gnome-shell-sass/_common.scss
|
||||
@@ -1825,6 +1825,10 @@ StScrollBar {
|
||||
padding-bottom: 12px;
|
||||
spacing: 8px;
|
||||
width: 23em;
|
||||
+ .login-dialog-timed-login-indicator {
|
||||
+ height: 2px;
|
||||
+ background-color: darken($fg_color,40%);
|
||||
+ }
|
||||
}
|
||||
|
||||
.login-dialog-prompt-label {
|
||||
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
|
||||
index 89cef4d5d..e44281117 100644
|
||||
--- a/js/gdm/authPrompt.js
|
||||
+++ b/js/gdm/authPrompt.js
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
+const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Signals = imports.signals;
|
||||
@@ -117,6 +118,11 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this._entry.grab_key_focus();
|
||||
|
||||
+ this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
||||
+ scale_x: 0 });
|
||||
+
|
||||
+ this.actor.add(this._timedLoginIndicator);
|
||||
+
|
||||
this._message = new St.Label({ opacity: 0,
|
||||
styleClass: 'login-dialog-message' });
|
||||
this._message.clutter_text.line_wrap = true;
|
||||
@@ -142,6 +148,40 @@ var AuthPrompt = new Lang.Class({
|
||||
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||
},
|
||||
|
||||
+ showTimedLoginIndicator(time) {
|
||||
+ let hold = new Batch.Hold();
|
||||
+
|
||||
+ this.hideTimedLoginIndicator();
|
||||
+
|
||||
+ let startTime = GLib.get_monotonic_time();
|
||||
+
|
||||
+ this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
|
||||
+ () => {
|
||||
+ let currentTime = GLib.get_monotonic_time();
|
||||
+ let elapsedTime = (currentTime - startTime) / GLib.USEC_PER_SEC;
|
||||
+ this._timedLoginIndicator.scale_x = elapsedTime / time;
|
||||
+ if (elapsedTime >= time) {
|
||||
+ this._timedLoginTimeoutId = 0;
|
||||
+ hold.release();
|
||||
+ return GLib.SOURCE_REMOVE;
|
||||
+ }
|
||||
+
|
||||
+ return GLib.SOURCE_CONTINUE;
|
||||
+ });
|
||||
+
|
||||
+ GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
|
||||
+
|
||||
+ return hold;
|
||||
+ },
|
||||
+
|
||||
+ hideTimedLoginIndicator() {
|
||||
+ if (this._timedLoginTimeoutId) {
|
||||
+ GLib.source_remove(this._timedLoginTimeoutId);
|
||||
+ this._timedLoginTimeoutId = 0;
|
||||
+ }
|
||||
+ this._timedLoginIndicator.scale_x = 0.;
|
||||
+ },
|
||||
+
|
||||
_onDestroy() {
|
||||
if (this._preemptiveAnswerWatchId) {
|
||||
this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
|
||||
index 4a93545af..65d9edf1a 100644
|
||||
--- a/js/gdm/loginDialog.js
|
||||
+++ b/js/gdm/loginDialog.js
|
||||
@@ -738,6 +738,9 @@ var LoginDialog = new Lang.Class({
|
||||
|
||||
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
||||
this._authPrompt.reset();
|
||||
+
|
||||
+ if (this._disableUserList && this._timedLoginUserListHold)
|
||||
+ this._timedLoginUserListHold.release();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1019,17 +1022,33 @@ var LoginDialog = new Lang.Class({
|
||||
},
|
||||
|
||||
_startTimedLogin(userName, delay) {
|
||||
+ this._timedLoginUserName = userName;
|
||||
this._timedLoginItem = null;
|
||||
this._timedLoginDelay = delay;
|
||||
this._timedLoginAnimationTime = delay;
|
||||
|
||||
- let tasks = [() => this._waitForItemForUser(userName),
|
||||
+ let tasks = [() => {
|
||||
+ if (this._disableUserList)
|
||||
+ return;
|
||||
+
|
||||
+ this._timedLoginUserListHold = this._waitForItemForUser(userName);
|
||||
+
|
||||
+ return this._timedLoginUserListHold;
|
||||
+ },
|
||||
|
||||
() => {
|
||||
+ this._timedLoginUserListHold = null;
|
||||
+
|
||||
+ if (this._disableUserList)
|
||||
+ return;
|
||||
+
|
||||
this._timedLoginItem = this._userList.getItemFromUserName(userName);
|
||||
},
|
||||
|
||||
() => {
|
||||
+ if (this._disableUserList)
|
||||
+ return;
|
||||
+
|
||||
// If we're just starting out, start on the right
|
||||
// item.
|
||||
if (!this._userManager.is_loaded) {
|
||||
@@ -1040,6 +1059,9 @@ var LoginDialog = new Lang.Class({
|
||||
this._blockTimedLoginUntilIdle,
|
||||
|
||||
() => {
|
||||
+ if (this._disableUserList)
|
||||
+ return;
|
||||
+
|
||||
this._userList.scrollToItem(this._timedLoginItem);
|
||||
},
|
||||
|
||||
@@ -1064,7 +1086,9 @@ var LoginDialog = new Lang.Class({
|
||||
if (this._timedLoginItem)
|
||||
this._timedLoginItem.hideTimedLoginIndicator();
|
||||
|
||||
- let userName = this._timedLoginItem.user.get_user_name();
|
||||
+ this._authPrompt.hideTimedLoginIndicator();
|
||||
+
|
||||
+ let userName = this._timedLoginUserName;
|
||||
|
||||
if (userName)
|
||||
this._startTimedLogin(userName, this._timedLoginDelay);
|
||||
--
|
||||
2.20.1
|
||||
|
398
SOURCES/backport-im-fixes.patch
Normal file
398
SOURCES/backport-im-fixes.patch
Normal file
@ -0,0 +1,398 @@
|
||||
From 99c77e85b3514e885641ebdc3dee3d4508e08fbf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 16 Jul 2018 23:36:38 +0000
|
||||
Subject: [PATCH 1/6] keyboard: Handle no-window case in FocusTracker
|
||||
|
||||
For windows, the cursor location needs to be adjusted by the frame
|
||||
offsets. However we cannot assume that there is a window, as the
|
||||
shell itself can have the key focus.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/414
|
||||
|
||||
|
||||
(cherry picked from commit 0dee82fb9fa974ebdb4dd77fd85535a6edf207fd)
|
||||
---
|
||||
js/ui/keyboard.js | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/js/ui/keyboard.js b/js/ui/keyboard.js
|
||||
index 5fcdf988a..66653d602 100644
|
||||
--- a/js/ui/keyboard.js
|
||||
+++ b/js/ui/keyboard.js
|
||||
@@ -533,17 +533,25 @@ var FocusTracker = new Lang.Class({
|
||||
},
|
||||
|
||||
_setCurrentRect(rect) {
|
||||
- let frameRect = this._currentWindow.get_frame_rect();
|
||||
- rect.x -= frameRect.x;
|
||||
- rect.y -= frameRect.y;
|
||||
+ if (this._currentWindow) {
|
||||
+ let frameRect = this._currentWindow.get_frame_rect();
|
||||
+ rect.x -= frameRect.x;
|
||||
+ rect.y -= frameRect.y;
|
||||
+ }
|
||||
|
||||
this._rect = rect;
|
||||
this.emit('position-changed');
|
||||
},
|
||||
|
||||
getCurrentRect() {
|
||||
- let frameRect = this._currentWindow.get_frame_rect();
|
||||
- let rect = { x: this._rect.x + frameRect.x, y: this._rect.y + frameRect.y, width: this._rect.width, height: this._rect.height };
|
||||
+ let rect = { x: this._rect.x, y: this._rect.y,
|
||||
+ width: this._rect.width, height: this._rect.height };
|
||||
+
|
||||
+ if (this._currentWindow) {
|
||||
+ let frameRect = this._currentWindow.get_frame_rect();
|
||||
+ rect.x += frameRect.x;
|
||||
+ rect.y += frameRect.y;
|
||||
+ }
|
||||
|
||||
return rect;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From b89224c37afc9cbedbd776bfdd27c57849669fba Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Fri, 29 Jun 2018 17:35:39 +0200
|
||||
Subject: [PATCH 2/6] inputMethod: Handle IBusInputContext::forward-key-press
|
||||
|
||||
The input method may hint that certain keycodes should be pressed/released
|
||||
besides the textual information in ::commit. An example is hitting space
|
||||
in some IMs to commit text, where both ::commit happens, and an space is
|
||||
visibly inserted. In order to handle this properly, we must honor
|
||||
::forward-key-press.
|
||||
|
||||
In order to cater for the case that a keypress is forwarded while handling
|
||||
that same keypress in a physical keyboard, check the current event being
|
||||
handled and just forward it as-is if it matches. This is necessary to
|
||||
prevent state from being doubly set, and the second event silenced away.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/275
|
||||
|
||||
Closes: #275
|
||||
---
|
||||
js/misc/inputMethod.js | 34 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 34 insertions(+)
|
||||
|
||||
diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
|
||||
index 621483243..59b3d78d6 100644
|
||||
--- a/js/misc/inputMethod.js
|
||||
+++ b/js/misc/inputMethod.js
|
||||
@@ -15,6 +15,8 @@ var InputMethod = new Lang.Class({
|
||||
this._purpose = 0;
|
||||
this._enabled = true;
|
||||
this._currentFocus = null;
|
||||
+ this._currentEvent = null;
|
||||
+ this._doForwardEvent = false;
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||
@@ -25,6 +27,9 @@ var InputMethod = new Lang.Class({
|
||||
this._onSourceChanged.bind(this));
|
||||
this._currentSource = this._inputSourceManager.currentSource;
|
||||
|
||||
+ let deviceManager = Clutter.DeviceManager.get_default();
|
||||
+ this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
+
|
||||
if (this._ibus.is_connected())
|
||||
this._onConnected();
|
||||
},
|
||||
@@ -64,6 +69,7 @@ var InputMethod = new Lang.Class({
|
||||
this._context.connect('commit-text', this._onCommitText.bind(this));
|
||||
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
|
||||
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
|
||||
+ this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
|
||||
|
||||
this._updateCapabilities();
|
||||
},
|
||||
@@ -96,6 +102,24 @@ var InputMethod = new Lang.Class({
|
||||
this.set_preedit_text(str, pos);
|
||||
},
|
||||
|
||||
+ _onForwardKeyEvent(context, keyval, keycode, state) {
|
||||
+ let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
|
||||
+
|
||||
+ if (this._currentEvent) {
|
||||
+ // If we are handling this same event in filter_key_press(),
|
||||
+ // just let it go through, sending the same event again will
|
||||
+ // be silenced away because the key counts as pressed.
|
||||
+ if (this._currentEvent.get_key_symbol() == keyval &&
|
||||
+ (this._currentEvent.type() == Clutter.EventType.KEY_PRESS) == press) {
|
||||
+ this._doForwardEvent = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ this._virtualDevice.notify_key(Clutter.get_current_event_time(), keycode,
|
||||
+ press ? Clutter.KeyState.PRESSED : Clutter.KeyState.RELEASED);
|
||||
+ },
|
||||
+
|
||||
vfunc_focus_in(focus) {
|
||||
this._currentFocus = focus;
|
||||
if (this._context) {
|
||||
@@ -197,13 +221,23 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
if (event.type() == Clutter.EventType.KEY_RELEASE)
|
||||
state |= IBus.ModifierType.RELEASE_MASK;
|
||||
+
|
||||
+ this._currentEvent = event;
|
||||
+ this._doForwardEvent = false;
|
||||
+
|
||||
this._context.process_key_event_async(event.get_key_symbol(),
|
||||
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
|
||||
state, -1, null,
|
||||
(context, res) => {
|
||||
try {
|
||||
let retval = context.process_key_event_async_finish(res);
|
||||
+
|
||||
+ if (this._doForwardEvent)
|
||||
+ retval = false;
|
||||
+
|
||||
this.notify_key_event(event, retval);
|
||||
+ this._doForwardEvent = false;
|
||||
+ this._currentEvent = null;
|
||||
} catch (e) {
|
||||
log('Error processing key on IM: ' + e.message);
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From f8040e59811cd28d9c55d766d6f4c80cf45a226d Mon Sep 17 00:00:00 2001
|
||||
From: Takao Fujiwara <tfujiwar@redhat.com>
|
||||
Date: Tue, 21 Aug 2018 20:21:53 +0900
|
||||
Subject: [PATCH 3/6] inputMethod: Fix to hide preedit text
|
||||
|
||||
ibus_engine_update_preedit_text() should hide the pre-edit text
|
||||
when visible == false.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/431
|
||||
---
|
||||
js/misc/inputMethod.js | 25 +++++++++++++++++++++----
|
||||
1 file changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
|
||||
index 59b3d78d6..320a6cc33 100644
|
||||
--- a/js/misc/inputMethod.js
|
||||
+++ b/js/misc/inputMethod.js
|
||||
@@ -17,6 +17,8 @@ var InputMethod = new Lang.Class({
|
||||
this._currentFocus = null;
|
||||
this._currentEvent = null;
|
||||
this._doForwardEvent = false;
|
||||
+ this._preeditStr = '';
|
||||
+ this._preeditPos = 0;
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
this._ibus.connect('connected', this._onConnected.bind(this));
|
||||
this._ibus.connect('disconnected', this._clear.bind(this));
|
||||
@@ -69,6 +71,8 @@ var InputMethod = new Lang.Class({
|
||||
this._context.connect('commit-text', this._onCommitText.bind(this));
|
||||
this._context.connect('delete-surrounding-text', this._onDeleteSurroundingText.bind(this));
|
||||
this._context.connect('update-preedit-text', this._onUpdatePreeditText.bind(this));
|
||||
+ this._context.connect('show-preedit-text', this._onShowPreeditText.bind(this));
|
||||
+ this._context.connect('hide-preedit-text', this._onHidePreeditText.bind(this));
|
||||
this._context.connect('forward-key-event', this._onForwardKeyEvent.bind(this));
|
||||
|
||||
this._updateCapabilities();
|
||||
@@ -79,6 +83,8 @@ var InputMethod = new Lang.Class({
|
||||
this._hints = 0;
|
||||
this._purpose = 0;
|
||||
this._enabled = false;
|
||||
+ this._preeditStr = ''
|
||||
+ this._preeditPos = 0;
|
||||
},
|
||||
|
||||
_emitRequestSurrounding() {
|
||||
@@ -95,11 +101,22 @@ var InputMethod = new Lang.Class({
|
||||
},
|
||||
|
||||
_onUpdatePreeditText(context, text, pos, visible) {
|
||||
- let str = null;
|
||||
- if (visible && text != null)
|
||||
- str = text.get_text();
|
||||
+ if (text == null)
|
||||
+ return;
|
||||
+ this._preeditStr = text.get_text();
|
||||
+ this._preeditPos = pos;
|
||||
+ if (visible)
|
||||
+ this.set_preedit_text(this._preeditStr, pos);
|
||||
+ else
|
||||
+ this.set_preedit_text(null, pos);
|
||||
+ },
|
||||
+
|
||||
+ _onShowPreeditText(context) {
|
||||
+ this.set_preedit_text(this._preeditStr, this._preeditPos);
|
||||
+ },
|
||||
|
||||
- this.set_preedit_text(str, pos);
|
||||
+ _onHidePreeditText(context) {
|
||||
+ this.set_preedit_text(null, this._preeditPos);
|
||||
},
|
||||
|
||||
_onForwardKeyEvent(context, keyval, keycode, state) {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 43c841a6b9f79b136f8bfe34a28b5c9681006ae7 Mon Sep 17 00:00:00 2001
|
||||
From: Andrea Azzarone <andrea.azzarone@canonical.com>
|
||||
Date: Mon, 17 Sep 2018 18:00:04 +0200
|
||||
Subject: [PATCH 4/6] inputMethod: Add a null-check for text in
|
||||
vfunc_set_surrounding.
|
||||
|
||||
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/579
|
||||
---
|
||||
js/misc/inputMethod.js | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
|
||||
index 320a6cc33..ec84f7277 100644
|
||||
--- a/js/misc/inputMethod.js
|
||||
+++ b/js/misc/inputMethod.js
|
||||
@@ -176,7 +176,7 @@ var InputMethod = new Lang.Class({
|
||||
},
|
||||
|
||||
vfunc_set_surrounding(text, cursor, anchor) {
|
||||
- if (this._context)
|
||||
+ if (this._context && text)
|
||||
this._context.set_surrounding_text(text, cursor, anchor);
|
||||
},
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 5f03edcadcada801100bab027188660fb2a4c3f6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Tue, 11 Sep 2018 15:36:35 +0200
|
||||
Subject: [PATCH 5/6] inputMethod: Fix setting surrounding text
|
||||
|
||||
The underlying ibus method expects an object of type IBusText rather
|
||||
than a plain string.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/228
|
||||
---
|
||||
js/misc/inputMethod.js | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
|
||||
index ec84f7277..7fb78178a 100644
|
||||
--- a/js/misc/inputMethod.js
|
||||
+++ b/js/misc/inputMethod.js
|
||||
@@ -176,8 +176,11 @@ var InputMethod = new Lang.Class({
|
||||
},
|
||||
|
||||
vfunc_set_surrounding(text, cursor, anchor) {
|
||||
- if (this._context && text)
|
||||
- this._context.set_surrounding_text(text, cursor, anchor);
|
||||
+ if (!this._context || !text)
|
||||
+ return;
|
||||
+
|
||||
+ let ibusText = IBus.Text.new_from_string(text);
|
||||
+ this._context.set_surrounding_text(ibusText, cursor, anchor);
|
||||
},
|
||||
|
||||
vfunc_update_content_hints(hints) {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 4ed4039ae031f1ed16bac2e7729c84e300f90534 Mon Sep 17 00:00:00 2001
|
||||
From: Carlos Garnacho <carlosg@gnome.org>
|
||||
Date: Thu, 27 Sep 2018 21:09:02 +0200
|
||||
Subject: [PATCH 6/6] inputMethod: Use forward_key() method to forward key
|
||||
events
|
||||
|
||||
ClutterVirtualInputDevice has the limitation that event flags won't be
|
||||
made to contain CLUTTER_EVENT_FLAG_INPUT_METHOD, possibly causing feedback
|
||||
loops.
|
||||
|
||||
As the event gets injected up the platform dependent bits, we can avoid
|
||||
care on not pressing the same key twice, we still expect coherence between
|
||||
key presses and releases from the IM though.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/531
|
||||
---
|
||||
js/misc/inputMethod.js | 34 ++++++++--------------------------
|
||||
1 file changed, 8 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/js/misc/inputMethod.js b/js/misc/inputMethod.js
|
||||
index 7fb78178a..4a92dc49b 100644
|
||||
--- a/js/misc/inputMethod.js
|
||||
+++ b/js/misc/inputMethod.js
|
||||
@@ -15,8 +15,6 @@ var InputMethod = new Lang.Class({
|
||||
this._purpose = 0;
|
||||
this._enabled = true;
|
||||
this._currentFocus = null;
|
||||
- this._currentEvent = null;
|
||||
- this._doForwardEvent = false;
|
||||
this._preeditStr = '';
|
||||
this._preeditPos = 0;
|
||||
this._ibus = IBus.Bus.new_async();
|
||||
@@ -29,9 +27,6 @@ var InputMethod = new Lang.Class({
|
||||
this._onSourceChanged.bind(this));
|
||||
this._currentSource = this._inputSourceManager.currentSource;
|
||||
|
||||
- let deviceManager = Clutter.DeviceManager.get_default();
|
||||
- this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
|
||||
-
|
||||
if (this._ibus.is_connected())
|
||||
this._onConnected();
|
||||
},
|
||||
@@ -121,20 +116,16 @@ var InputMethod = new Lang.Class({
|
||||
|
||||
_onForwardKeyEvent(context, keyval, keycode, state) {
|
||||
let press = (state & IBus.ModifierType.RELEASE_MASK) == 0;
|
||||
+ state &= ~(IBus.ModifierType.RELEASE_MASK);
|
||||
|
||||
- if (this._currentEvent) {
|
||||
- // If we are handling this same event in filter_key_press(),
|
||||
- // just let it go through, sending the same event again will
|
||||
- // be silenced away because the key counts as pressed.
|
||||
- if (this._currentEvent.get_key_symbol() == keyval &&
|
||||
- (this._currentEvent.type() == Clutter.EventType.KEY_PRESS) == press) {
|
||||
- this._doForwardEvent = true;
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
+ let curEvent = Clutter.get_current_event();
|
||||
+ let time;
|
||||
+ if (curEvent)
|
||||
+ time = curEvent.get_time();
|
||||
+ else
|
||||
+ time = global.display.get_current_time_roundtrip();
|
||||
|
||||
- this._virtualDevice.notify_key(Clutter.get_current_event_time(), keycode,
|
||||
- press ? Clutter.KeyState.PRESSED : Clutter.KeyState.RELEASED);
|
||||
+ this.forward_key(keyval, keycode + 8, state & Clutter.ModifierType.MODIFIER_MASK, time, press);
|
||||
},
|
||||
|
||||
vfunc_focus_in(focus) {
|
||||
@@ -242,22 +233,13 @@ var InputMethod = new Lang.Class({
|
||||
if (event.type() == Clutter.EventType.KEY_RELEASE)
|
||||
state |= IBus.ModifierType.RELEASE_MASK;
|
||||
|
||||
- this._currentEvent = event;
|
||||
- this._doForwardEvent = false;
|
||||
-
|
||||
this._context.process_key_event_async(event.get_key_symbol(),
|
||||
event.get_key_code() - 8, // Convert XKB keycodes to evcodes
|
||||
state, -1, null,
|
||||
(context, res) => {
|
||||
try {
|
||||
let retval = context.process_key_event_async_finish(res);
|
||||
-
|
||||
- if (this._doForwardEvent)
|
||||
- retval = false;
|
||||
-
|
||||
this.notify_key_event(event, retval);
|
||||
- this._doForwardEvent = false;
|
||||
- this._currentEvent = null;
|
||||
} catch (e) {
|
||||
log('Error processing key on IM: ' + e.message);
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
166
SOURCES/disable-unlock-entry-until-question.patch
Normal file
166
SOURCES/disable-unlock-entry-until-question.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From bd6220c0450ab117c851fb1d21ca35ceb76739f8 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 30 Sep 2015 12:51:24 -0400
|
||||
Subject: [PATCH 1/3] authPrompt: don't fade out auth messages if user types
|
||||
password up front
|
||||
|
||||
Right now we fade out any stale auth messages as soon as the user starts
|
||||
typing. This behavior doesn't really make sense if the user is typing up
|
||||
front, before a password is asked.
|
||||
---
|
||||
js/gdm/authPrompt.js | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
|
||||
index 481cd3a77..0ad3d2338 100644
|
||||
--- a/js/gdm/authPrompt.js
|
||||
+++ b/js/gdm/authPrompt.js
|
||||
@@ -176,7 +176,7 @@ var AuthPrompt = new Lang.Class({
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||
|
||||
this._entry.clutter_text.connect('text-changed', () => {
|
||||
- if (!this._userVerifier.hasPendingMessages)
|
||||
+ if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer)
|
||||
this._fadeOutMessage();
|
||||
|
||||
this._updateNextButtonSensitivity(this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING);
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 1aeff45d29983f8b0e970eb9bf15e5d19aa27903 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Wed, 30 Sep 2015 14:36:33 -0400
|
||||
Subject: [PATCH 2/3] authPrompt: don't spin unless answering question
|
||||
|
||||
---
|
||||
js/gdm/authPrompt.js | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
|
||||
index 0ad3d2338..f18ef41f2 100644
|
||||
--- a/js/gdm/authPrompt.js
|
||||
+++ b/js/gdm/authPrompt.js
|
||||
@@ -66,8 +66,8 @@ var AuthPrompt = new Lang.Class({
|
||||
|
||||
this.connect('next', () => {
|
||||
this.updateSensitivity(false);
|
||||
- this.startSpinning();
|
||||
if (this._queryingService) {
|
||||
+ this.startSpinning();
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 6afeaae067b5ad280a0899bd6b10931a9b2f02e4 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 5 Oct 2015 15:26:18 -0400
|
||||
Subject: [PATCH 3/3] authPrompt: stop accepting preemptive answer if user
|
||||
stops typing
|
||||
|
||||
We only want to allow the user to type the preemptive password in
|
||||
one smooth motion. If they start to type, and then stop typing,
|
||||
we should discard their preemptive password as expired.
|
||||
|
||||
Typing ahead the password is just a convenience for users who don't
|
||||
want to manually lift the shift before typing their passwords, after
|
||||
all.
|
||||
---
|
||||
js/gdm/authPrompt.js | 37 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 37 insertions(+)
|
||||
|
||||
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
|
||||
index f18ef41f2..89cef4d5d 100644
|
||||
--- a/js/gdm/authPrompt.js
|
||||
+++ b/js/gdm/authPrompt.js
|
||||
@@ -10,6 +10,7 @@ const St = imports.gi.St;
|
||||
const Animation = imports.ui.animation;
|
||||
const Batch = imports.gdm.batch;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
+const Meta = imports.gi.Meta;
|
||||
const Params = imports.misc.params;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const Tweener = imports.ui.tweener;
|
||||
@@ -47,6 +48,8 @@ var AuthPrompt = new Lang.Class({
|
||||
this._gdmClient = gdmClient;
|
||||
this._mode = mode;
|
||||
|
||||
+ this._idleMonitor = Meta.IdleMonitor.get_core();
|
||||
+
|
||||
let reauthenticationOnly;
|
||||
if (this._mode == AuthPromptMode.UNLOCK_ONLY)
|
||||
reauthenticationOnly = true;
|
||||
@@ -71,6 +74,11 @@ var AuthPrompt = new Lang.Class({
|
||||
this._userVerifier.answerQuery(this._queryingService, this._entry.text);
|
||||
} else {
|
||||
this._preemptiveAnswer = this._entry.text;
|
||||
+
|
||||
+ if (this._preemptiveAnswerWatchId) {
|
||||
+ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
+ this._preemptiveAnswerWatchId = 0;
|
||||
+ }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -135,6 +143,11 @@ var AuthPrompt = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
+ if (this._preemptiveAnswerWatchId) {
|
||||
+ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
+ this._preemptiveAnswerWatchId = 0;
|
||||
+ }
|
||||
+
|
||||
this._userVerifier.destroy();
|
||||
this._userVerifier = null;
|
||||
},
|
||||
@@ -349,6 +362,11 @@ var AuthPrompt = new Lang.Class({
|
||||
},
|
||||
|
||||
setQuestion(question) {
|
||||
+ if (this._preemptiveAnswerWatchId) {
|
||||
+ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
+ this._preemptiveAnswerWatchId = 0;
|
||||
+ }
|
||||
+
|
||||
this._label.set_text(question);
|
||||
|
||||
this._label.show();
|
||||
@@ -434,12 +452,31 @@ var AuthPrompt = new Lang.Class({
|
||||
}
|
||||
},
|
||||
|
||||
+ _onUserStoppedTypePreemptiveAnswer() {
|
||||
+ if (!this._preemptiveAnswerWatchId ||
|
||||
+ this._preemptiveAnswer ||
|
||||
+ this._queryingService)
|
||||
+ return;
|
||||
+
|
||||
+ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
+ this._preemptiveAnswerWatchId = 0;
|
||||
+
|
||||
+ this._entry.text = '';
|
||||
+ this.updateSensitivity(false);
|
||||
+ },
|
||||
+
|
||||
reset() {
|
||||
let oldStatus = this.verificationStatus;
|
||||
this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
|
||||
this.cancelButton.reactive = true;
|
||||
this.nextButton.label = _("Next");
|
||||
|
||||
+ if (this._preemptiveAnswerWatchId) {
|
||||
+ this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
|
||||
+ }
|
||||
+ this._preemptiveAnswerWatchId = this._idleMonitor.add_idle_watch (500,
|
||||
+ this._onUserStoppedTypePreemptiveAnswer.bind(this));
|
||||
+
|
||||
if (this._userVerifier)
|
||||
this._userVerifier.cancel();
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
115
SOURCES/enforce-smartcard-at-unlock.patch
Normal file
115
SOURCES/enforce-smartcard-at-unlock.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 483ac09afb6503432e48bc30a57194a490ec98c9 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 28 Sep 2015 10:57:02 -0400
|
||||
Subject: [PATCH 1/3] smartcardManager: add way to detect if user logged using
|
||||
(any) token
|
||||
|
||||
If a user uses a token at login time, we need to make sure they continue
|
||||
to use the token at unlock time.
|
||||
|
||||
As a prerequisite for addressing that problem we need to know up front
|
||||
if a user logged in with a token at all.
|
||||
|
||||
This commit adds the necessary api to detect that case.
|
||||
---
|
||||
js/misc/smartcardManager.js | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/js/misc/smartcardManager.js b/js/misc/smartcardManager.js
|
||||
index 60808b371..a9a748fb3 100644
|
||||
--- a/js/misc/smartcardManager.js
|
||||
+++ b/js/misc/smartcardManager.js
|
||||
@@ -112,6 +112,13 @@ var SmartcardManager = new Lang.Class({
|
||||
return false;
|
||||
|
||||
return true;
|
||||
+ },
|
||||
+
|
||||
+ loggedInWithToken() {
|
||||
+ if (this._loginToken)
|
||||
+ return true;
|
||||
+
|
||||
+ return false;
|
||||
}
|
||||
|
||||
});
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 5da6b6393ac89eaae91d2b250fb432c7e1cbe676 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 28 Sep 2015 19:56:53 -0400
|
||||
Subject: [PATCH 2/3] gdm: only unlock with smartcard, if smartcard used for
|
||||
login
|
||||
|
||||
If a smartcard is used for login, we need to make sure the smartcard
|
||||
gets used for unlock, too.
|
||||
---
|
||||
js/gdm/util.js | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/js/gdm/util.js b/js/gdm/util.js
|
||||
index 261e1e433..3d6d69c10 100644
|
||||
--- a/js/gdm/util.js
|
||||
+++ b/js/gdm/util.js
|
||||
@@ -134,7 +134,6 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this._settings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
||||
this._settings.connect('changed',
|
||||
this._updateDefaultService.bind(this));
|
||||
- this._updateDefaultService();
|
||||
|
||||
this._fprintManager = Fprint.FprintManager();
|
||||
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
||||
@@ -146,6 +145,8 @@ var ShellUserVerifier = new Lang.Class({
|
||||
this.smartcardDetected = false;
|
||||
this._checkForSmartcard();
|
||||
|
||||
+ this._updateDefaultService();
|
||||
+
|
||||
this._smartcardInsertedId = this._smartcardManager.connect('smartcard-inserted',
|
||||
this._checkForSmartcard.bind(this));
|
||||
this._smartcardRemovedId = this._smartcardManager.connect('smartcard-removed',
|
||||
@@ -412,7 +413,9 @@ var ShellUserVerifier = new Lang.Class({
|
||||
},
|
||||
|
||||
_updateDefaultService() {
|
||||
- if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||
+ if (this._smartcardManager.loggedInWithToken())
|
||||
+ this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||
+ else if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY))
|
||||
this._defaultService = PASSWORD_SERVICE_NAME;
|
||||
else if (this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY))
|
||||
this._defaultService = SMARTCARD_SERVICE_NAME;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 1d6de184a8bfbd54b9472eea822380b89f70509a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
Date: Mon, 28 Sep 2015 19:57:36 -0400
|
||||
Subject: [PATCH 3/3] gdm: update default service when smartcard inserted
|
||||
|
||||
Early on at start up we may not know if a smartcard is
|
||||
available. Make sure we reupdate the default service
|
||||
after we get a smartcard insertion event.
|
||||
---
|
||||
js/gdm/util.js | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/js/gdm/util.js b/js/gdm/util.js
|
||||
index 3d6d69c10..f5f9d5e5d 100644
|
||||
--- a/js/gdm/util.js
|
||||
+++ b/js/gdm/util.js
|
||||
@@ -335,6 +335,8 @@ var ShellUserVerifier = new Lang.Class({
|
||||
else if (this._preemptingService == SMARTCARD_SERVICE_NAME)
|
||||
this._preemptingService = null;
|
||||
|
||||
+ this._updateDefaultService();
|
||||
+
|
||||
this.emit('smartcard-status-changed');
|
||||
}
|
||||
},
|
||||
--
|
||||
2.20.1
|
||||
|
231
SOURCES/fix-close-dialog-annoyances.patch
Normal file
231
SOURCES/fix-close-dialog-annoyances.patch
Normal file
@ -0,0 +1,231 @@
|
||||
From fe9d88cf790282811719ea3343831ce5923687a3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 21 May 2018 21:21:05 +0200
|
||||
Subject: [PATCH 1/3] closeDialog: Disable unredirection while showing
|
||||
|
||||
The dialog won't be visible when unredirection is in place (for example
|
||||
while a fullscreen window is focused), so disable unredirection while
|
||||
the dialog is up.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
|
||||
---
|
||||
js/ui/closeDialog.js | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
||||
index aa0b5ceaf..821480a9c 100644
|
||||
--- a/js/ui/closeDialog.js
|
||||
+++ b/js/ui/closeDialog.js
|
||||
@@ -97,6 +97,8 @@ var CloseDialog = new Lang.Class({
|
||||
if (this._dialog != null)
|
||||
return;
|
||||
|
||||
+ Meta.disable_unredirect_for_screen(global.screen);
|
||||
+
|
||||
this._addWindowEffect();
|
||||
this._initDialog();
|
||||
|
||||
@@ -117,6 +119,8 @@ var CloseDialog = new Lang.Class({
|
||||
if (this._dialog == null)
|
||||
return;
|
||||
|
||||
+ Meta.enable_unredirect_for_screen(global.screen);
|
||||
+
|
||||
let dialog = this._dialog;
|
||||
this._dialog = null;
|
||||
this._removeWindowEffect();
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 0ba4c8fc447338740199cf0250d888716a8181fd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 21 May 2018 23:12:35 +0200
|
||||
Subject: [PATCH 2/3] closeDialog: Periodically check for window to become
|
||||
responsive again
|
||||
|
||||
The close dialog for non-responding windows is closed automatically
|
||||
when we detect that the window is responding again. However as we
|
||||
currently only ping the window in response to certain user actions
|
||||
(like focusing the window or opening the window menu), this can
|
||||
easily go undetected.
|
||||
|
||||
Address this by periodically pinging the window while the close
|
||||
dialog is shown.
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/298
|
||||
---
|
||||
js/ui/closeDialog.js | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
||||
index 821480a9c..7943880d8 100644
|
||||
--- a/js/ui/closeDialog.js
|
||||
+++ b/js/ui/closeDialog.js
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
+const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
@@ -13,6 +14,7 @@ const Tweener = imports.ui.tweener;
|
||||
|
||||
var FROZEN_WINDOW_BRIGHTNESS = -0.3
|
||||
var DIALOG_TRANSITION_TIME = 0.15
|
||||
+var ALIVE_TIMEOUT = 5000;
|
||||
|
||||
var CloseDialog = new Lang.Class({
|
||||
Name: 'CloseDialog',
|
||||
@@ -26,6 +28,7 @@ var CloseDialog = new Lang.Class({
|
||||
this.parent();
|
||||
this._window = window;
|
||||
this._dialog = null;
|
||||
+ this._timeoutId = 0;
|
||||
},
|
||||
|
||||
get window() {
|
||||
@@ -99,6 +102,12 @@ var CloseDialog = new Lang.Class({
|
||||
|
||||
Meta.disable_unredirect_for_screen(global.screen);
|
||||
|
||||
+ this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, ALIVE_TIMEOUT,
|
||||
+ () => {
|
||||
+ this._window.check_alive(global.display.get_current_time_roundtrip());
|
||||
+ return GLib.SOURCE_CONTINUE;
|
||||
+ });
|
||||
+
|
||||
this._addWindowEffect();
|
||||
this._initDialog();
|
||||
|
||||
@@ -121,6 +130,9 @@ var CloseDialog = new Lang.Class({
|
||||
|
||||
Meta.enable_unredirect_for_screen(global.screen);
|
||||
|
||||
+ GLib.source_remove(this._timeoutId);
|
||||
+ this._timeoutId = 0;
|
||||
+
|
||||
let dialog = this._dialog;
|
||||
this._dialog = null;
|
||||
this._removeWindowEffect();
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 7e41beb3fca2bf4809a852cbf6699669fff4cd6f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Tue, 4 Sep 2018 13:53:24 +0200
|
||||
Subject: [PATCH 3/3] closeDialog: Untrack chrome when window loses focus
|
||||
|
||||
On X11, reactive chrome must be added to the input region in order
|
||||
to work as expected. However that region works independently from
|
||||
any window stacking, with the result that the unresponsive-app dialog
|
||||
currently blocks all input in the "covered" area, even in windows
|
||||
stacked above the unresponsive window.
|
||||
|
||||
The correct fix would be to track the unobscured parts of the dialog
|
||||
and set the input region from that, but that's quite cumbersome. So
|
||||
instead, only track chrome when the corresponding window is focused
|
||||
(or the dialog itself of course).
|
||||
|
||||
https://gitlab.gnome.org/GNOME/gnome-shell/issues/273
|
||||
---
|
||||
js/ui/closeDialog.js | 52 +++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 49 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/js/ui/closeDialog.js b/js/ui/closeDialog.js
|
||||
index 7943880d8..c4b033230 100644
|
||||
--- a/js/ui/closeDialog.js
|
||||
+++ b/js/ui/closeDialog.js
|
||||
@@ -28,7 +28,10 @@ var CloseDialog = new Lang.Class({
|
||||
this.parent();
|
||||
this._window = window;
|
||||
this._dialog = null;
|
||||
+ this._tracked = undefined;
|
||||
this._timeoutId = 0;
|
||||
+ this._windowFocusChangedId = 0;
|
||||
+ this._keyFocusChangedId = 0;
|
||||
},
|
||||
|
||||
get window() {
|
||||
@@ -96,6 +99,37 @@ var CloseDialog = new Lang.Class({
|
||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
||||
},
|
||||
|
||||
+ _onFocusChanged() {
|
||||
+ if (Meta.is_wayland_compositor())
|
||||
+ return;
|
||||
+
|
||||
+ let focusWindow = global.display.focus_window;
|
||||
+ let keyFocus = global.stage.key_focus;
|
||||
+
|
||||
+ let shouldTrack;
|
||||
+ if (focusWindow != null)
|
||||
+ shouldTrack = focusWindow == this._window;
|
||||
+ else
|
||||
+ shouldTrack = keyFocus && this._dialog.contains(keyFocus);
|
||||
+
|
||||
+ if (this._tracked === shouldTrack)
|
||||
+ return;
|
||||
+
|
||||
+ if (shouldTrack)
|
||||
+ Main.layoutManager.trackChrome(this._dialog,
|
||||
+ { affectsInputRegion: true });
|
||||
+ else
|
||||
+ Main.layoutManager.untrackChrome(this._dialog);
|
||||
+
|
||||
+ // The buttons are broken when they aren't added to the input region,
|
||||
+ // so disable them properly in that case
|
||||
+ this._dialog.buttonLayout.get_children().forEach(b => {
|
||||
+ b.reactive = shouldTrack;
|
||||
+ });
|
||||
+
|
||||
+ this._tracked = shouldTrack;
|
||||
+ },
|
||||
+
|
||||
vfunc_show() {
|
||||
if (this._dialog != null)
|
||||
return;
|
||||
@@ -108,6 +142,14 @@ var CloseDialog = new Lang.Class({
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
});
|
||||
|
||||
+ this._windowFocusChangedId =
|
||||
+ global.display.connect('notify::focus-window',
|
||||
+ this._onFocusChanged.bind(this));
|
||||
+
|
||||
+ this._keyFocusChangedId =
|
||||
+ global.stage.connect('notify::key-focus',
|
||||
+ this._onFocusChanged.bind(this));
|
||||
+
|
||||
this._addWindowEffect();
|
||||
this._initDialog();
|
||||
|
||||
@@ -118,9 +160,7 @@ var CloseDialog = new Lang.Class({
|
||||
{ scale_y: 1,
|
||||
transition: 'linear',
|
||||
time: DIALOG_TRANSITION_TIME,
|
||||
- onComplete: () => {
|
||||
- Main.layoutManager.trackChrome(this._dialog, { affectsInputRegion: true });
|
||||
- }
|
||||
+ onComplete: this._onFocusChanged.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
@@ -133,6 +173,12 @@ var CloseDialog = new Lang.Class({
|
||||
GLib.source_remove(this._timeoutId);
|
||||
this._timeoutId = 0;
|
||||
|
||||
+ global.display.disconnect(this._windowFocusChangedId)
|
||||
+ this._windowFocusChangedId = 0;
|
||||
+
|
||||
+ global.stage.disconnect(this._keyFocusChangedId);
|
||||
+ this._keyFocusChangedId = 0;
|
||||
+
|
||||
let dialog = this._dialog;
|
||||
this._dialog = null;
|
||||
this._removeWindowEffect();
|
||||
--
|
||||
2.20.1
|
||||
|
500
SOURCES/fix-invalid-access-warnings.patch
Normal file
500
SOURCES/fix-invalid-access-warnings.patch
Normal file
@ -0,0 +1,500 @@
|
||||
From 1c838205dcd99a0a2a901f7449197da3df7b3954 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||||
Date: Tue, 5 Dec 2017 22:41:17 +0100
|
||||
Subject: [PATCH 1/6] dnd: Nullify _dragActor after we've destroyed it, and
|
||||
avoid invalid access
|
||||
|
||||
We need to avoid that we use the _dragActor instance after that it has
|
||||
been destroyed or we'll get errors. We now set it to null when this
|
||||
happens, protecting any access to that.
|
||||
|
||||
Add a DragState enum-like object to keep track of the state
|
||||
instead of using booleans.
|
||||
|
||||
Remove duplicated handler on 'destroy' and just use a generic one.
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=791233
|
||||
---
|
||||
js/ui/dnd.js | 65 +++++++++++++++++++++++++++++++---------------------
|
||||
1 file changed, 39 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
|
||||
index a38607c24..431c60d6c 100644
|
||||
--- a/js/ui/dnd.js
|
||||
+++ b/js/ui/dnd.js
|
||||
@@ -27,6 +27,12 @@ var DragMotionResult = {
|
||||
CONTINUE: 3
|
||||
};
|
||||
|
||||
+var DragState = {
|
||||
+ INIT: 0,
|
||||
+ DRAGGING: 1,
|
||||
+ CANCELLED: 2,
|
||||
+};
|
||||
+
|
||||
var DRAG_CURSOR_MAP = {
|
||||
0: Meta.Cursor.DND_UNSUPPORTED_TARGET,
|
||||
1: Meta.Cursor.DND_COPY,
|
||||
@@ -78,6 +84,8 @@ var _Draggable = new Lang.Class({
|
||||
dragActorOpacity: undefined });
|
||||
|
||||
this.actor = actor;
|
||||
+ this._dragState = DragState.INIT;
|
||||
+
|
||||
if (!params.manualMode) {
|
||||
this.actor.connect('button-press-event',
|
||||
this._onButtonPress.bind(this));
|
||||
@@ -88,7 +96,7 @@ var _Draggable = new Lang.Class({
|
||||
this.actor.connect('destroy', () => {
|
||||
this._actorDestroyed = true;
|
||||
|
||||
- if (this._dragInProgress && this._dragCancellable)
|
||||
+ if (this._dragState == DragState.DRAGGING && this._dragCancellable)
|
||||
this._cancelDrag(global.get_current_time());
|
||||
this.disconnectAll();
|
||||
});
|
||||
@@ -100,7 +108,6 @@ var _Draggable = new Lang.Class({
|
||||
this._dragActorOpacity = params.dragActorOpacity;
|
||||
|
||||
this._buttonDown = false; // The mouse button has been pressed and has not yet been released.
|
||||
- this._dragInProgress = false; // The drag has been started, and has not been dropped or cancelled yet.
|
||||
this._animationInProgress = false; // The drag is over and the item is in the process of animating to its original position (snapping back or reverting).
|
||||
this._dragCancellable = true;
|
||||
|
||||
@@ -206,9 +213,10 @@ var _Draggable = new Lang.Class({
|
||||
(event.type() == Clutter.EventType.TOUCH_END &&
|
||||
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
||||
this._buttonDown = false;
|
||||
- if (this._dragInProgress) {
|
||||
+ if (this._dragState == DragState.DRAGGING) {
|
||||
return this._dragActorDropped(event);
|
||||
- } else if (this._dragActor != null && !this._animationInProgress) {
|
||||
+ } else if ((this._dragActor != null || this._dragState == DragState.CANCELLED) &&
|
||||
+ !this._animationInProgress) {
|
||||
// Drag must have been cancelled with Esc.
|
||||
this._dragComplete();
|
||||
return Clutter.EVENT_STOP;
|
||||
@@ -222,14 +230,14 @@ var _Draggable = new Lang.Class({
|
||||
} else if (event.type() == Clutter.EventType.MOTION ||
|
||||
(event.type() == Clutter.EventType.TOUCH_UPDATE &&
|
||||
global.display.is_pointer_emulating_sequence(event.get_event_sequence()))) {
|
||||
- if (this._dragInProgress) {
|
||||
+ if (this._dragActor && this._dragState == DragState.DRAGGING) {
|
||||
return this._updateDragPosition(event);
|
||||
- } else if (this._dragActor == null) {
|
||||
+ } else if (this._dragActor == null && this._dragState != DragState.CANCELLED) {
|
||||
return this._maybeStartDrag(event);
|
||||
}
|
||||
// We intercept KEY_PRESS event so that we can process Esc key press to cancel
|
||||
// dragging and ignore all other key presses.
|
||||
- } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragInProgress) {
|
||||
+ } else if (event.type() == Clutter.EventType.KEY_PRESS && this._dragState == DragState.DRAGGING) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this._cancelDrag(event.get_time());
|
||||
@@ -265,7 +273,7 @@ var _Draggable = new Lang.Class({
|
||||
*/
|
||||
startDrag(stageX, stageY, time, sequence) {
|
||||
currentDraggable = this;
|
||||
- this._dragInProgress = true;
|
||||
+ this._dragState = DragState.DRAGGING;
|
||||
|
||||
// Special-case St.Button: the pointer grab messes with the internal
|
||||
// state, so force a reset to a reasonable state here
|
||||
@@ -342,6 +350,13 @@ var _Draggable = new Lang.Class({
|
||||
Shell.util_set_hidden_from_pick(this._dragActor, true);
|
||||
}
|
||||
|
||||
+ this._dragActorDestroyId = this._dragActor.connect('destroy', () => {
|
||||
+ // Cancel ongoing animation (if any)
|
||||
+ this._finishAnimation();
|
||||
+
|
||||
+ this._dragActor = null;
|
||||
+ this._dragState = DragState.CANCELLED;
|
||||
+ });
|
||||
this._dragOrigOpacity = this._dragActor.opacity;
|
||||
if (this._dragActorOpacity != undefined)
|
||||
this._dragActor.opacity = this._dragActorOpacity;
|
||||
@@ -500,7 +515,7 @@ var _Draggable = new Lang.Class({
|
||||
event.get_time())) {
|
||||
// If it accepted the drop without taking the actor,
|
||||
// handle it ourselves.
|
||||
- if (this._dragActor.get_parent() == Main.uiGroup) {
|
||||
+ if (this._dragActor && this._dragActor.get_parent() == Main.uiGroup) {
|
||||
if (this._restoreOnSuccess) {
|
||||
this._restoreDragActor(event.get_time());
|
||||
return true;
|
||||
@@ -508,7 +523,7 @@ var _Draggable = new Lang.Class({
|
||||
this._dragActor.destroy();
|
||||
}
|
||||
|
||||
- this._dragInProgress = false;
|
||||
+ this._dragState = DragState.INIT;
|
||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||
this.emit('drag-end', event.get_time(), true);
|
||||
this._dragComplete();
|
||||
@@ -557,20 +572,22 @@ var _Draggable = new Lang.Class({
|
||||
|
||||
_cancelDrag(eventTime) {
|
||||
this.emit('drag-cancelled', eventTime);
|
||||
- this._dragInProgress = false;
|
||||
- let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
||||
+ let wasCancelled = (this._dragState == DragState.CANCELLED);
|
||||
+ this._dragState = DragState.CANCELLED;
|
||||
|
||||
- if (this._actorDestroyed) {
|
||||
+ if (this._actorDestroyed || wasCancelled) {
|
||||
global.screen.set_cursor(Meta.Cursor.DEFAULT);
|
||||
if (!this._buttonDown)
|
||||
this._dragComplete();
|
||||
this.emit('drag-end', eventTime, false);
|
||||
- if (!this._dragOrigParent)
|
||||
+ if (!this._dragOrigParent && this._dragActor)
|
||||
this._dragActor.destroy();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+ let [snapBackX, snapBackY, snapBackScale] = this._getRestoreLocation();
|
||||
+
|
||||
this._animateDragEnd(eventTime,
|
||||
{ x: snapBackX,
|
||||
y: snapBackY,
|
||||
@@ -581,7 +598,7 @@ var _Draggable = new Lang.Class({
|
||||
},
|
||||
|
||||
_restoreDragActor(eventTime) {
|
||||
- this._dragInProgress = false;
|
||||
+ this._dragState = DragState.INIT;
|
||||
let [restoreX, restoreY, restoreScale] = this._getRestoreLocation();
|
||||
|
||||
// fade the actor back in at its original location
|
||||
@@ -596,12 +613,6 @@ var _Draggable = new Lang.Class({
|
||||
_animateDragEnd(eventTime, params) {
|
||||
this._animationInProgress = true;
|
||||
|
||||
- // finish animation if the actor gets destroyed
|
||||
- // during it
|
||||
- this._dragActorDestroyId =
|
||||
- this._dragActor.connect('destroy',
|
||||
- this._finishAnimation.bind(this));
|
||||
-
|
||||
params['opacity'] = this._dragOrigOpacity;
|
||||
params['transition'] = 'easeOutQuad';
|
||||
params['onComplete'] = this._onAnimationComplete;
|
||||
@@ -624,9 +635,6 @@ var _Draggable = new Lang.Class({
|
||||
},
|
||||
|
||||
_onAnimationComplete(dragActor, eventTime) {
|
||||
- dragActor.disconnect(this._dragActorDestroyId);
|
||||
- this._dragActorDestroyId = 0;
|
||||
-
|
||||
if (this._dragOrigParent) {
|
||||
Main.uiGroup.remove_child(this._dragActor);
|
||||
this._dragOrigParent.add_actor(this._dragActor);
|
||||
@@ -641,7 +649,7 @@ var _Draggable = new Lang.Class({
|
||||
},
|
||||
|
||||
_dragComplete() {
|
||||
- if (!this._actorDestroyed)
|
||||
+ if (!this._actorDestroyed && this._dragActor)
|
||||
Shell.util_set_hidden_from_pick(this._dragActor, false);
|
||||
|
||||
this._ungrabEvents();
|
||||
@@ -652,7 +660,12 @@ var _Draggable = new Lang.Class({
|
||||
this._updateHoverId = 0;
|
||||
}
|
||||
|
||||
- this._dragActor = undefined;
|
||||
+ if (this._dragActor) {
|
||||
+ this._dragActor.disconnect(this._dragActorDestroyId);
|
||||
+ this._dragActor = null;
|
||||
+ }
|
||||
+
|
||||
+ this._dragState = DragState.INIT;
|
||||
currentDraggable = null;
|
||||
}
|
||||
});
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 98fd633f3b124f72f71aa5da38df9c69121fd4ed Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Thu, 3 Jan 2019 11:53:13 +0100
|
||||
Subject: [PATCH 2/6] dnd: Repick target actor if destroyed mid iteration
|
||||
|
||||
The picked target actor may be destroyed (e.g. hover style change
|
||||
resulting in the ClutterTexture to be destroyed). If we don't handle
|
||||
this, GJS will abort when it sees the exception caused by Javascript
|
||||
code trying to access the destroyed target actor.
|
||||
|
||||
To handle it, listen on the 'destroy' signal on the target actor, and
|
||||
repick, so a valid actor is passed to the next motion callback.
|
||||
|
||||
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/632
|
||||
---
|
||||
js/ui/dnd.js | 22 ++++++++++++++++++++--
|
||||
1 file changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/js/ui/dnd.js b/js/ui/dnd.js
|
||||
index 431c60d6c..9e961a186 100644
|
||||
--- a/js/ui/dnd.js
|
||||
+++ b/js/ui/dnd.js
|
||||
@@ -411,10 +411,15 @@ var _Draggable = new Lang.Class({
|
||||
return true;
|
||||
},
|
||||
|
||||
+ _pickTargetActor() {
|
||||
+ return this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
+ this._dragX, this._dragY);
|
||||
+ },
|
||||
+
|
||||
_updateDragHover() {
|
||||
this._updateHoverId = 0;
|
||||
- let target = this._dragActor.get_stage().get_actor_at_pos(Clutter.PickMode.ALL,
|
||||
- this._dragX, this._dragY);
|
||||
+ let target = this._pickTargetActor();
|
||||
+
|
||||
let dragEvent = {
|
||||
x: this._dragX,
|
||||
y: this._dragY,
|
||||
@@ -422,6 +427,18 @@ var _Draggable = new Lang.Class({
|
||||
source: this.actor._delegate,
|
||||
targetActor: target
|
||||
};
|
||||
+
|
||||
+ let targetActorDestroyHandlerId;
|
||||
+ let handleTargetActorDestroyClosure;
|
||||
+ handleTargetActorDestroyClosure = () => {
|
||||
+ target = this._pickTargetActor();
|
||||
+ dragEvent.targetActor = target;
|
||||
+ targetActorDestroyHandlerId =
|
||||
+ target.connect('destroy', handleTargetActorDestroyClosure);
|
||||
+ };
|
||||
+ targetActorDestroyHandlerId =
|
||||
+ target.connect('destroy', handleTargetActorDestroyClosure);
|
||||
+
|
||||
for (let i = 0; i < dragMonitors.length; i++) {
|
||||
let motionFunc = dragMonitors[i].dragMotion;
|
||||
if (motionFunc) {
|
||||
@@ -432,6 +449,7 @@ var _Draggable = new Lang.Class({
|
||||
}
|
||||
}
|
||||
}
|
||||
+ dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
|
||||
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.handleDragOver) {
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 2dfae7213f0d3849dfcc38bb2fbaeaf80d4e8b19 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||||
Date: Wed, 4 Jul 2018 15:56:25 +0200
|
||||
Subject: [PATCH 3/6] messageList: stop syncing if closeButton has been
|
||||
destroyed
|
||||
|
||||
The _sync function for Message only updates the close button visibility,
|
||||
so we can safely stop doing that if the close button get get destroyed earlier
|
||||
(as it happens when clicking on it).
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=791233
|
||||
---
|
||||
js/ui/messageList.js | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/js/ui/messageList.js b/js/ui/messageList.js
|
||||
index aff201ed6..2d397c1d7 100644
|
||||
--- a/js/ui/messageList.js
|
||||
+++ b/js/ui/messageList.js
|
||||
@@ -362,7 +362,8 @@ var Message = new Lang.Class({
|
||||
this.setBody(body);
|
||||
|
||||
this._closeButton.connect('clicked', this.close.bind(this));
|
||||
- this.actor.connect('notify::hover', this._sync.bind(this));
|
||||
+ let actorHoverId = this.actor.connect('notify::hover', this._sync.bind(this));
|
||||
+ this._closeButton.connect('destroy', this.actor.disconnect.bind(this.actor, actorHoverId));
|
||||
this.actor.connect('clicked', this._onClicked.bind(this));
|
||||
this.actor.connect('destroy', this._onDestroy.bind(this));
|
||||
this._sync();
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From 41bde330384ba7021c96ea3d4575bfa12295dff1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||||
Date: Wed, 4 Jul 2018 16:55:28 +0200
|
||||
Subject: [PATCH 4/6] automountManager: remove allowAutorun expire timeout on
|
||||
volume removal
|
||||
|
||||
If the volume is removed before AUTORUN_EXPIRE_TIMEOUT_SECS seconds, we can stop
|
||||
the timeout earlier as there's nothing to unset, while the volume instance
|
||||
won't be valid anymore.
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=791233
|
||||
---
|
||||
js/ui/components/automountManager.js | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/js/ui/components/automountManager.js b/js/ui/components/automountManager.js
|
||||
index 2d8f3f8fb..a6cd85792 100644
|
||||
--- a/js/ui/components/automountManager.js
|
||||
+++ b/js/ui/components/automountManager.js
|
||||
@@ -210,6 +210,10 @@ var AutomountManager = new Lang.Class({
|
||||
},
|
||||
|
||||
_onVolumeRemoved(monitor, volume) {
|
||||
+ if (volume._allowAutorunExpireId && volume._allowAutorunExpireId > 0) {
|
||||
+ Mainloop.source_remove(volume._allowAutorunExpireId);
|
||||
+ delete volume._allowAutorunExpireId;
|
||||
+ }
|
||||
this._volumeQueue =
|
||||
this._volumeQueue.filter(element => (element != volume));
|
||||
},
|
||||
@@ -234,8 +238,10 @@ var AutomountManager = new Lang.Class({
|
||||
_allowAutorunExpire(volume) {
|
||||
let id = Mainloop.timeout_add_seconds(AUTORUN_EXPIRE_TIMEOUT_SECS, () => {
|
||||
volume.allowAutorun = false;
|
||||
+ delete volume._allowAutorunExpireId;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
+ volume._allowAutorunExpireId = id;
|
||||
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
||||
}
|
||||
});
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From f0d608cea903538683b2eaafadbdefe7ff41475e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Mon, 9 Jul 2018 13:31:26 +0200
|
||||
Subject: [PATCH 5/6] calendar: chain up to parent on _onDestroy
|
||||
|
||||
---
|
||||
js/ui/calendar.js | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/js/ui/calendar.js b/js/ui/calendar.js
|
||||
index a46017ad0..65133d9f7 100644
|
||||
--- a/js/ui/calendar.js
|
||||
+++ b/js/ui/calendar.js
|
||||
@@ -802,6 +802,8 @@ var NotificationMessage = new Lang.Class({
|
||||
},
|
||||
|
||||
_onDestroy() {
|
||||
+ this.parent();
|
||||
+
|
||||
if (this._updatedId)
|
||||
this.notification.disconnect(this._updatedId);
|
||||
this._updatedId = 0;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
|
||||
From dc75a4e785e5f19f61bfd8f58e079c0bdfd0fca8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||||
Date: Tue, 5 Dec 2017 02:41:50 +0100
|
||||
Subject: [PATCH 6/6] tweener: Save handlers on target and remove them on
|
||||
destroy
|
||||
|
||||
Saving handlers we had using the wrapper as a property of the object and delete
|
||||
them when resetting the object state.
|
||||
Without doing this an handler could be called on a destroyed target when this
|
||||
happens on the onComplete callback.
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=791233
|
||||
---
|
||||
js/ui/tweener.js | 63 ++++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 50 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/js/ui/tweener.js b/js/ui/tweener.js
|
||||
index 1a85e2fb1..22818ba4b 100644
|
||||
--- a/js/ui/tweener.js
|
||||
+++ b/js/ui/tweener.js
|
||||
@@ -69,30 +69,67 @@ function _getTweenState(target) {
|
||||
return target.__ShellTweenerState;
|
||||
}
|
||||
|
||||
+function _ensureHandlers(target) {
|
||||
+ if (!target.__ShellTweenerHandlers)
|
||||
+ target.__ShellTweenerHandlers = {};
|
||||
+ return target.__ShellTweenerHandlers;
|
||||
+}
|
||||
+
|
||||
function _resetTweenState(target) {
|
||||
let state = target.__ShellTweenerState;
|
||||
|
||||
if (state) {
|
||||
- if (state.destroyedId)
|
||||
+ if (state.destroyedId) {
|
||||
state.actor.disconnect(state.destroyedId);
|
||||
+ delete state.destroyedId;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ _removeHandler(target, 'onComplete', _tweenCompleted);
|
||||
target.__ShellTweenerState = {};
|
||||
}
|
||||
|
||||
function _addHandler(target, params, name, handler) {
|
||||
- if (params[name]) {
|
||||
- let oldHandler = params[name];
|
||||
- let oldScope = params[name + 'Scope'];
|
||||
- let oldParams = params[name + 'Params'];
|
||||
- let eventScope = oldScope ? oldScope : target;
|
||||
-
|
||||
- params[name] = () => {
|
||||
- oldHandler.apply(eventScope, oldParams);
|
||||
- handler(target);
|
||||
- };
|
||||
- } else
|
||||
- params[name] = () => { handler(target); };
|
||||
+ let wrapperNeeded = false;
|
||||
+ let tweenerHandlers = _ensureHandlers(target);
|
||||
+
|
||||
+ if (!(name in tweenerHandlers)) {
|
||||
+ tweenerHandlers[name] = [];
|
||||
+ wrapperNeeded = true;
|
||||
+ }
|
||||
+
|
||||
+ let handlers = tweenerHandlers[name];
|
||||
+ handlers.push(handler);
|
||||
+
|
||||
+ if (wrapperNeeded) {
|
||||
+ if (params[name]) {
|
||||
+ let oldHandler = params[name];
|
||||
+ let oldScope = params[name + 'Scope'];
|
||||
+ let oldParams = params[name + 'Params'];
|
||||
+ let eventScope = oldScope ? oldScope : target;
|
||||
+
|
||||
+ params[name] = () => {
|
||||
+ oldHandler.apply(eventScope, oldParams);
|
||||
+ handlers.forEach((h) => h(target));
|
||||
+ };
|
||||
+ } else {
|
||||
+ params[name] = () => { handlers.forEach((h) => h(target)); };
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+function _removeHandler(target, name, handler) {
|
||||
+ let tweenerHandlers = _ensureHandlers(target);
|
||||
+
|
||||
+ if (name in tweenerHandlers) {
|
||||
+ let handlers = tweenerHandlers[name];
|
||||
+ let handlerIndex = handlers.indexOf(handler);
|
||||
+
|
||||
+ while (handlerIndex > -1) {
|
||||
+ handlers.splice(handlerIndex, 1);
|
||||
+ handlerIndex = handlers.indexOf(handler);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
function _actorDestroyed(target) {
|
||||
--
|
||||
2.20.1
|
||||
|
21
SOURCES/gnome-shell-favourite-apps-firefox.patch
Normal file
21
SOURCES/gnome-shell-favourite-apps-firefox.patch
Normal file
@ -0,0 +1,21 @@
|
||||
--- gnome-shell-3.13.90/data/org.gnome.shell.gschema.xml.in.firefox 2014-08-20 20:28:07.601133033 +0200
|
||||
+++ gnome-shell-3.13.90/data/org.gnome.shell.gschema.xml.in 2014-08-20 20:28:41.741503518 +0200
|
||||
@@ -31,7 +31,7 @@
|
||||
</description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
- <default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
+ <default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
<summary>List of desktop file IDs for favorite applications</summary>
|
||||
<description>
|
||||
The applications corresponding to these identifiers
|
||||
--- a/js/ui/appFavorites.js
|
||||
+++ b/js/ui/appFavorites.js
|
||||
@@ -31,6 +31,7 @@ const RENAMED_DESKTOP_IDS = {
|
||||
'gnotravex.desktop': 'gnome-tetravex.desktop',
|
||||
'gnotski.desktop': 'gnome-klotski.desktop',
|
||||
'gtali.desktop': 'tali.desktop',
|
||||
+ 'mozilla-firefox.desktop': 'firefox.desktop',
|
||||
'nautilus.desktop': 'org.gnome.Nautilus.desktop',
|
||||
'polari.desktop': 'org.gnome.Polari.desktop',
|
||||
'totem.desktop': 'org.gnome.Totem.desktop',
|
25
SOURCES/gnome-shell-favourite-apps-terminal.patch
Normal file
25
SOURCES/gnome-shell-favourite-apps-terminal.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 78386767ec5e7b249186133333462d9866c6e18e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Thu, 9 Mar 2017 14:44:32 +0100
|
||||
Subject: [PATCH] appFavorites: Add terminal
|
||||
|
||||
---
|
||||
data/org.gnome.shell.gschema.xml.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in
|
||||
index 8fb7f7291..6f1459c86 100644
|
||||
--- a/data/org.gnome.shell.gschema.xml.in
|
||||
+++ b/data/org.gnome.shell.gschema.xml.in
|
||||
@@ -39,7 +39,7 @@
|
||||
</description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
- <default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop' ]</default>
|
||||
+ <default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop', 'gnome-terminal.desktop' ]</default>
|
||||
<summary>List of desktop file IDs for favorite applications</summary>
|
||||
<description>
|
||||
The applications corresponding to these identifiers
|
||||
--
|
||||
2.20.1
|
||||
|
26
SOURCES/gnome-shell-favourite-apps-yelp.patch
Normal file
26
SOURCES/gnome-shell-favourite-apps-yelp.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From e2a0880744b7e508fba7728c6810ac43f3ea2a87 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
Date: Thu, 9 Mar 2017 14:44:03 +0100
|
||||
Subject: [PATCH] Add 'yelp' to default favorites
|
||||
|
||||
Help should be easily available, so add it to the default favorites.
|
||||
---
|
||||
data/org.gnome.shell.gschema.xml.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in
|
||||
index 868d8edc9..8fb7f7291 100644
|
||||
--- a/data/org.gnome.shell.gschema.xml.in
|
||||
+++ b/data/org.gnome.shell.gschema.xml.in
|
||||
@@ -39,7 +39,7 @@
|
||||
</description>
|
||||
</key>
|
||||
<key name="favorite-apps" type="as">
|
||||
- <default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
|
||||
+ <default>[ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop', 'yelp.desktop' ]</default>
|
||||
<summary>List of desktop file IDs for favorite applications</summary>
|
||||
<description>
|
||||
The applications corresponding to these identifiers
|
||||
--
|
||||
2.20.1
|
||||
|
1244
SPECS/gnome-shell.spec
Normal file
1244
SPECS/gnome-shell.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user