legacyTray: Add a hideable tray for legacy status icons
Commit 5a8923ef95
removed support for legacy status icons from
the notification system, as we no longer want them to appear as
notifications. As we are unfortunately not quite at a point where
we can remove all support for them for good, so we now need an
alternative place to put them. Add a small dedicated tray at the
bottom which appears when any legacy status icons are active. By
default it is almost completely hidden to not interfere with the
user's windows, but can be expanded on demand to interact with
the icons.
https://bugzilla.gnome.org/show_bug.cgi?id=745162
This commit is contained in:
parent
f1370ef578
commit
874cf0ba15
@ -1327,6 +1327,27 @@ StScrollBar {
|
|||||||
color: pink; }
|
color: pink; }
|
||||||
|
|
||||||
/* Eeeky things */
|
/* Eeeky things */
|
||||||
|
.legacy-tray {
|
||||||
|
background-color: #000;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-bottom-width: 0; }
|
||||||
|
.legacy-tray:ltr {
|
||||||
|
border-radius: 0 6px 0 0;
|
||||||
|
border-left-width: 0; }
|
||||||
|
.legacy-tray:rtl {
|
||||||
|
border-radius: 6px 0 0 0;
|
||||||
|
border-right-width: 0; }
|
||||||
|
|
||||||
|
.legacy-tray-handle StIcon {
|
||||||
|
icon-size: 24px; }
|
||||||
|
|
||||||
|
.legacy-tray-icon-box {
|
||||||
|
padding: 6px;
|
||||||
|
spacing: 12px; }
|
||||||
|
.legacy-tray-icon-box StButton {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px; }
|
||||||
|
|
||||||
.magnifier-zoom-region {
|
.magnifier-zoom-region {
|
||||||
border: 2px solid #215d9c; }
|
border: 2px solid #215d9c; }
|
||||||
.magnifier-zoom-region.full-screen {
|
.magnifier-zoom-region.full-screen {
|
||||||
|
@ -1327,6 +1327,27 @@ StScrollBar {
|
|||||||
color: pink; }
|
color: pink; }
|
||||||
|
|
||||||
/* Eeeky things */
|
/* Eeeky things */
|
||||||
|
.legacy-tray {
|
||||||
|
background-color: #393f3f;
|
||||||
|
border: 1px solid #1c1f1f;
|
||||||
|
border-bottom-width: 0; }
|
||||||
|
.legacy-tray:ltr {
|
||||||
|
border-radius: 0 6px 0 0;
|
||||||
|
border-left-width: 0; }
|
||||||
|
.legacy-tray:rtl {
|
||||||
|
border-radius: 6px 0 0 0;
|
||||||
|
border-right-width: 0; }
|
||||||
|
|
||||||
|
.legacy-tray-handle StIcon {
|
||||||
|
icon-size: 24px; }
|
||||||
|
|
||||||
|
.legacy-tray-icon-box {
|
||||||
|
padding: 6px;
|
||||||
|
spacing: 12px; }
|
||||||
|
.legacy-tray-icon-box StButton {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px; }
|
||||||
|
|
||||||
.magnifier-zoom-region {
|
.magnifier-zoom-region {
|
||||||
border: 2px solid #215d9c; }
|
border: 2px solid #215d9c; }
|
||||||
.magnifier-zoom-region.full-screen {
|
.magnifier-zoom-region.full-screen {
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
<file>ui/layout.js</file>
|
<file>ui/layout.js</file>
|
||||||
<file>ui/lightbox.js</file>
|
<file>ui/lightbox.js</file>
|
||||||
<file>ui/lookingGlass.js</file>
|
<file>ui/lookingGlass.js</file>
|
||||||
|
<file>ui/legacyTray.js</file>
|
||||||
<file>ui/magnifier.js</file>
|
<file>ui/magnifier.js</file>
|
||||||
<file>ui/magnifierDBus.js</file>
|
<file>ui/magnifierDBus.js</file>
|
||||||
<file>ui/main.js</file>
|
<file>ui/main.js</file>
|
||||||
|
178
js/ui/legacyTray.js
Normal file
178
js/ui/legacyTray.js
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const GObject = imports.gi.GObject;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Layout = imports.ui.layout;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Overview = imports.ui.overview;
|
||||||
|
const OverviewControls = imports.ui.overviewControls;
|
||||||
|
const Tweener = imports.ui.tweener;
|
||||||
|
|
||||||
|
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
|
||||||
|
'bluetooth-applet': 'bluetooth',
|
||||||
|
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
|
||||||
|
// when moved to control center
|
||||||
|
'gnome-sound-applet': 'volume',
|
||||||
|
'nm-applet': 'network',
|
||||||
|
'gnome-power-manager': 'battery',
|
||||||
|
'keyboard': 'keyboard',
|
||||||
|
'a11y-keyboard': 'a11y',
|
||||||
|
'kbd-scrolllock': 'keyboard',
|
||||||
|
'kbd-numlock': 'keyboard',
|
||||||
|
'kbd-capslock': 'keyboard',
|
||||||
|
'ibus-ui-gtk': 'keyboard'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Offset of the original position from the bottom-right corner
|
||||||
|
const CONCEALED_VISIBLE_FRACTION = 0.2;
|
||||||
|
const REVEAL_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
|
const LegacyTray = new Lang.Class({
|
||||||
|
Name: 'LegacyTray',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.Widget({ clip_to_allocation: true,
|
||||||
|
layout_manager: new Clutter.BinLayout() });
|
||||||
|
let constraint = new Layout.MonitorConstraint({ primary: true,
|
||||||
|
work_area: true });
|
||||||
|
this.actor.add_constraint(constraint);
|
||||||
|
|
||||||
|
this._slideLayout = new OverviewControls.SlideLayout();
|
||||||
|
this._slideLayout.translationX = 0;
|
||||||
|
this._slideLayout.slideDirection = OverviewControls.SlideDirection.LEFT;
|
||||||
|
|
||||||
|
this._slider = new St.Widget({ style_class: 'legacy-tray',
|
||||||
|
x_expand: true, y_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.START,
|
||||||
|
y_align: Clutter.ActorAlign.END,
|
||||||
|
layout_manager: this._slideLayout });
|
||||||
|
this.actor.add_actor(this._slider);
|
||||||
|
|
||||||
|
this._box = new St.BoxLayout();
|
||||||
|
this._slider.add_actor(this._box);
|
||||||
|
|
||||||
|
this._concealHandle = new St.Button({ style_class: 'legacy-tray-handle' });
|
||||||
|
this._concealHandle.child = new St.Icon({ icon_name: 'go-previous-symbolic' });
|
||||||
|
this._box.add_child(this._concealHandle);
|
||||||
|
|
||||||
|
this._iconBox = new St.BoxLayout({ style_class: 'legacy-tray-icon-box' });
|
||||||
|
this._box.add_actor(this._iconBox);
|
||||||
|
|
||||||
|
this._revealHandle = new St.Button({ style_class: 'legacy-tray-handle' });
|
||||||
|
this._revealHandle.child = new St.Icon({ icon_name: 'go-next-symbolic' });
|
||||||
|
this._box.add_child(this._revealHandle);
|
||||||
|
|
||||||
|
this._revealHandle.bind_property('visible',
|
||||||
|
this._concealHandle, 'visible',
|
||||||
|
GObject.BindingFlags.BIDIRECTIONAL |
|
||||||
|
GObject.BindingFlags.INVERT_BOOLEAN);
|
||||||
|
this._revealHandle.connect('notify::visible',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
|
this._revealHandle.connect('notify::hover',
|
||||||
|
Lang.bind(this ,this._sync));
|
||||||
|
this._revealHandle.connect('clicked', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._concealHandle.show();
|
||||||
|
}));
|
||||||
|
this._concealHandle.connect('clicked', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._revealHandle.show();
|
||||||
|
}));
|
||||||
|
|
||||||
|
Main.layoutManager.addChrome(this.actor, { affectsInputRegion: false });
|
||||||
|
Main.layoutManager.trackChrome(this._slider, { affectsInputRegion: true });
|
||||||
|
|
||||||
|
this._trayManager = new Shell.TrayManager();
|
||||||
|
this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
|
||||||
|
this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
|
||||||
|
this._trayManager.manage_screen(global.screen, this.actor);
|
||||||
|
|
||||||
|
Main.overview.connect('showing', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
Tweener.removeTweens(this._slider);
|
||||||
|
Tweener.addTween(this._slider, { opacity: 0,
|
||||||
|
time: Overview.ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
}));
|
||||||
|
Main.overview.connect('shown', Lang.bind(this, this._sync));
|
||||||
|
Main.overview.connect('hiding', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._sync();
|
||||||
|
Tweener.removeTweens(this._slider);
|
||||||
|
Tweener.addTween(this._slider, { opacity: 255,
|
||||||
|
time: Overview.ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
}));
|
||||||
|
|
||||||
|
Main.layoutManager.connect('monitors-changed',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
|
global.screen.connect('in-fullscreen-changed',
|
||||||
|
Lang.bind(this, this._sync));
|
||||||
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sync));
|
||||||
|
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onTrayIconAdded: function(tm, icon) {
|
||||||
|
let wmClass = icon.wm_class ? icon.wm_class.toLowerCase() : '';
|
||||||
|
if (STANDARD_TRAY_ICON_IMPLEMENTATIONS[wmClass] !== undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let button = new St.Button({ child: icon,
|
||||||
|
button_mask: St.ButtonMask.ONE |
|
||||||
|
St.ButtonMask.TWO |
|
||||||
|
St.ButtonMask.THREE,
|
||||||
|
x_fill: true, y_fill: true });
|
||||||
|
button.connect('clicked',
|
||||||
|
function() {
|
||||||
|
icon.click(Clutter.get_current_event());
|
||||||
|
});
|
||||||
|
|
||||||
|
this._iconBox.add_actor(button);
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onTrayIconRemoved: function(tm, icon) {
|
||||||
|
if (!this.actor.contains(icon))
|
||||||
|
return;
|
||||||
|
|
||||||
|
icon.get_parent().destroy();
|
||||||
|
this._sync();
|
||||||
|
},
|
||||||
|
|
||||||
|
_sync: function() {
|
||||||
|
// FIXME: we no longer treat tray icons as notifications
|
||||||
|
let allowed = Main.sessionMode.hasNotifications;
|
||||||
|
let hasIcons = this._iconBox.get_n_children() > 0;
|
||||||
|
let inOverview = Main.overview.visible && !Main.overview.animationInProgress;
|
||||||
|
let inFullscreen = Main.layoutManager.primaryMonitor.inFullscreen;
|
||||||
|
this.actor.visible = allowed && hasIcons && !inOverview && !inFullscreen;
|
||||||
|
|
||||||
|
if (!hasIcons)
|
||||||
|
this._concealHandle.hide();
|
||||||
|
|
||||||
|
let targetSlide;
|
||||||
|
if (this._concealHandle.visible) {
|
||||||
|
targetSlide = 1.0;
|
||||||
|
} else if (!hasIcons) {
|
||||||
|
targetSlide = 0.0;
|
||||||
|
} else {
|
||||||
|
let [, boxWidth] = this._box.get_preferred_width(-1);
|
||||||
|
let [, handleWidth] = this._revealHandle.get_preferred_width(-1);
|
||||||
|
|
||||||
|
targetSlide = handleWidth / boxWidth;
|
||||||
|
if (!this._revealHandle.hover)
|
||||||
|
targetSlide *= CONCEALED_VISIBLE_FRACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.actor.visible)
|
||||||
|
Tweener.addTween(this._slideLayout,
|
||||||
|
{ slideX: targetSlide,
|
||||||
|
time: REVEAL_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
else
|
||||||
|
this._slideLayout.slideX = targetSlide;
|
||||||
|
}
|
||||||
|
});
|
@ -18,6 +18,7 @@ const Environment = imports.ui.environment;
|
|||||||
const ExtensionSystem = imports.ui.extensionSystem;
|
const ExtensionSystem = imports.ui.extensionSystem;
|
||||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||||
const Keyboard = imports.ui.keyboard;
|
const Keyboard = imports.ui.keyboard;
|
||||||
|
const LegacyTray = imports.ui.legacyTray;
|
||||||
const MessageTray = imports.ui.messageTray;
|
const MessageTray = imports.ui.messageTray;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const OsdWindow = imports.ui.osdWindow;
|
const OsdWindow = imports.ui.osdWindow;
|
||||||
@ -52,6 +53,7 @@ let overview = null;
|
|||||||
let runDialog = null;
|
let runDialog = null;
|
||||||
let lookingGlass = null;
|
let lookingGlass = null;
|
||||||
let wm = null;
|
let wm = null;
|
||||||
|
let legacyTray = null;
|
||||||
let messageTray = null;
|
let messageTray = null;
|
||||||
let screenShield = null;
|
let screenShield = null;
|
||||||
let notificationDaemon = null;
|
let notificationDaemon = null;
|
||||||
@ -159,6 +161,7 @@ function _initializeUI() {
|
|||||||
if (LoginManager.canLock())
|
if (LoginManager.canLock())
|
||||||
screenShield = new ScreenShield.ScreenShield();
|
screenShield = new ScreenShield.ScreenShield();
|
||||||
|
|
||||||
|
legacyTray = new LegacyTray.LegacyTray();
|
||||||
messageTray = new MessageTray.MessageTray();
|
messageTray = new MessageTray.MessageTray();
|
||||||
panel = new Panel.Panel();
|
panel = new Panel.Panel();
|
||||||
keyboard = new Keyboard.Keyboard();
|
keyboard = new Keyboard.Keyboard();
|
||||||
|
Loading…
Reference in New Issue
Block a user