Compare commits
	
		
			21 Commits
		
	
	
		
			wip/notif-
			...
			wip/new-no
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bf374ccabb | ||
| 
						 | 
					02060d2bbc | ||
| 
						 | 
					8750f1edc0 | ||
| 
						 | 
					798f17a97d | ||
| 
						 | 
					a4091adbf2 | ||
| 
						 | 
					ecf795b6ef | ||
| 
						 | 
					75447b249c | ||
| 
						 | 
					26d2fb8a37 | ||
| 
						 | 
					f7223763d2 | ||
| 
						 | 
					0b414308fb | ||
| 
						 | 
					060917ae2b | ||
| 
						 | 
					9f2e5b9b51 | ||
| 
						 | 
					4a07eb77f6 | ||
| 
						 | 
					fbe379c81c | ||
| 
						 | 
					a07e8bbf37 | ||
| 
						 | 
					a6aabb1d3a | ||
| 
						 | 
					aef6273fed | ||
| 
						 | 
					be8b1c7d2d | ||
| 
						 | 
					14bc748cea | ||
| 
						 | 
					c32917f6c1 | ||
| 
						 | 
					182d45dace | 
@@ -1491,58 +1491,54 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
 | 
			
		||||
/* Message Tray */
 | 
			
		||||
 | 
			
		||||
#message-tray {
 | 
			
		||||
    background: #2e3436 url(message-tray-background.png);
 | 
			
		||||
    background-repeat: repeat;
 | 
			
		||||
    height: 72px;
 | 
			
		||||
.notification-drawer {
 | 
			
		||||
    background: rgba(0,0,0,0.8);
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
    border: 2px solid #4c4c4c;
 | 
			
		||||
    border-bottom: 0px;
 | 
			
		||||
    border-radius: 6px 6px 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-summary {
 | 
			
		||||
    height: 72px;
 | 
			
		||||
.system-tray-icons,
 | 
			
		||||
.notification-drawer-footer-actions {
 | 
			
		||||
    spacing: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-menu-button StIcon {
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
    color: #aaaaaa;
 | 
			
		||||
    icon-size: 24px;
 | 
			
		||||
.system-tray-icon-button,
 | 
			
		||||
.notification-drawer-button {
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    border: 1px solid #4c4c4c;
 | 
			
		||||
    padding: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-menu-button:hover StIcon,
 | 
			
		||||
.message-tray-menu-button:active StIcon,
 | 
			
		||||
.message-tray-menu-button:focus StIcon {
 | 
			
		||||
    color: #eeeeee;
 | 
			
		||||
.system-tray-icon-button {
 | 
			
		||||
    width: 22px;
 | 
			
		||||
    height: 22px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-drawer-button StIcon {
 | 
			
		||||
    icon-size: 22px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.system-tray-icon-button:hover,
 | 
			
		||||
.notification-drawer-button:hover {
 | 
			
		||||
    background: 1px solid #4c4c4c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.url-highlighter {
 | 
			
		||||
    link-color: #ccccff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-messages-label {
 | 
			
		||||
    color: #999999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification, #notification-container {
 | 
			
		||||
.notification, #notification-container, .notification-drawer {
 | 
			
		||||
    font-size: 11pt;
 | 
			
		||||
    width: 34em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-main-button,
 | 
			
		||||
.notification-button {
 | 
			
		||||
    background: rgba(0,0,0,0.9);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-main-button {
 | 
			
		||||
    border-radius: 10px 10px 0px 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-main-content {
 | 
			
		||||
    padding: 8px;
 | 
			
		||||
    spacing: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-close-button {
 | 
			
		||||
    padding: 8px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    border-radius: 10px 10px 0px 0px;
 | 
			
		||||
    background: rgba(0,0,0,0.8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-action-area {
 | 
			
		||||
@@ -1551,6 +1547,7 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
 | 
			
		||||
.notification-action-area,
 | 
			
		||||
.notification-button {
 | 
			
		||||
    background: rgba(0,0,0,0.8);
 | 
			
		||||
    border-top: 1px solid #666;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1559,13 +1556,10 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    border-right: 1px solid #666;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-main-button:hover,
 | 
			
		||||
.notification-button:hover,
 | 
			
		||||
.notification-close-button:hover {
 | 
			
		||||
    background: rgba(100,100,100,0.9);
 | 
			
		||||
.notification-button:hover {
 | 
			
		||||
    background: rgba(255,255,255,0.3);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-main-button:active,
 | 
			
		||||
.notification-button:active {
 | 
			
		||||
    background: rgba(255,255,255,0.1);
 | 
			
		||||
}
 | 
			
		||||
@@ -1586,40 +1580,6 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    padding-right: 6px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-boxpointer {
 | 
			
		||||
    -arrow-border-radius: 15px;
 | 
			
		||||
    -arrow-background-color: rgba(0,0,0,0.9);
 | 
			
		||||
    -arrow-base: 36px;
 | 
			
		||||
    -arrow-rise: 18px;
 | 
			
		||||
    color: white;
 | 
			
		||||
    -boxpointer-gap: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-boxpointer .notification {
 | 
			
		||||
    border-radius: 9px;
 | 
			
		||||
    background: rgba(0,0,0,0) !important;
 | 
			
		||||
    padding-bottom: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-boxpointer #summary-right-click-menu {
 | 
			
		||||
    padding-top: 12px;
 | 
			
		||||
    padding-bottom: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-notification-stack-scrollview {
 | 
			
		||||
    max-height: 18em;
 | 
			
		||||
    padding-top: 8px;
 | 
			
		||||
    padding-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-notification-stack-scrollview:ltr {
 | 
			
		||||
    padding-right: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.summary-notification-stack-scrollview:rtl {
 | 
			
		||||
    padding-left: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notification-scrollview {
 | 
			
		||||
    max-height: 10em;
 | 
			
		||||
    -st-vfade-offset: 24px;
 | 
			
		||||
@@ -1740,6 +1700,28 @@ StScrollBar StButton#vhandle:active {
 | 
			
		||||
    -shell-counter-overlap-y: 13px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-indicator {
 | 
			
		||||
    spacing: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-indicator-count {
 | 
			
		||||
    font-size: 1.2em;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
 | 
			
		||||
    color: black;
 | 
			
		||||
    background-color: rgba(255, 255, 255, 0.7);
 | 
			
		||||
    border-radius: 1em;
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.message-tray-indicator-glow {
 | 
			
		||||
    height: 4px;
 | 
			
		||||
    background-gradient-start: rgba(255, 255, 255, 0);
 | 
			
		||||
    background-gradient-end: rgba(255, 255, 255, 1);
 | 
			
		||||
    background-gradient-direction: vertical;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* OSD */
 | 
			
		||||
.osd-window {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
 
 | 
			
		||||
@@ -735,7 +735,11 @@ const ChatNotification = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._lastMessageBox = new St.BoxLayout({ vertical: false });
 | 
			
		||||
        this._lastMessageBox.add(body, props.childProps);
 | 
			
		||||
 | 
			
		||||
        let revealer = new MessageTray.Revealer(body);
 | 
			
		||||
        this._lastMessageBox.add(revealer, props.childProps);
 | 
			
		||||
        revealer.show(true);
 | 
			
		||||
 | 
			
		||||
        this._bodyBox.add_child(this._lastMessageBox);
 | 
			
		||||
 | 
			
		||||
        let timestamp = props.timestamp;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										169
									
								
								js/ui/layout.js
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								js/ui/layout.js
									
									
									
									
									
								
							@@ -22,11 +22,6 @@ const KEYBOARD_ANIMATION_TIME = 0.15;
 | 
			
		||||
const BACKGROUND_FADE_ANIMATION_TIME = 1.0;
 | 
			
		||||
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
 | 
			
		||||
 | 
			
		||||
// The message tray takes this much pressure
 | 
			
		||||
// in the pressure barrier at once to release it.
 | 
			
		||||
const MESSAGE_TRAY_PRESSURE_THRESHOLD = 250; // pixels
 | 
			
		||||
const MESSAGE_TRAY_PRESSURE_TIMEOUT = 1000; // ms
 | 
			
		||||
 | 
			
		||||
const HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
 | 
			
		||||
const HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +145,6 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._keyboardIndex = -1;
 | 
			
		||||
        this._rightPanelBarrier = null;
 | 
			
		||||
        this._trayBarrier = null;
 | 
			
		||||
 | 
			
		||||
        this._inOverview = false;
 | 
			
		||||
        this._updateRegionIdle = 0;
 | 
			
		||||
@@ -210,7 +204,6 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
        this.trayBox = new St.Widget({ name: 'trayBox',
 | 
			
		||||
                                       layout_manager: new Clutter.BinLayout() }); 
 | 
			
		||||
        this.addChrome(this.trayBox);
 | 
			
		||||
        this._setupTrayPressure();
 | 
			
		||||
 | 
			
		||||
        this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup',
 | 
			
		||||
                                                layout_manager: new Clutter.BinLayout() });
 | 
			
		||||
@@ -449,50 +442,9 @@ const LayoutManager = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setupTrayPressure: function() {
 | 
			
		||||
        this._trayPressure = new PressureBarrier(MESSAGE_TRAY_PRESSURE_THRESHOLD,
 | 
			
		||||
                                                 MESSAGE_TRAY_PRESSURE_TIMEOUT,
 | 
			
		||||
                                                 Shell.KeyBindingMode.NORMAL |
 | 
			
		||||
                                                 Shell.KeyBindingMode.OVERVIEW);
 | 
			
		||||
        this._trayPressure.setEventFilter(this._trayBarrierEventFilter);
 | 
			
		||||
        this._trayPressure.connect('trigger', function(barrier) {
 | 
			
		||||
            if (Main.layoutManager.bottomMonitor.inFullscreen)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            Main.messageTray.openTray();
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateTrayBarrier: function() {
 | 
			
		||||
        let monitor = this.bottomMonitor;
 | 
			
		||||
 | 
			
		||||
        if (this._trayBarrier) {
 | 
			
		||||
            this._trayPressure.removeBarrier(this._trayBarrier);
 | 
			
		||||
            this._trayBarrier.destroy();
 | 
			
		||||
            this._trayBarrier = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._trayBarrier = new Meta.Barrier({ display: global.display,
 | 
			
		||||
                                               x1: monitor.x, x2: monitor.x + monitor.width,
 | 
			
		||||
                                               y1: monitor.y + monitor.height, y2: monitor.y + monitor.height,
 | 
			
		||||
                                               directions: Meta.BarrierDirection.NEGATIVE_Y });
 | 
			
		||||
        this._trayPressure.addBarrier(this._trayBarrier);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trayBarrierEventFilter: function(event) {
 | 
			
		||||
        // Throw out all events where the pointer was grabbed by another
 | 
			
		||||
        // client, as the client that grabbed the pointer expects to have
 | 
			
		||||
        // complete control over it
 | 
			
		||||
        if (event.grabbed && Main.modalCount == 0)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _monitorsChanged: function() {
 | 
			
		||||
        this._updateMonitors();
 | 
			
		||||
        this._updateBoxes();
 | 
			
		||||
        this._updateTrayBarrier();
 | 
			
		||||
        this._updateHotCorners();
 | 
			
		||||
        this._updateBackgrounds();
 | 
			
		||||
        this._updateFullscreen();
 | 
			
		||||
@@ -1096,10 +1048,10 @@ const HotCorner = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._setupFallbackCornerIfNeeded(layoutManager);
 | 
			
		||||
 | 
			
		||||
        this._pressureBarrier = new PressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
 | 
			
		||||
                                                    HOT_CORNER_PRESSURE_TIMEOUT,
 | 
			
		||||
                                                    Shell.KeyBindingMode.NORMAL |
 | 
			
		||||
                                                    Shell.KeyBindingMode.OVERVIEW);
 | 
			
		||||
        this._pressureBarrier = new TriggerablePressureBarrier(HOT_CORNER_PRESSURE_THRESHOLD,
 | 
			
		||||
                                                               HOT_CORNER_PRESSURE_TIMEOUT,
 | 
			
		||||
                                                               Shell.KeyBindingMode.NORMAL |
 | 
			
		||||
                                                               Shell.KeyBindingMode.OVERVIEW);
 | 
			
		||||
        this._pressureBarrier.connect('trigger', Lang.bind(this, this._toggleOverview));
 | 
			
		||||
 | 
			
		||||
        // Cache the three ripples instead of dynamically creating and destroying them.
 | 
			
		||||
@@ -1277,14 +1229,12 @@ const PressureBarrier = new Lang.Class({
 | 
			
		||||
    Name: 'PressureBarrier',
 | 
			
		||||
 | 
			
		||||
    _init: function(threshold, timeout, keybindingMode) {
 | 
			
		||||
        this._threshold = threshold;
 | 
			
		||||
        this._timeout = timeout;
 | 
			
		||||
        this.threshold = threshold;
 | 
			
		||||
        this.timeout = timeout;
 | 
			
		||||
        this._keybindingMode = keybindingMode;
 | 
			
		||||
        this._barriers = [];
 | 
			
		||||
        this._eventFilter = null;
 | 
			
		||||
 | 
			
		||||
        this._isTriggered = false;
 | 
			
		||||
        this._reset();
 | 
			
		||||
        this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    addBarrier: function(barrier) {
 | 
			
		||||
@@ -1313,10 +1263,10 @@ const PressureBarrier = new Lang.Class({
 | 
			
		||||
        this._eventFilter = filter;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _reset: function() {
 | 
			
		||||
    reset: function() {
 | 
			
		||||
        this._barrierEvents = [];
 | 
			
		||||
        this._currentPressure = 0;
 | 
			
		||||
        this._lastTime = 0;
 | 
			
		||||
        this.currentPressure = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _isHorizontal: function(barrier) {
 | 
			
		||||
@@ -1337,12 +1287,21 @@ const PressureBarrier = new Lang.Class({
 | 
			
		||||
            return Math.abs(event.dy);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get currentPressure() {
 | 
			
		||||
        return this._currentPressure;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    set currentPressure(value) {
 | 
			
		||||
        this._currentPressure = value;
 | 
			
		||||
        this.emit('pressure-changed');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trimBarrierEvents: function() {
 | 
			
		||||
        // Events are guaranteed to be sorted in time order from
 | 
			
		||||
        // oldest to newest, so just look for the first old event,
 | 
			
		||||
        // and then chop events after that off.
 | 
			
		||||
        let i = 0;
 | 
			
		||||
        let threshold = this._lastTime - this._timeout;
 | 
			
		||||
        let threshold = this._lastTime - this.timeout;
 | 
			
		||||
 | 
			
		||||
        while (i < this._barrierEvents.length) {
 | 
			
		||||
            let [time, distance] = this._barrierEvents[i];
 | 
			
		||||
@@ -1355,21 +1314,75 @@ const PressureBarrier = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < firstNewEvent; i++) {
 | 
			
		||||
            let [time, distance] = this._barrierEvents[i];
 | 
			
		||||
            this._currentPressure -= distance;
 | 
			
		||||
            this.currentPressure = distance;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._barrierEvents = this._barrierEvents.slice(firstNewEvent);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierLeft: function(barrier, event) {
 | 
			
		||||
        this._reset();
 | 
			
		||||
        this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _shouldUseEvent: function(barrier, event) {
 | 
			
		||||
        if (this._eventFilter && this._eventFilter(event))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Throw out all events not in the proper keybinding mode
 | 
			
		||||
        if (!(this._keybindingMode & Main.keybindingMode))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let slide = this._getDistanceAlongBarrier(barrier, event);
 | 
			
		||||
        let distance = this._getDistanceAcrossBarrier(barrier, event);
 | 
			
		||||
 | 
			
		||||
        // Throw out events where the cursor is move more
 | 
			
		||||
        // along the axis of the barrier than moving with
 | 
			
		||||
        // the barrier.
 | 
			
		||||
        if (slide > distance)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _appendEvent: function(barrier, event) {
 | 
			
		||||
        let distance = this._getDistanceAcrossBarrier(barrier, event);
 | 
			
		||||
 | 
			
		||||
        this._lastTime = event.time;
 | 
			
		||||
 | 
			
		||||
        this._trimBarrierEvents();
 | 
			
		||||
        distance = Math.min(15, distance);
 | 
			
		||||
 | 
			
		||||
        this._barrierEvents.push([event.time, distance]);
 | 
			
		||||
        this.currentPressure += distance;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierHit: function(barrier, event) {
 | 
			
		||||
        if (!this._shouldUseEvent(barrier, event))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._appendEvent(barrier, event);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(PressureBarrier.prototype);
 | 
			
		||||
 | 
			
		||||
const TriggerablePressureBarrier = new Lang.Class({
 | 
			
		||||
    Name: 'TriggerablePressureBarrier',
 | 
			
		||||
    Extends: PressureBarrier,
 | 
			
		||||
 | 
			
		||||
    _init: function(threshold, timeout, keybindingMode) {
 | 
			
		||||
        this.parent(threshold, timeout, keybindingMode);
 | 
			
		||||
        this._isTriggered = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _trigger: function() {
 | 
			
		||||
        this._isTriggered = true;
 | 
			
		||||
        this.emit('trigger');
 | 
			
		||||
        this._reset();
 | 
			
		||||
        this.reset();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierLeft: function() {
 | 
			
		||||
        this.parent();
 | 
			
		||||
        this._isTriggered = false;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onBarrierHit: function(barrier, event) {
 | 
			
		||||
@@ -1378,37 +1391,17 @@ const PressureBarrier = new Lang.Class({
 | 
			
		||||
        if (this._isTriggered)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._eventFilter && this._eventFilter(event))
 | 
			
		||||
        if (!this._shouldUseEvent(barrier, event))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Throw out all events not in the proper keybinding mode
 | 
			
		||||
        if (!(this._keybindingMode & Main.keybindingMode))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let slide = this._getDistanceAlongBarrier(barrier, event);
 | 
			
		||||
        let distance = this._getDistanceAcrossBarrier(barrier, event);
 | 
			
		||||
 | 
			
		||||
        if (distance >= this._threshold) {
 | 
			
		||||
        if (distance >= this.threshold) {
 | 
			
		||||
            this._trigger();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Throw out events where the cursor is move more
 | 
			
		||||
        // along the axis of the barrier than moving with
 | 
			
		||||
        // the barrier.
 | 
			
		||||
        if (slide > distance)
 | 
			
		||||
            return;
 | 
			
		||||
        this._appendEvent(barrier, event);
 | 
			
		||||
 | 
			
		||||
        this._lastTime = event.time;
 | 
			
		||||
 | 
			
		||||
        this._trimBarrierEvents();
 | 
			
		||||
        distance = Math.min(15, distance);
 | 
			
		||||
 | 
			
		||||
        this._barrierEvents.push([event.time, distance]);
 | 
			
		||||
        this._currentPressure += distance;
 | 
			
		||||
 | 
			
		||||
        if (this._currentPressure >= this._threshold)
 | 
			
		||||
        if (this.currentPressure >= this.threshold)
 | 
			
		||||
            this._trigger();
 | 
			
		||||
    }
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(PressureBarrier.prototype);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1398
									
								
								js/ui/messageTray.js
									
									
									
									
									
								
							
							
						
						
									
										1398
									
								
								js/ui/messageTray.js
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -105,16 +105,10 @@ const FdoNotificationDaemon = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._nextNotificationId = 1;
 | 
			
		||||
 | 
			
		||||
        this._trayManager = new Shell.TrayManager();
 | 
			
		||||
        this._trayIconAddedId = this._trayManager.connect('tray-icon-added', Lang.bind(this, this._onTrayIconAdded));
 | 
			
		||||
        this._trayIconRemovedId = this._trayManager.connect('tray-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
 | 
			
		||||
 | 
			
		||||
        Shell.WindowTracker.get_default().connect('notify::focus-app',
 | 
			
		||||
            Lang.bind(this, this._onFocusAppChanged));
 | 
			
		||||
        Main.overview.connect('hidden',
 | 
			
		||||
            Lang.bind(this, this._onFocusAppChanged));
 | 
			
		||||
 | 
			
		||||
        this._trayManager.manage_screen(global.screen, Main.messageTray.actor);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _imageForNotificationData: function(hints) {
 | 
			
		||||
@@ -155,28 +149,23 @@ const FdoNotificationDaemon = new Lang.Class({
 | 
			
		||||
        return null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lookupSource: function(title, pid, trayIcon) {
 | 
			
		||||
    _lookupSource: function(title, pid) {
 | 
			
		||||
        for (let i = 0; i < this._sources.length; i++) {
 | 
			
		||||
            let source = this._sources[i];
 | 
			
		||||
            if (source.pid == pid &&
 | 
			
		||||
                (source.initialTitle == title || source.trayIcon || trayIcon))
 | 
			
		||||
            if (source.pid == pid && source.initialTitle == title)
 | 
			
		||||
                return source;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Returns the source associated with ndata.notification if it is set.
 | 
			
		||||
    // If the existing or requested source is associated with a tray icon
 | 
			
		||||
    // and passed in pid matches a pid of an existing source, the title
 | 
			
		||||
    // match is ignored to enable representing a tray icon and notifications
 | 
			
		||||
    // from the same application with a single source.
 | 
			
		||||
    //
 | 
			
		||||
    // If no existing source is found, a new source is created as long as
 | 
			
		||||
    // pid is provided.
 | 
			
		||||
    //
 | 
			
		||||
    // Either a pid or ndata.notification is needed to retrieve or
 | 
			
		||||
    // create a source.
 | 
			
		||||
    _getSource: function(title, pid, ndata, sender, trayIcon) {
 | 
			
		||||
    _getSource: function(title, pid, ndata, sender) {
 | 
			
		||||
        if (!pid && !(ndata && ndata.notification))
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
@@ -187,13 +176,13 @@ const FdoNotificationDaemon = new Lang.Class({
 | 
			
		||||
        if (ndata && ndata.notification)
 | 
			
		||||
            return ndata.notification.source;
 | 
			
		||||
 | 
			
		||||
        let source = this._lookupSource(title, pid, trayIcon);
 | 
			
		||||
        let source = this._lookupSource(title, pid);
 | 
			
		||||
        if (source) {
 | 
			
		||||
            source.setTitle(title);
 | 
			
		||||
            return source;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let source = new FdoNotificationDaemonSource(title, pid, sender, trayIcon, ndata ? ndata.hints['desktop-entry'] : null);
 | 
			
		||||
        let source = new FdoNotificationDaemonSource(title, pid, sender, ndata ? ndata.hints['desktop-entry'] : null);
 | 
			
		||||
 | 
			
		||||
        this._sources.push(source);
 | 
			
		||||
        source.connect('destroy', Lang.bind(this, function() {
 | 
			
		||||
@@ -485,26 +474,15 @@ const FdoNotificationDaemon = new Lang.Class({
 | 
			
		||||
        this._dbusImpl.emit_signal('ActionInvoked',
 | 
			
		||||
                                   GLib.Variant.new('(us)', [id, action]));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onTrayIconAdded: function(o, icon) {
 | 
			
		||||
        let source = this._getSource(icon.title || icon.wm_class || C_("program", "Unknown"), icon.pid, null, null, icon);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onTrayIconRemoved: function(o, icon) {
 | 
			
		||||
        let source = this._lookupSource(null, icon.pid, true);
 | 
			
		||||
        if (source)
 | 
			
		||||
            source.destroy();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
    Name: 'FdoNotificationDaemonSource',
 | 
			
		||||
    Extends: MessageTray.Source,
 | 
			
		||||
 | 
			
		||||
    _init: function(title, pid, sender, trayIcon, appId) {
 | 
			
		||||
    _init: function(title, pid, sender, appId) {
 | 
			
		||||
        // Need to set the app before chaining up, so
 | 
			
		||||
        // methods called from the parent constructor can find it
 | 
			
		||||
        this.trayIcon = trayIcon;
 | 
			
		||||
        this.pid = pid;
 | 
			
		||||
        this.app = this._getApp(appId);
 | 
			
		||||
 | 
			
		||||
@@ -524,12 +502,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
                                                              Lang.bind(this, this._onNameVanished));
 | 
			
		||||
        else
 | 
			
		||||
            this._nameWatcherId = 0;
 | 
			
		||||
 | 
			
		||||
        if (this.trayIcon) {
 | 
			
		||||
            // Try again finding the app, using the WM_CLASS from the tray icon
 | 
			
		||||
            this._setSummaryIcon(this.trayIcon);
 | 
			
		||||
            this.useNotificationIcon = false;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _createPolicy: function() {
 | 
			
		||||
@@ -545,17 +517,15 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
        // Destroy the notification source when its sender is removed from DBus.
 | 
			
		||||
        // Only do so if this.app is set to avoid removing "notify-send" sources, senders
 | 
			
		||||
        // of which аre removed from DBus immediately.
 | 
			
		||||
        // Sender being removed from DBus would normally result in a tray icon being removed,
 | 
			
		||||
        // so allow the code path that handles the tray icon being removed to handle that case.
 | 
			
		||||
        if (!this.trayIcon && this.app)
 | 
			
		||||
        if (this.app)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    processNotification: function(notification, gicon) {
 | 
			
		||||
        if (gicon)
 | 
			
		||||
            this._gicon = gicon;
 | 
			
		||||
        if (!this.trayIcon)
 | 
			
		||||
            this.iconUpdated();
 | 
			
		||||
 | 
			
		||||
        this.iconUpdated();
 | 
			
		||||
 | 
			
		||||
        let tracker = Shell.WindowTracker.get_default();
 | 
			
		||||
        if (this.app && tracker.focus_app == this.app)
 | 
			
		||||
@@ -564,29 +534,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
            this.notify(notification);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    handleSummaryClick: function(button) {
 | 
			
		||||
        if (!this.trayIcon)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let event = Clutter.get_current_event();
 | 
			
		||||
 | 
			
		||||
        // Left clicks are passed through only where there aren't unacknowledged
 | 
			
		||||
        // notifications, so it possible to open them in summary mode; right
 | 
			
		||||
        // clicks are always forwarded, as the right click menu is not useful for
 | 
			
		||||
        // tray icons
 | 
			
		||||
        if (button == 1 &&
 | 
			
		||||
            this.notifications.length > 0)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        let id = global.stage.connect('deactivate', Lang.bind(this, function () {
 | 
			
		||||
            global.stage.disconnect(id);
 | 
			
		||||
            this.trayIcon.click(event);
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        return true;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _getApp: function(appId) {
 | 
			
		||||
        let app;
 | 
			
		||||
 | 
			
		||||
@@ -594,16 +541,6 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
        if (app != null)
 | 
			
		||||
            return app;
 | 
			
		||||
 | 
			
		||||
        if (this.trayIcon) {
 | 
			
		||||
            app = Shell.AppSystem.get_default().lookup_startup_wmclass(this.trayIcon.wm_class);
 | 
			
		||||
            if (app != null)
 | 
			
		||||
                return app;
 | 
			
		||||
 | 
			
		||||
            app = Shell.AppSystem.get_default().lookup_desktop_wmclass(this.trayIcon.wm_class);
 | 
			
		||||
            if (app != null)
 | 
			
		||||
                return app;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (appId) {
 | 
			
		||||
            app = Shell.AppSystem.get_default().lookup_app(appId + '.desktop');
 | 
			
		||||
            if (app != null)
 | 
			
		||||
@@ -629,8 +566,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lastNotificationRemoved: function() {
 | 
			
		||||
        if (!this.trayIcon)
 | 
			
		||||
            this.destroy();
 | 
			
		||||
        this.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    openApp: function() {
 | 
			
		||||
@@ -651,11 +587,7 @@ const FdoNotificationDaemonSource = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createIcon: function(size) {
 | 
			
		||||
        if (this.trayIcon) {
 | 
			
		||||
            return new Clutter.Clone({ width: size,
 | 
			
		||||
                                       height: size,
 | 
			
		||||
                                       source: this.trayIcon });
 | 
			
		||||
        } else if (this.app) {
 | 
			
		||||
        if (this.app) {
 | 
			
		||||
            return this.app.create_icon_texture(size);
 | 
			
		||||
        } else if (this._gicon) {
 | 
			
		||||
            return new St.Icon({ gicon: this._gicon,
 | 
			
		||||
 
 | 
			
		||||
@@ -263,8 +263,6 @@ const Overview = new Lang.Class({
 | 
			
		||||
        this._overview.add(this._controls.actor, { y_fill: true, expand: true });
 | 
			
		||||
        this._controls.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
 | 
			
		||||
 | 
			
		||||
        this._stack.add_actor(this._controls.indicatorActor);
 | 
			
		||||
 | 
			
		||||
        // TODO - recalculate everything when desktop size changes
 | 
			
		||||
        this.dashIconSize = this._dash.iconSize;
 | 
			
		||||
        this._dash.connect('icon-size-changed',
 | 
			
		||||
 
 | 
			
		||||
@@ -396,111 +396,6 @@ const DashSpacer = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const MessagesIndicator = new Lang.Class({
 | 
			
		||||
    Name: 'MessagesIndicator',
 | 
			
		||||
 | 
			
		||||
    _init: function(viewSelector) {
 | 
			
		||||
        this._count = 0;
 | 
			
		||||
        this._sources = [];
 | 
			
		||||
        this._viewSelector = viewSelector;
 | 
			
		||||
 | 
			
		||||
        this._container = new St.BoxLayout({ style_class: 'messages-indicator-contents',
 | 
			
		||||
                                             reactive: true,
 | 
			
		||||
                                             track_hover: true,
 | 
			
		||||
                                             x_expand: true,
 | 
			
		||||
                                             y_expand: true,
 | 
			
		||||
                                             x_align: Clutter.ActorAlign.CENTER });
 | 
			
		||||
 | 
			
		||||
        this._icon = new St.Icon({ icon_name: 'user-idle-symbolic',
 | 
			
		||||
                                   icon_size: 16 });
 | 
			
		||||
        this._container.add_actor(this._icon);
 | 
			
		||||
 | 
			
		||||
        this._label = new St.Label();
 | 
			
		||||
        this._container.add_actor(this._label);
 | 
			
		||||
 | 
			
		||||
        this._highlight = new St.Widget({ style_class: 'messages-indicator-highlight',
 | 
			
		||||
                                          x_expand: true,
 | 
			
		||||
                                          y_expand: true,
 | 
			
		||||
                                          y_align: Clutter.ActorAlign.END,
 | 
			
		||||
                                          visible: false });
 | 
			
		||||
 | 
			
		||||
        this._container.connect('notify::hover', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._highlight.visible = this._container.hover;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let clickAction = new Clutter.ClickAction();
 | 
			
		||||
        this._container.add_action(clickAction);
 | 
			
		||||
        clickAction.connect('clicked', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                Main.messageTray.openTray();
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.connect('showing', Lang.bind(this,
 | 
			
		||||
            function() {
 | 
			
		||||
                this._highlight.visible = false;
 | 
			
		||||
                this._container.hover = false;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        let layout = new Clutter.BinLayout();
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: layout,
 | 
			
		||||
                                     style_class: 'messages-indicator',
 | 
			
		||||
                                     y_expand: true,
 | 
			
		||||
                                     y_align: Clutter.ActorAlign.END,
 | 
			
		||||
                                     visible: false });
 | 
			
		||||
        this.actor.add_actor(this._container);
 | 
			
		||||
        this.actor.add_actor(this._highlight);
 | 
			
		||||
 | 
			
		||||
        Main.messageTray.connect('source-added', Lang.bind(this, this._onSourceAdded));
 | 
			
		||||
        Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved));
 | 
			
		||||
 | 
			
		||||
        let sources = Main.messageTray.getSources();
 | 
			
		||||
        sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); }));
 | 
			
		||||
 | 
			
		||||
        this._viewSelector.connect('page-changed', Lang.bind(this, this._updateVisibility));
 | 
			
		||||
        Main.overview.connect('showing', Lang.bind(this, this._updateVisibility));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceAdded: function(tray, source) {
 | 
			
		||||
        if (source.trayIcon)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        source.connect('count-updated', Lang.bind(this, this._updateCount));
 | 
			
		||||
        this._sources.push(source);
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSourceRemoved: function(tray, source) {
 | 
			
		||||
        this._sources.splice(this._sources.indexOf(source), 1);
 | 
			
		||||
        this._updateCount();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateCount: function() {
 | 
			
		||||
        let count = 0;
 | 
			
		||||
        let hasChats = false;
 | 
			
		||||
        this._sources.forEach(Lang.bind(this,
 | 
			
		||||
            function(source) {
 | 
			
		||||
                count += source.indicatorCount;
 | 
			
		||||
                hasChats |= source.isChat;
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
        this._count = count;
 | 
			
		||||
        this._label.text = ngettext("%d new message",
 | 
			
		||||
                                    "%d new messages",
 | 
			
		||||
                                   count).format(count);
 | 
			
		||||
 | 
			
		||||
        this._icon.visible = hasChats;
 | 
			
		||||
        this._updateVisibility();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateVisibility: function() {
 | 
			
		||||
        let activePage = this._viewSelector.getActivePage();
 | 
			
		||||
        let visible = ((this._count > 0) && (activePage == ViewSelector.ViewPage.WINDOWS));
 | 
			
		||||
 | 
			
		||||
        this.actor.visible = visible;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const ControlsLayout = new Lang.Class({
 | 
			
		||||
    Name: 'ControlsLayout',
 | 
			
		||||
    Extends: Clutter.BinLayout,
 | 
			
		||||
@@ -529,9 +424,6 @@ const ControlsManager = new Lang.Class({
 | 
			
		||||
        this.viewSelector.connect('page-changed', Lang.bind(this, this._setVisibility));
 | 
			
		||||
        this.viewSelector.connect('page-empty', Lang.bind(this, this._onPageEmpty));
 | 
			
		||||
 | 
			
		||||
        this._indicator = new MessagesIndicator(this.viewSelector);
 | 
			
		||||
        this.indicatorActor = this._indicator.actor;
 | 
			
		||||
 | 
			
		||||
        let layout = new ControlsLayout();
 | 
			
		||||
        this.actor = new St.Widget({ layout_manager: layout,
 | 
			
		||||
                                     reactive: true,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user