Compare commits
	
		
			35 Commits
		
	
	
		
			wip/fmuell
			...
			wip/textur
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0507fef4cd | ||
| 
						 | 
					68c631223c | ||
| 
						 | 
					97b38c1950 | ||
| 
						 | 
					b098930e6d | ||
| 
						 | 
					45da60516c | ||
| 
						 | 
					c4b1ba48f2 | ||
| 
						 | 
					6ed21e1ce0 | ||
| 
						 | 
					9c51c87d8c | ||
| 
						 | 
					db2245d60b | ||
| 
						 | 
					f26cc3ac23 | ||
| 
						 | 
					02c5b4b947 | ||
| 
						 | 
					df57829ea1 | ||
| 
						 | 
					da96408098 | ||
| 
						 | 
					4b2e0247af | ||
| 
						 | 
					2c617e5a3a | ||
| 
						 | 
					4ff7e84c51 | ||
| 
						 | 
					9f76b6e4a2 | ||
| 
						 | 
					0ac0f7e85b | ||
| 
						 | 
					73b00ff1a7 | ||
| 
						 | 
					a52597ac5b | ||
| 
						 | 
					9a2597f80b | ||
| 
						 | 
					e1ed4b25e1 | ||
| 
						 | 
					c70b18764b | ||
| 
						 | 
					4398516520 | ||
| 
						 | 
					220514d10e | ||
| 
						 | 
					18312d9ccd | ||
| 
						 | 
					234b1441e4 | ||
| 
						 | 
					e909db5848 | ||
| 
						 | 
					702338bc7d | ||
| 
						 | 
					7c9dbc66d9 | ||
| 
						 | 
					0d031dc20f | ||
| 
						 | 
					b476e851b7 | ||
| 
						 | 
					a27be6a540 | ||
| 
						 | 
					4b6a57fabe | ||
| 
						 | 
					92758890bb | 
							
								
								
									
										28
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,31 @@
 | 
			
		||||
3.28.3
 | 
			
		||||
======
 | 
			
		||||
* Fix lagging pointer when zoomed [Daniel; #682013]
 | 
			
		||||
* Fix "Clear All" for calendar events [Florian; #325]
 | 
			
		||||
* Misc. bug fixes [Florian, Mario, Marco; #136, #214, #788931, #791233]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Carlos Garnacho, Florian Müllner, Mario Sanchez Prada, Joe Rabinoff,
 | 
			
		||||
  Didier Roche, Marco Trevisan (Treviño), Daniel van Vugt
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Pieter Schalk Schoeman [af], Gun Chleoc [gd]
 | 
			
		||||
 | 
			
		||||
3.28.2
 | 
			
		||||
======
 | 
			
		||||
* Fix lock-up on cancelling polkit dialog [Florian; #221]
 | 
			
		||||
* Guard against untimely keyboard map changes [Carlos; #240]
 | 
			
		||||
* Fix blurriness of OSD under some resolutions [Silvère; #782011]
 | 
			
		||||
* Fix icons in search provider results [Florian; #249]
 | 
			
		||||
* Misc. bug fixes [Marco, Florian; #792687, #781471]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Carlos Garnacho, Silvère Latchurié, Florian Müllner, Mario Sanchez Prada,
 | 
			
		||||
  Ray Strode, Marco Trevisan (Treviño)
 | 
			
		||||
 | 
			
		||||
Translators:
 | 
			
		||||
  Stas Solovey [ru], Rafael Fontenelle [pt_BR]
 | 
			
		||||
 | 
			
		||||
3.28.1
 | 
			
		||||
======
 | 
			
		||||
* Fix compose characters in shell entries [Carlos; #115]
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,11 @@ var IBusManager = new Lang.Class({
 | 
			
		||||
                                                         object_path: IBus.PATH_PANEL });
 | 
			
		||||
            this._candidatePopup.setPanelService(this._panelService);
 | 
			
		||||
            this._panelService.connect('update-property', this._updateProperty.bind(this));
 | 
			
		||||
            this._panelService.connect('set-cursor-location', (ps, x, y, w, h) => {
 | 
			
		||||
                let cursorLocation = { x, y, width: w, height: h };
 | 
			
		||||
                this.emit('set-cursor-location', cursorLocation);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                // IBus versions older than 1.5.10 have a bug which
 | 
			
		||||
                // causes spurious set-content-type emissions when
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,8 @@ 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 = {};
 | 
			
		||||
 | 
			
		||||
@@ -115,6 +117,9 @@ var KeyboardManager = new Lang.Class({
 | 
			
		||||
            info.group = group;
 | 
			
		||||
            info.groupIndex = groupIndex;
 | 
			
		||||
 | 
			
		||||
            if (currentId == id && currentGroupIndex == groupIndex)
 | 
			
		||||
                this._current = info;
 | 
			
		||||
 | 
			
		||||
            i += 1;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,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',
 | 
			
		||||
 
 | 
			
		||||
@@ -264,7 +264,7 @@ var Background = new Lang.Class({
 | 
			
		||||
            (lm, aboutToSuspend) => {
 | 
			
		||||
                if (aboutToSuspend)
 | 
			
		||||
                    return;
 | 
			
		||||
                this._refreshAnimation();
 | 
			
		||||
                this.emit('changed');
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        this._settingsChangedSignalId = this._settings.connect('changed', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -821,6 +821,8 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
        this._desktopSettings.connect('changed', this._reloadEvents.bind(this));
 | 
			
		||||
        this._eventSource = new EmptyEventSource();
 | 
			
		||||
 | 
			
		||||
        this._messageById = new Map();
 | 
			
		||||
 | 
			
		||||
        this.parent();
 | 
			
		||||
 | 
			
		||||
        this._title = new St.Button({ style_class: 'events-section-title',
 | 
			
		||||
@@ -875,20 +877,32 @@ var EventsSection = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._reloading = true;
 | 
			
		||||
 | 
			
		||||
        this._list.destroy_all_children();
 | 
			
		||||
 | 
			
		||||
        let periodBegin = _getBeginningOfDay(this._date);
 | 
			
		||||
        let periodEnd = _getEndOfDay(this._date);
 | 
			
		||||
        let events = this._eventSource.getEvents(periodBegin, periodEnd);
 | 
			
		||||
 | 
			
		||||
        let ids = events.map(e => e.id);
 | 
			
		||||
        this._messageById.forEach((message, id) => {
 | 
			
		||||
            if (ids.includes(id))
 | 
			
		||||
                return;
 | 
			
		||||
            this._messageById.delete(id);
 | 
			
		||||
            this.removeMessage(message);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < events.length; i++) {
 | 
			
		||||
            let event = events[i];
 | 
			
		||||
 | 
			
		||||
            let message = new EventMessage(event, this._date);
 | 
			
		||||
            let message = this._messageById.get(event.id);
 | 
			
		||||
            if (!message) {
 | 
			
		||||
                message = new EventMessage(event, this._date);
 | 
			
		||||
                message.connect('close', () => {
 | 
			
		||||
                    this._ignoreEvent(event);
 | 
			
		||||
                });
 | 
			
		||||
                this._messageById.set(event.id, message);
 | 
			
		||||
                this.addMessage(message, false);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.moveMessage(message, i, false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._reloading = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -655,7 +655,7 @@ var NetworkAgent = new Lang.Class({
 | 
			
		||||
        switch (connectionType) {
 | 
			
		||||
        case '802-11-wireless':
 | 
			
		||||
            let wirelessSetting = connection.get_setting_wireless();
 | 
			
		||||
            let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid());
 | 
			
		||||
            let ssid = NM.utils_ssid_to_utf8(wirelessSetting.get_ssid().get_data());
 | 
			
		||||
            title = _("Authentication required by wireless network");
 | 
			
		||||
            body = _("Passwords or encryption keys are required to access the wireless network “%s”.").format(ssid);
 | 
			
		||||
            break;
 | 
			
		||||
 
 | 
			
		||||
@@ -201,7 +201,9 @@ var AuthenticationDialog = new Lang.Class({
 | 
			
		||||
    close(timestamp) {
 | 
			
		||||
        this.parent(timestamp);
 | 
			
		||||
 | 
			
		||||
        if (this._sessionUpdatedId)
 | 
			
		||||
            Main.sessionMode.disconnect(this._sessionUpdatedId);
 | 
			
		||||
        this._sessionUpdatedId = 0;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _ensureOpen() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 | 
			
		||||
 | 
			
		||||
const FocusCaretTracker = imports.ui.focusCaretTracker;
 | 
			
		||||
const Atspi = imports.gi.Atspi;
 | 
			
		||||
const Clutter = imports.gi.Clutter;
 | 
			
		||||
const Gdk = imports.gi.Gdk;
 | 
			
		||||
@@ -13,6 +12,7 @@ const Signals = imports.signals;
 | 
			
		||||
const St = imports.gi.St;
 | 
			
		||||
const InputSourceManager = imports.ui.status.keyboard;
 | 
			
		||||
 | 
			
		||||
const IBusManager = imports.misc.ibusManager;
 | 
			
		||||
const BoxPointer = imports.ui.boxpointer;
 | 
			
		||||
const Layout = imports.ui.layout;
 | 
			
		||||
const Main = imports.ui.main;
 | 
			
		||||
@@ -261,6 +261,7 @@ var Key = new Lang.Class({
 | 
			
		||||
        this._extended_keyboard = null;
 | 
			
		||||
        this._pressTimeoutId = 0;
 | 
			
		||||
        this._capturedPress = false;
 | 
			
		||||
 | 
			
		||||
        this._capturedEventId = 0;
 | 
			
		||||
        this._unmapId = 0;
 | 
			
		||||
        this._longPress = false;
 | 
			
		||||
@@ -484,6 +485,71 @@ var KeyboardModel = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var FocusTracker = new Lang.Class({
 | 
			
		||||
    Name: 'FocusTracker',
 | 
			
		||||
 | 
			
		||||
    _init() {
 | 
			
		||||
        this._currentWindow = null;
 | 
			
		||||
        this._currentWindowPositionId = 0;
 | 
			
		||||
 | 
			
		||||
        global.screen.get_display().connect('notify::focus-window', () => {
 | 
			
		||||
            this._setCurrentWindow(global.screen.get_display().focus_window);
 | 
			
		||||
            this.emit('window-changed', this._currentWindow);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        /* Valid for wayland clients */
 | 
			
		||||
        Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
 | 
			
		||||
            let newRect = { x: rect.get_x(), y: rect.get_y(), width: rect.get_width(), height: rect.get_height() };
 | 
			
		||||
            this._setCurrentRect(newRect);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this._ibusManager = IBusManager.getIBusManager();
 | 
			
		||||
        this._ibusManager.connect('set-cursor-location', (manager, rect) => {
 | 
			
		||||
            /* Valid for X11 clients only */
 | 
			
		||||
            if (Main.inputMethod.currentFocus)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            this._setCurrentRect(rect);
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get currentWindow() {
 | 
			
		||||
        return this._currentWindow;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setCurrentWindow(window) {
 | 
			
		||||
        if (this._currentWindow)
 | 
			
		||||
            this._currentWindow.disconnect(this._currentWindowPositionId);
 | 
			
		||||
 | 
			
		||||
        this._currentWindow = window;
 | 
			
		||||
        if (window) {
 | 
			
		||||
            this._currentWindowPositionId = this._currentWindow.connect('position-changed', () => {
 | 
			
		||||
                if (global.display.get_grab_op() == Meta.GrabOp.NONE)
 | 
			
		||||
                    this.emit('position-changed');
 | 
			
		||||
                else
 | 
			
		||||
                    this.emit('reset');
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setCurrentRect(rect) {
 | 
			
		||||
        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 };
 | 
			
		||||
 | 
			
		||||
        return rect;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(FocusTracker.prototype);
 | 
			
		||||
 | 
			
		||||
var Keyboard = new Lang.Class({
 | 
			
		||||
    Name: 'Keyboard',
 | 
			
		||||
 | 
			
		||||
@@ -491,15 +557,10 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        this.actor = null;
 | 
			
		||||
        this._focusInExtendedKeys = false;
 | 
			
		||||
 | 
			
		||||
        this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
 | 
			
		||||
        this._focusCaretTracker.connect('focus-changed', this._onFocusChanged.bind(this));
 | 
			
		||||
        this._focusCaretTracker.connect('caret-moved', this._onCaretMoved.bind(this));
 | 
			
		||||
        this._languagePopup = null;
 | 
			
		||||
        this._currentAccessible = null;
 | 
			
		||||
        this._caretTrackingEnabled = false;
 | 
			
		||||
        this._updateCaretPositionId = 0;
 | 
			
		||||
        this._currentFocusWindow = null;
 | 
			
		||||
        this._originalWindowY = null;
 | 
			
		||||
        this._animFocusedWindow = null;
 | 
			
		||||
        this._delayedAnimFocusWindow = null;
 | 
			
		||||
 | 
			
		||||
        this._enableKeyboard = false; // a11y settings value
 | 
			
		||||
        this._enabled = false; // enabled state (by setting or device type)
 | 
			
		||||
@@ -510,6 +571,14 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        this._lastDeviceId = null;
 | 
			
		||||
        this._suggestions = null;
 | 
			
		||||
 | 
			
		||||
        this._focusTracker = new FocusTracker();
 | 
			
		||||
        this._focusTracker.connect('position-changed', this._onFocusPositionChanged.bind(this));
 | 
			
		||||
        this._focusTracker.connect('reset', () => {
 | 
			
		||||
            this._delayedAnimFocusWindow = null;
 | 
			
		||||
            this._animFocusedWindow = null;
 | 
			
		||||
            this._oskFocusWindow = null;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Meta.get_backend().connect('last-device-changed', 
 | 
			
		||||
            (backend, deviceId) => {
 | 
			
		||||
                let manager = Clutter.DeviceManager.get_default();
 | 
			
		||||
@@ -532,102 +601,15 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        this._keyboardRestingId = 0;
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
 | 
			
		||||
        //Main.inputMethod.connect('cursor-location-changed', (o, rect) => {
 | 
			
		||||
        //    if (this._keyboardVisible) {
 | 
			
		||||
        //        let currentWindow = global.screen.get_display().focus_window;
 | 
			
		||||
        //        this.setCursorLocation(currentWindow, rect.get_x(), rect.get_y(),
 | 
			
		||||
        //                               rect.get_width(), rect.get_height());
 | 
			
		||||
        //    }
 | 
			
		||||
        //});
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get visible() {
 | 
			
		||||
        return this._keyboardVisible;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _setCaretTrackerEnabled(enabled) {
 | 
			
		||||
        if (this._caretTrackingEnabled == enabled)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._caretTrackingEnabled = enabled;
 | 
			
		||||
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            this._focusCaretTracker.registerFocusListener();
 | 
			
		||||
            this._focusCaretTracker.registerCaretListener();
 | 
			
		||||
        } else {
 | 
			
		||||
            this._focusCaretTracker.deregisterFocusListener();
 | 
			
		||||
            this._focusCaretTracker.deregisterCaretListener();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateCaretPosition(accessible) {
 | 
			
		||||
        if (this._updateCaretPositionId)
 | 
			
		||||
            GLib.source_remove(this._updateCaretPositionId);
 | 
			
		||||
        if (!this._keyboardRequested)
 | 
			
		||||
            return;
 | 
			
		||||
        this._updateCaretPositionId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
 | 
			
		||||
            this._updateCaretPositionId = 0;
 | 
			
		||||
 | 
			
		||||
            let currentWindow = global.screen.get_display().focus_window;
 | 
			
		||||
            if (!currentWindow) {
 | 
			
		||||
                this.setCursorLocation(null);
 | 
			
		||||
                return GLib.SOURCE_REMOVE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let windowRect = currentWindow.get_frame_rect();
 | 
			
		||||
            let text = accessible.get_text_iface();
 | 
			
		||||
            let component = accessible.get_component_iface();
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                let caretOffset = text.get_caret_offset();
 | 
			
		||||
                let caretRect = text.get_character_extents(caretOffset, Atspi.CoordType.WINDOW);
 | 
			
		||||
                let focusRect = component.get_extents(Atspi.CoordType.WINDOW);
 | 
			
		||||
 | 
			
		||||
                if (caretRect.width == 0 && caretRect.height == 0)
 | 
			
		||||
                    caretRect = focusRect;
 | 
			
		||||
 | 
			
		||||
                this.setCursorLocation(currentWindow, caretRect.x, caretRect.y, caretRect.width, caretRect.height);
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
                log('Error updating caret position for OSK: ' + e.message);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return GLib.SOURCE_REMOVE;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        GLib.Source.set_name_by_id(this._updateCaretPositionId, '[gnome-shell] this._updateCaretPosition');
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _focusIsTextEntry(accessible) {
 | 
			
		||||
        try {
 | 
			
		||||
            let role = accessible.get_role();
 | 
			
		||||
            let stateSet = accessible.get_state_set();
 | 
			
		||||
            return stateSet.contains(Atspi.StateType.EDITABLE) || role == Atspi.Role.TERMINAL;
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            log('Error determining accessible role: ' + e.message);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onFocusChanged(caretTracker, event) {
 | 
			
		||||
        let accessible = event.source;
 | 
			
		||||
        if (!this._focusIsTextEntry(accessible))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let focused = event.detail1 != 0;
 | 
			
		||||
        if (focused) {
 | 
			
		||||
            this._currentAccessible = accessible;
 | 
			
		||||
            this._updateCaretPosition(accessible);
 | 
			
		||||
            this.show(Main.layoutManager.focusIndex);
 | 
			
		||||
        } else if (this._currentAccessible == accessible) {
 | 
			
		||||
            this._currentAccessible = null;
 | 
			
		||||
            this.hide();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onCaretMoved(caretTracker, event) {
 | 
			
		||||
        let accessible = event.source;
 | 
			
		||||
        if (this._currentAccessible == accessible)
 | 
			
		||||
            this._updateCaretPosition(accessible);
 | 
			
		||||
    _onFocusPositionChanged(focusTracker) {
 | 
			
		||||
        let rect = focusTracker.getCurrentRect();
 | 
			
		||||
        this.setCursorLocation(focusTracker.currentWindow, rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _lastDeviceIsTouchscreen() {
 | 
			
		||||
@@ -650,8 +632,6 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        if (!this._enabled && !this._keyboardController)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        this._setCaretTrackerEnabled(this._enabled);
 | 
			
		||||
 | 
			
		||||
        if (this._enabled && !this._keyboardController)
 | 
			
		||||
            this._setupKeyboard();
 | 
			
		||||
        else if (!this._enabled)
 | 
			
		||||
@@ -1027,11 +1007,14 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        if (!this._keyboardRequested)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._currentAccessible)
 | 
			
		||||
            this._updateCaretPosition(this._currentAccessible);
 | 
			
		||||
        Main.layoutManager.keyboardIndex = monitor;
 | 
			
		||||
        this._relayout();
 | 
			
		||||
        Main.layoutManager.showKeyboard();
 | 
			
		||||
 | 
			
		||||
        if (this._delayedAnimFocusWindow) {
 | 
			
		||||
            this._setAnimationWindow(this._delayedAnimFocusWindow);
 | 
			
		||||
            this._delayedAnimFocusWindow = null;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    hide() {
 | 
			
		||||
@@ -1102,8 +1085,9 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        window.move_frame(true, frameRect.x, frameRect.y);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _animateWindow(window, show, deltaY) {
 | 
			
		||||
    _animateWindow(window, show) {
 | 
			
		||||
        let windowActor = window.get_compositor_private();
 | 
			
		||||
        let deltaY = Main.layoutManager.keyboardBox.height;
 | 
			
		||||
        if (!windowActor)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
@@ -1124,35 +1108,39 @@ var Keyboard = new Lang.Class({
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setCursorLocation(window, x, y , w, h) {
 | 
			
		||||
        if (window == this._oskFocusWindow)
 | 
			
		||||
    _setAnimationWindow(window) {
 | 
			
		||||
        if (this._animFocusedWindow == window)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (this._oskFocusWindow) {
 | 
			
		||||
            let display = global.screen.get_display();
 | 
			
		||||
        if (this._animFocusedWindow)
 | 
			
		||||
            this._animateWindow(this._animFocusedWindow, false);
 | 
			
		||||
        if (window)
 | 
			
		||||
            this._animateWindow(window, true);
 | 
			
		||||
 | 
			
		||||
            if (display.get_grab_op() == Meta.GrabOp.NONE ||
 | 
			
		||||
                display.get_focus_window() != this._oskFocusWindow)
 | 
			
		||||
                this._animateWindow(this._oskFocusWindow, false, this._oskFocusWindowDelta);
 | 
			
		||||
        this._animFocusedWindow = window;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
            this._oskFocusWindow = null;
 | 
			
		||||
            this._oskFocusWindowDelta = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (window) {
 | 
			
		||||
    setCursorLocation(window, x, y , w, h) {
 | 
			
		||||
        let monitor = Main.layoutManager.keyboardMonitor;
 | 
			
		||||
 | 
			
		||||
        if (window && monitor) {
 | 
			
		||||
            let keyboardHeight = Main.layoutManager.keyboardBox.height;
 | 
			
		||||
            let frameRect = window.get_frame_rect();
 | 
			
		||||
            let windowActor = window.get_compositor_private();
 | 
			
		||||
            let delta = 0;
 | 
			
		||||
            let focusObscured = false;
 | 
			
		||||
 | 
			
		||||
            if (frameRect.y + y + h >= monitor.height - keyboardHeight)
 | 
			
		||||
                delta = keyboardHeight;
 | 
			
		||||
 | 
			
		||||
            this._animateWindow(window, true, delta);
 | 
			
		||||
            this._oskFocusWindow = window;
 | 
			
		||||
            this._oskFocusWindowDelta = delta;
 | 
			
		||||
            if (y + h >= monitor.y + monitor.height - keyboardHeight) {
 | 
			
		||||
                if (this._keyboardVisible)
 | 
			
		||||
                    this._setAnimationWindow(window);
 | 
			
		||||
                else
 | 
			
		||||
                    this._delayedAnimFocusWindow = window;
 | 
			
		||||
            } else if (y < keyboardHeight) {
 | 
			
		||||
                this._delayedAnimFocusWindow = null;
 | 
			
		||||
                this._setAnimationWindow(null);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            this._setAnimationWindow(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this._oskFocusWindow = window;
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ const MagnifierDBus = imports.ui.magnifierDBus;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const PointerWatcher = imports.ui.pointerWatcher;
 | 
			
		||||
 | 
			
		||||
var MOUSE_POLL_FREQUENCY = 50;
 | 
			
		||||
var CROSSHAIRS_CLIP_SIZE = [100, 100];
 | 
			
		||||
var NO_CHANGE = 0.0;
 | 
			
		||||
 | 
			
		||||
@@ -152,8 +151,10 @@ var Magnifier = new Lang.Class({
 | 
			
		||||
     * Turn on mouse tracking, if not already doing so.
 | 
			
		||||
     */
 | 
			
		||||
    startTrackingMouse() {
 | 
			
		||||
        if (!this._pointerWatch)
 | 
			
		||||
            this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(MOUSE_POLL_FREQUENCY, this.scrollToMousePos.bind(this));
 | 
			
		||||
        if (!this._pointerWatch) {
 | 
			
		||||
            let interval = 1000 / Clutter.get_default_frame_rate();
 | 
			
		||||
            this._pointerWatch = PointerWatcher.getPointerWatcher().addWatch(interval, this.scrollToMousePos.bind(this));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -207,7 +207,13 @@ function _initializeUI() {
 | 
			
		||||
        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.
 | 
			
		||||
@@ -256,6 +262,14 @@ function _getStylesheet(name) {
 | 
			
		||||
    if (stylesheet.query_exists(null))
 | 
			
		||||
        return stylesheet;
 | 
			
		||||
 | 
			
		||||
    let dataDirs = GLib.get_system_data_dirs();
 | 
			
		||||
    for (let i = 0; i < dataDirs.length; i++) {
 | 
			
		||||
        let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'theme', name]);
 | 
			
		||||
        let stylesheet = Gio.file_new_for_path(path);
 | 
			
		||||
        if (stylesheet.query_exists(null))
 | 
			
		||||
            return stylesheet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stylesheet = Gio.File.new_for_path(global.datadir + '/theme/' + name);
 | 
			
		||||
    if (stylesheet.query_exists(null))
 | 
			
		||||
        return stylesheet;
 | 
			
		||||
 
 | 
			
		||||
@@ -204,7 +204,7 @@ var OsdWindow = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
 | 
			
		||||
        this._icon.icon_size = popupSize / (2 * scaleFactor);
 | 
			
		||||
        this._box.translation_y = monitor.height / 4;
 | 
			
		||||
        this._box.translation_y = Math.round(monitor.height / 4);
 | 
			
		||||
        this._boxConstraint.minSize = popupSize;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -394,8 +394,9 @@ var PopupImageMenuItem = new Lang.Class({
 | 
			
		||||
    _init(text, icon, params) {
 | 
			
		||||
        this.parent(params);
 | 
			
		||||
 | 
			
		||||
        this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
 | 
			
		||||
        this.actor.add_child(this._icon, { align: St.Align.END });
 | 
			
		||||
        this._icon = new St.Icon({ style_class: 'popup-menu-icon',
 | 
			
		||||
                                   x_align: Clutter.ActorAlign.END });
 | 
			
		||||
        this.actor.add_child(this._icon);
 | 
			
		||||
        this.label = new St.Label({ text: text });
 | 
			
		||||
        this.actor.add_child(this.label);
 | 
			
		||||
        this.actor.label_actor = this.label;
 | 
			
		||||
 
 | 
			
		||||
@@ -295,7 +295,7 @@ var RemoteSearchProvider = new Lang.Class({
 | 
			
		||||
                               name: metas[i]['name'],
 | 
			
		||||
                               description: metas[i]['description'],
 | 
			
		||||
                               createIcon: size => {
 | 
			
		||||
                                   this.createIcon(size, metas[i]);
 | 
			
		||||
                                   return this.createIcon(size, metas[i]);
 | 
			
		||||
                               },
 | 
			
		||||
                               clipboardText: metas[i]['clipboardText'] });
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -1944,6 +1944,7 @@ var NMApplet = new Lang.Class({
 | 
			
		||||
        this.indicators.visible = this._client.nm_running;
 | 
			
		||||
        this.menu.actor.visible = this._client.networking_enabled;
 | 
			
		||||
 | 
			
		||||
        this._updateIcon();
 | 
			
		||||
        this._syncConnectivity();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								js/ui/status/remoteAccess.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								js/ui/status/remoteAccess.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
// -*- 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._indicator.add_style_class_name('remote-access-indicator');
 | 
			
		||||
        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();
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
@@ -24,7 +24,7 @@ const EdgeDragAction = imports.ui.edgeDragAction;
 | 
			
		||||
const CloseDialog = imports.ui.closeDialog;
 | 
			
		||||
const SwitchMonitor = imports.ui.switchMonitor;
 | 
			
		||||
 | 
			
		||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
 | 
			
		||||
var SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
 | 
			
		||||
var MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
 | 
			
		||||
var SHOW_WINDOW_ANIMATION_TIME = 0.15;
 | 
			
		||||
var DIALOG_SHOW_WINDOW_ANIMATION_TIME = 0.1;
 | 
			
		||||
 
 | 
			
		||||
@@ -1431,17 +1431,9 @@ var Workspace = new Lang.Class({
 | 
			
		||||
    _doRemoveWindow(metaWin) {
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
        let index = this._lookupIndex (metaWin);
 | 
			
		||||
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._windows[index];
 | 
			
		||||
 | 
			
		||||
        this._windows.splice(index, 1);
 | 
			
		||||
        this._windowOverlays.splice(index, 1);
 | 
			
		||||
        let clone = this._removeWindowClone(metaWin);
 | 
			
		||||
 | 
			
		||||
        if (clone) {
 | 
			
		||||
            // If metaWin.get_compositor_private() returned non-NULL, that
 | 
			
		||||
            // means the window still exists (and is just being moved to
 | 
			
		||||
            // another workspace or something), so set its overviewHint
 | 
			
		||||
@@ -1458,7 +1450,7 @@ var Workspace = new Lang.Class({
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
            clone.destroy();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // We need to reposition the windows; to avoid shuffling windows
 | 
			
		||||
        // around while the user is interacting with the workspace, we delay
 | 
			
		||||
@@ -1848,6 +1840,9 @@ var Workspace = new Lang.Class({
 | 
			
		||||
        clone.connect('size-changed', () => {
 | 
			
		||||
            this._recalculateWindowPositions(WindowPositionFlags.NONE);
 | 
			
		||||
        });
 | 
			
		||||
        clone.actor.connect('destroy', () => {
 | 
			
		||||
            this._removeWindowClone(clone.metaWindow);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        this.actor.add_actor(clone.actor);
 | 
			
		||||
 | 
			
		||||
@@ -1869,6 +1864,17 @@ var Workspace = new Lang.Class({
 | 
			
		||||
        return [clone, overlay];
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeWindowClone(metaWin) {
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
        let index = this._lookupIndex (metaWin);
 | 
			
		||||
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        this._windowOverlays.splice(index, 1);
 | 
			
		||||
        return this._windows.splice(index, 1).pop();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onShowOverlayClose(windowOverlay) {
 | 
			
		||||
        for (let i = 0; i < this._windowOverlays.length; i++) {
 | 
			
		||||
            let overlay = this._windowOverlays[i];
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ var WORKSPACE_CUT_SIZE = 10;
 | 
			
		||||
 | 
			
		||||
var WORKSPACE_KEEP_ALIVE_TIME = 100;
 | 
			
		||||
 | 
			
		||||
const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
 | 
			
		||||
var OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
 | 
			
		||||
 | 
			
		||||
/* A layout manager that requests size only for primary_actor, but then allocates
 | 
			
		||||
   all using a fixed layout */
 | 
			
		||||
@@ -241,7 +241,7 @@ var WindowClone = new Lang.Class({
 | 
			
		||||
Signals.addSignalMethods(WindowClone.prototype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const ThumbnailState = {
 | 
			
		||||
var ThumbnailState = {
 | 
			
		||||
    NEW   :         0,
 | 
			
		||||
    ANIMATING_IN :  1,
 | 
			
		||||
    NORMAL:         2,
 | 
			
		||||
@@ -275,8 +275,8 @@ var WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
 | 
			
		||||
        this._createBackground();
 | 
			
		||||
 | 
			
		||||
        let monitor = Main.layoutManager.primaryMonitor;
 | 
			
		||||
        this.setPorthole(monitor.x, monitor.y, monitor.width, monitor.height);
 | 
			
		||||
        let workArea = Main.layoutManager.getWorkAreaForMonitor(this.monitorIndex);
 | 
			
		||||
        this.setPorthole(workArea.x, workArea.y, workArea.width, workArea.height);
 | 
			
		||||
 | 
			
		||||
        let windows = global.get_window_actors().filter(actor => {
 | 
			
		||||
            let win = actor.meta_window;
 | 
			
		||||
@@ -321,8 +321,6 @@ var WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    setPorthole(x, y, width, height) {
 | 
			
		||||
        this._portholeX = x;
 | 
			
		||||
        this._portholeY = y;
 | 
			
		||||
        this.actor.set_size(width, height);
 | 
			
		||||
        this._contents.set_position(-x, -y);
 | 
			
		||||
    },
 | 
			
		||||
@@ -374,17 +372,8 @@ var WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _doRemoveWindow(metaWin) {
 | 
			
		||||
        let win = metaWin.get_compositor_private();
 | 
			
		||||
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
        let index = this._lookupIndex (metaWin);
 | 
			
		||||
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        let clone = this._windows[index];
 | 
			
		||||
        this._windows.splice(index, 1);
 | 
			
		||||
 | 
			
		||||
        let clone = this._removeWindowClone(metaWin);
 | 
			
		||||
        if (clone)
 | 
			
		||||
            clone.destroy();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -537,6 +526,9 @@ var WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
        clone.connect('drag-end', () => {
 | 
			
		||||
            Main.overview.endWindowDrag(clone.metaWindow);
 | 
			
		||||
        });
 | 
			
		||||
        clone.actor.connect('destroy', () => {
 | 
			
		||||
            this._removeWindowClone(clone.metaWindow);
 | 
			
		||||
        });
 | 
			
		||||
        this._contents.add_actor(clone.actor);
 | 
			
		||||
 | 
			
		||||
        if (this._windows.length == 0)
 | 
			
		||||
@@ -549,6 +541,16 @@ var WorkspaceThumbnail = new Lang.Class({
 | 
			
		||||
        return clone;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _removeWindowClone(metaWin) {
 | 
			
		||||
        // find the position of the window in our list
 | 
			
		||||
        let index = this._lookupIndex (metaWin);
 | 
			
		||||
 | 
			
		||||
        if (index == -1)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        return this._windows.splice(index, 1).pop();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activate(time) {
 | 
			
		||||
        if (this.state > ThumbnailState.NORMAL)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -675,11 +677,7 @@ var ThumbnailsBox = new Lang.Class({
 | 
			
		||||
        this._settings.connect('changed::dynamic-workspaces',
 | 
			
		||||
            this._updateSwitcherVisibility.bind(this));
 | 
			
		||||
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', () => {
 | 
			
		||||
            this._destroyThumbnails();
 | 
			
		||||
            if (Main.overview.visible)
 | 
			
		||||
                this._createThumbnails();
 | 
			
		||||
        });
 | 
			
		||||
        Main.layoutManager.connect('monitors-changed', this._rebuildThumbnails.bind(this));
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateSwitcherVisibility() {
 | 
			
		||||
@@ -872,6 +870,9 @@ var ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            Main.overview.connect('windows-restacked',
 | 
			
		||||
                                  this._syncStacking.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._workareasChangedId =
 | 
			
		||||
            global.screen.connect('workareas-changed', this._rebuildThumbnails.bind(this));
 | 
			
		||||
 | 
			
		||||
        this._targetScale = 0;
 | 
			
		||||
        this._scale = 0;
 | 
			
		||||
        this._pendingScaleUpdate = false;
 | 
			
		||||
@@ -901,12 +902,24 @@ var ThumbnailsBox = new Lang.Class({
 | 
			
		||||
            this._syncStackingId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (this._workareasChangedId > 0) {
 | 
			
		||||
            global.screen.disconnect(this._workareasChangedId);
 | 
			
		||||
            this._workareasChangedId = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (let w = 0; w < this._thumbnails.length; w++)
 | 
			
		||||
            this._thumbnails[w].destroy();
 | 
			
		||||
        this._thumbnails = [];
 | 
			
		||||
        this._porthole = null;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _rebuildThumbnails() {
 | 
			
		||||
        this._destroyThumbnails();
 | 
			
		||||
 | 
			
		||||
        if (Main.overview.visible)
 | 
			
		||||
            this._createThumbnails();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _workspacesChanged() {
 | 
			
		||||
        let validThumbnails =
 | 
			
		||||
            this._thumbnails.filter(t => t.state <= ThumbnailState.NORMAL);
 | 
			
		||||
@@ -1159,7 +1172,7 @@ var ThumbnailsBox = new Lang.Class({
 | 
			
		||||
    // The "porthole" is the portion of the screen that we show in the
 | 
			
		||||
    // workspaces
 | 
			
		||||
    _ensurePorthole() {
 | 
			
		||||
        if (!Main.layoutManager.primaryMonitor)
 | 
			
		||||
        if (!Main.layoutManager.primaryMonitor || !Main.overview.visible)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        if (!this._porthole)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
project('gnome-shell', 'c',
 | 
			
		||||
  version: '3.28.1',
 | 
			
		||||
  version: '3.28.3',
 | 
			
		||||
  meson_version: '>= 0.42.0',
 | 
			
		||||
  license: 'GPLv2+'
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								po/pt_BR.po
									
									
									
									
									
								
							@@ -15,22 +15,22 @@
 | 
			
		||||
# Georges Basile Stavracas Neto <georges.stavracas@gmail.com>, 2014.
 | 
			
		||||
# Felipe Braga <fbobraga@gmail.com>, 2015.
 | 
			
		||||
# Artur de Aquino Morais <artur.morais93@outlook.com>, 2016.
 | 
			
		||||
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2017.
 | 
			
		||||
# Rafael Fontenelle <rafaelff@gnome.org>, 2013-2018.
 | 
			
		||||
# Enrico Nicoletto <liverig@gmail.com>, 2013-2018.
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-03-16 21:34+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-02-09 21:52-0200\n"
 | 
			
		||||
"Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n"
 | 
			
		||||
"POT-Creation-Date: 2018-04-13 18:31+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-05-02 15:45-0200\n"
 | 
			
		||||
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
 | 
			
		||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
 | 
			
		||||
"Language: pt_BR\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
 | 
			
		||||
"X-Generator: Poedit 2.0.6\n"
 | 
			
		||||
"X-Generator: Virtaal 1.0.0-beta1\n"
 | 
			
		||||
"X-Project-Style: gnome\n"
 | 
			
		||||
 | 
			
		||||
#: data/50-gnome-shell-system.xml:6
 | 
			
		||||
@@ -356,7 +356,7 @@ msgid "There was an error loading the preferences dialog for %s:"
 | 
			
		||||
msgstr "Ocorreu um erro ao carregar o dialogo de preferências para %s:"
 | 
			
		||||
 | 
			
		||||
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
 | 
			
		||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:148
 | 
			
		||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
 | 
			
		||||
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
 | 
			
		||||
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
@@ -642,7 +642,7 @@ msgstr "Negar acesso"
 | 
			
		||||
 | 
			
		||||
#: js/ui/accessDialog.js:64 js/ui/status/location.js:396
 | 
			
		||||
msgid "Grant Access"
 | 
			
		||||
msgstr "Garantir acesso"
 | 
			
		||||
msgstr "Conceder acesso"
 | 
			
		||||
 | 
			
		||||
#: js/ui/appDisplay.js:793
 | 
			
		||||
msgid "Frequently used applications will appear here"
 | 
			
		||||
@@ -676,12 +676,12 @@ msgstr "Adicionar aos favoritos"
 | 
			
		||||
msgid "Show Details"
 | 
			
		||||
msgstr "Mostrar detalhes"
 | 
			
		||||
 | 
			
		||||
#: js/ui/appFavorites.js:138
 | 
			
		||||
#: js/ui/appFavorites.js:140
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s has been added to your favorites."
 | 
			
		||||
msgstr "%s foi adicionado aos seus favoritos."
 | 
			
		||||
 | 
			
		||||
#: js/ui/appFavorites.js:172
 | 
			
		||||
#: js/ui/appFavorites.js:174
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s has been removed from your favorites."
 | 
			
		||||
msgstr "%s foi removido dos seus favoritos."
 | 
			
		||||
@@ -876,7 +876,7 @@ msgstr "Unidade externa desconectada"
 | 
			
		||||
msgid "Open with %s"
 | 
			
		||||
msgstr "Abrir com %s"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:284
 | 
			
		||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Senha:"
 | 
			
		||||
 | 
			
		||||
@@ -964,15 +964,15 @@ msgstr "Uma senha é necessária para se conectar a “%s”."
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Gerenciador de rede"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:43
 | 
			
		||||
#: js/ui/components/polkitAgent.js:48
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Autenticação necessária"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:71
 | 
			
		||||
#: js/ui/components/polkitAgent.js:76
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Administrador"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:151
 | 
			
		||||
#: js/ui/components/polkitAgent.js:156
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Autenticação"
 | 
			
		||||
 | 
			
		||||
@@ -980,7 +980,7 @@ msgstr "Autenticação"
 | 
			
		||||
#. * requested authentication was not gained; this can happen
 | 
			
		||||
#. * because of an authentication error (like invalid password),
 | 
			
		||||
#. * for instance.
 | 
			
		||||
#: js/ui/components/polkitAgent.js:270 js/ui/shellMountOperation.js:327
 | 
			
		||||
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
 | 
			
		||||
msgid "Sorry, that didn’t work. Please try again."
 | 
			
		||||
msgstr "Desculpe, isto não funcionou. Por favor, tente novamente."
 | 
			
		||||
 | 
			
		||||
@@ -1028,7 +1028,7 @@ msgstr "Adicionar relógios mundiais…"
 | 
			
		||||
msgid "World Clocks"
 | 
			
		||||
msgstr "Relógios mundiais"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:225
 | 
			
		||||
#: js/ui/dateMenu.js:227
 | 
			
		||||
msgid "Weather"
 | 
			
		||||
msgstr "Meteorologia"
 | 
			
		||||
 | 
			
		||||
@@ -1036,7 +1036,7 @@ msgstr "Meteorologia"
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:289
 | 
			
		||||
#: js/ui/dateMenu.js:291
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s all day."
 | 
			
		||||
msgstr "%s por todo o dia."
 | 
			
		||||
@@ -1045,7 +1045,7 @@ msgstr "%s por todo o dia."
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:295
 | 
			
		||||
#: js/ui/dateMenu.js:297
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s, then %s later."
 | 
			
		||||
msgstr "%s, depois %s mais tarde."
 | 
			
		||||
@@ -1054,30 +1054,30 @@ msgstr "%s, depois %s mais tarde."
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:301
 | 
			
		||||
#: js/ui/dateMenu.js:303
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s, then %s, followed by %s later."
 | 
			
		||||
msgstr "%s, depois %s, seguido de %s mais tarde."
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:312
 | 
			
		||||
#: js/ui/dateMenu.js:314
 | 
			
		||||
msgid "Select a location…"
 | 
			
		||||
msgstr "Selecione uma localização…"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:315
 | 
			
		||||
#: js/ui/dateMenu.js:317
 | 
			
		||||
msgid "Loading…"
 | 
			
		||||
msgstr "Carregando…"
 | 
			
		||||
 | 
			
		||||
#. Translators: %s is a temperature with unit, e.g. "23℃"
 | 
			
		||||
#: js/ui/dateMenu.js:321
 | 
			
		||||
#: js/ui/dateMenu.js:323
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "Feels like %s."
 | 
			
		||||
msgstr "Sensação térmica de %s."
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:324
 | 
			
		||||
#: js/ui/dateMenu.js:326
 | 
			
		||||
msgid "Go online for weather information"
 | 
			
		||||
msgstr "Conecte-se à internet para obter as informações meteorológicas"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:326
 | 
			
		||||
#: js/ui/dateMenu.js:328
 | 
			
		||||
msgid "Weather information is currently unavailable"
 | 
			
		||||
msgstr "No momento as informações meteorológicas não estão disponíveis"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								po/ru.po
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								po/ru.po
									
									
									
									
									
								
							@@ -18,8 +18,8 @@ msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: gnome-shell\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell/issues\n"
 | 
			
		||||
"POT-Creation-Date: 2018-04-12 11:47+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-04-12 16:48+0300\n"
 | 
			
		||||
"POT-Creation-Date: 2018-04-13 18:31+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2018-04-19 23:31+0300\n"
 | 
			
		||||
"Last-Translator: Stas Solovey <whats_up@tut.by>\n"
 | 
			
		||||
"Language-Team: Русский <gnome-cyr@gnome.org>\n"
 | 
			
		||||
"Language: ru\n"
 | 
			
		||||
@@ -344,7 +344,7 @@ msgid "There was an error loading the preferences dialog for %s:"
 | 
			
		||||
msgstr "Возникла ошибка загрузки диалогового окна параметров для %s:"
 | 
			
		||||
 | 
			
		||||
#: js/gdm/authPrompt.js:147 js/ui/audioDeviceSelection.js:71
 | 
			
		||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:149
 | 
			
		||||
#: js/ui/components/networkAgent.js:117 js/ui/components/polkitAgent.js:153
 | 
			
		||||
#: js/ui/endSessionDialog.js:482 js/ui/extensionDownloader.js:197
 | 
			
		||||
#: js/ui/shellMountOperation.js:343 js/ui/status/network.js:919
 | 
			
		||||
msgid "Cancel"
 | 
			
		||||
@@ -563,7 +563,6 @@ msgstr "Вчера, %H∶%M"
 | 
			
		||||
msgid "%A, %H∶%M"
 | 
			
		||||
msgstr "%A, %H∶%M"
 | 
			
		||||
 | 
			
		||||
# fix даты "11 мар., 20:35"
 | 
			
		||||
#. Translators: this is the month name and day number
 | 
			
		||||
#. followed by a time string in 24h format.
 | 
			
		||||
#. i.e. "May 25, 14:30"
 | 
			
		||||
@@ -572,7 +571,6 @@ msgstr "%A, %H∶%M"
 | 
			
		||||
msgid "%B %d, %H∶%M"
 | 
			
		||||
msgstr "%-d %B, %H∶%M"
 | 
			
		||||
 | 
			
		||||
# fix даты
 | 
			
		||||
#. Translators: this is the month name, day number, year
 | 
			
		||||
#. number followed by a time string in 24h format.
 | 
			
		||||
#. i.e. "May 25 2012, 14:30"
 | 
			
		||||
@@ -581,7 +579,6 @@ msgstr "%-d %B, %H∶%M"
 | 
			
		||||
msgid "%B %d %Y, %H∶%M"
 | 
			
		||||
msgstr "%-d %B %Y, %H∶%M"
 | 
			
		||||
 | 
			
		||||
# по всей видимости разрабы коммент перепутали c "Translators: Time in 12h format"
 | 
			
		||||
#. Translators: Time in 12h format
 | 
			
		||||
#: js/misc/util.js:257
 | 
			
		||||
msgid "%l∶%M %p"
 | 
			
		||||
@@ -823,7 +820,6 @@ msgctxt "calendar heading"
 | 
			
		||||
msgid "%A, %B %d"
 | 
			
		||||
msgstr "%A, %-d %B"
 | 
			
		||||
 | 
			
		||||
# fix для даты в календаре и на экране блокировки
 | 
			
		||||
#: js/ui/calendar.js:868
 | 
			
		||||
msgctxt "calendar heading"
 | 
			
		||||
msgid "%A, %B %d, %Y"
 | 
			
		||||
@@ -876,7 +872,7 @@ msgstr "Внешний диск отключён"
 | 
			
		||||
msgid "Open with %s"
 | 
			
		||||
msgstr "Открыть с помощью %s"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:285
 | 
			
		||||
#: js/ui/components/keyring.js:107 js/ui/components/polkitAgent.js:295
 | 
			
		||||
msgid "Password:"
 | 
			
		||||
msgstr "Пароль:"
 | 
			
		||||
 | 
			
		||||
@@ -963,15 +959,15 @@ msgstr "Для подключения к «%s» требуется пароль.
 | 
			
		||||
msgid "Network Manager"
 | 
			
		||||
msgstr "Диспетчер сети"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:44
 | 
			
		||||
#: js/ui/components/polkitAgent.js:48
 | 
			
		||||
msgid "Authentication Required"
 | 
			
		||||
msgstr "Требуется подтверждение подлинности"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:72
 | 
			
		||||
#: js/ui/components/polkitAgent.js:76
 | 
			
		||||
msgid "Administrator"
 | 
			
		||||
msgstr "Администратор"
 | 
			
		||||
 | 
			
		||||
#: js/ui/components/polkitAgent.js:152
 | 
			
		||||
#: js/ui/components/polkitAgent.js:156
 | 
			
		||||
msgid "Authenticate"
 | 
			
		||||
msgstr "Подтвердить"
 | 
			
		||||
 | 
			
		||||
@@ -979,7 +975,7 @@ msgstr "Подтвердить"
 | 
			
		||||
#. * requested authentication was not gained; this can happen
 | 
			
		||||
#. * because of an authentication error (like invalid password),
 | 
			
		||||
#. * for instance.
 | 
			
		||||
#: js/ui/components/polkitAgent.js:271 js/ui/shellMountOperation.js:327
 | 
			
		||||
#: js/ui/components/polkitAgent.js:281 js/ui/shellMountOperation.js:327
 | 
			
		||||
msgid "Sorry, that didn’t work. Please try again."
 | 
			
		||||
msgstr "Не удалось подтвердить подлинность. Попробуйте снова."
 | 
			
		||||
 | 
			
		||||
@@ -1004,7 +1000,6 @@ msgstr "Показать приложения"
 | 
			
		||||
msgid "Dash"
 | 
			
		||||
msgstr "Панель приложений"
 | 
			
		||||
 | 
			
		||||
# fix для даты в календаре и на экране блокировки
 | 
			
		||||
#. Translators: This is the date format to use when the calendar popup is
 | 
			
		||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
 | 
			
		||||
#.
 | 
			
		||||
@@ -1012,7 +1007,6 @@ msgstr "Панель приложений"
 | 
			
		||||
msgid "%B %e %Y"
 | 
			
		||||
msgstr "%-d %B %Y"
 | 
			
		||||
 | 
			
		||||
# fix для даты в календаре и на экране блокировки
 | 
			
		||||
#. Translators: This is the accessible name of the date button shown
 | 
			
		||||
#. * below the time in the shell; it should combine the weekday and the
 | 
			
		||||
#. * date, e.g. "Tuesday February 17 2015".
 | 
			
		||||
@@ -1029,7 +1023,7 @@ msgstr "Добавить мировые часы…"
 | 
			
		||||
msgid "World Clocks"
 | 
			
		||||
msgstr "Мировые часы"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:225
 | 
			
		||||
#: js/ui/dateMenu.js:227
 | 
			
		||||
msgid "Weather"
 | 
			
		||||
msgstr "Погода"
 | 
			
		||||
 | 
			
		||||
@@ -1037,7 +1031,7 @@ msgstr "Погода"
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:289
 | 
			
		||||
#: js/ui/dateMenu.js:291
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s all day."
 | 
			
		||||
msgstr "%s весь день."
 | 
			
		||||
@@ -1046,7 +1040,7 @@ msgstr "%s весь день."
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:295
 | 
			
		||||
#: js/ui/dateMenu.js:297
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s, then %s later."
 | 
			
		||||
msgstr "%s, затем позднее %s."
 | 
			
		||||
@@ -1055,30 +1049,30 @@ msgstr "%s, затем позднее %s."
 | 
			
		||||
#. libgweather for the possible condition strings. If at all
 | 
			
		||||
#. possible, the sentence should match the grammatical case etc. of
 | 
			
		||||
#. the inserted conditions.
 | 
			
		||||
#: js/ui/dateMenu.js:301
 | 
			
		||||
#: js/ui/dateMenu.js:303
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "%s, then %s, followed by %s later."
 | 
			
		||||
msgstr "%s, затем %s, позже %s."
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:312
 | 
			
		||||
#: js/ui/dateMenu.js:314
 | 
			
		||||
msgid "Select a location…"
 | 
			
		||||
msgstr "Выберите местоположение…"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:315
 | 
			
		||||
#: js/ui/dateMenu.js:317
 | 
			
		||||
msgid "Loading…"
 | 
			
		||||
msgstr "Загрузка…"
 | 
			
		||||
 | 
			
		||||
#. Translators: %s is a temperature with unit, e.g. "23℃"
 | 
			
		||||
#: js/ui/dateMenu.js:321
 | 
			
		||||
#: js/ui/dateMenu.js:323
 | 
			
		||||
#, javascript-format
 | 
			
		||||
msgid "Feels like %s."
 | 
			
		||||
msgstr "Ощущается как %s."
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:324
 | 
			
		||||
#: js/ui/dateMenu.js:326
 | 
			
		||||
msgid "Go online for weather information"
 | 
			
		||||
msgstr "Подключите интернет для получения информации о погоде"
 | 
			
		||||
 | 
			
		||||
#: js/ui/dateMenu.js:326
 | 
			
		||||
#: js/ui/dateMenu.js:328
 | 
			
		||||
msgid "Weather information is currently unavailable"
 | 
			
		||||
msgstr "Информация о погоде сейчас недоступна"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -399,9 +399,6 @@ get_gl_vendor (void)
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,7 @@ libst_gir = gnome.generate_gir(libst,
 | 
			
		||||
  sources: st_gir_sources,
 | 
			
		||||
  nsversion: '1.0',
 | 
			
		||||
  namespace: 'St',
 | 
			
		||||
  includes: ['Clutter-' + mutter_api_version, 'Gtk-3.0'],
 | 
			
		||||
  includes: ['Clutter-' + mutter_api_version, 'Cally-' + mutter_api_version, 'Gtk-3.0'],
 | 
			
		||||
  dependencies: [mutter_dep],
 | 
			
		||||
  include_directories: include_directories('..'),
 | 
			
		||||
  extra_args: ['-DST_COMPILATION', '--quiet'],
 | 
			
		||||
 
 | 
			
		||||
@@ -180,6 +180,7 @@ st_label_dispose (GObject   *object)
 | 
			
		||||
{
 | 
			
		||||
  StLabelPrivate *priv = ST_LABEL (object)->priv;
 | 
			
		||||
 | 
			
		||||
  priv->label = NULL;
 | 
			
		||||
  g_clear_pointer (&priv->text_shadow_pipeline, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (st_label_parent_class)->dispose (object);
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ struct _StTextureCachePrivate
 | 
			
		||||
 | 
			
		||||
  /* Things that were loaded with a cache policy != NONE */
 | 
			
		||||
  GHashTable *keyed_cache; /* char * -> CoglTexture* */
 | 
			
		||||
  GHashTable *keyed_surface_cache; /* char * -> cairo_surface_t* */
 | 
			
		||||
 | 
			
		||||
  /* Presently this is used to de-duplicate requests for GIcons and async URIs. */
 | 
			
		||||
  GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
 | 
			
		||||
@@ -104,6 +105,18 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
 | 
			
		||||
                  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)
 | 
			
		||||
@@ -145,6 +158,10 @@ st_texture_cache_init (StTextureCache *self)
 | 
			
		||||
 | 
			
		||||
  self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
                                                   g_free, cogl_object_unref);
 | 
			
		||||
  self->priv->keyed_surface_cache = g_hash_table_new_full (g_str_hash,
 | 
			
		||||
                                                           g_str_equal,
 | 
			
		||||
                                                           g_free,
 | 
			
		||||
                                                           (GDestroyNotify) cairo_surface_destroy);
 | 
			
		||||
  self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
 | 
			
		||||
                                                            g_free, NULL);
 | 
			
		||||
  self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
 | 
			
		||||
@@ -166,6 +183,7 @@ st_texture_cache_dispose (GObject *object)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy);
 | 
			
		||||
  g_clear_pointer (&self->priv->keyed_surface_cache, g_hash_table_destroy);
 | 
			
		||||
  g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy);
 | 
			
		||||
  g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy);
 | 
			
		||||
 | 
			
		||||
@@ -520,6 +538,8 @@ finish_texture_load (AsyncTextureLoadData *data,
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  texdata = pixbuf_to_cogl_texture (pixbuf);
 | 
			
		||||
  if (!texdata)
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
 | 
			
		||||
    {
 | 
			
		||||
@@ -986,7 +1006,7 @@ file_changed_cb (GFileMonitor      *monitor,
 | 
			
		||||
  g_free (key);
 | 
			
		||||
 | 
			
		||||
  key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
 | 
			
		||||
  g_hash_table_remove (cache->priv->keyed_cache, key);
 | 
			
		||||
  g_hash_table_remove (cache->priv->keyed_surface_cache, key);
 | 
			
		||||
  g_free (key);
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
 | 
			
		||||
@@ -1273,6 +1293,9 @@ st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache,
 | 
			
		||||
      texdata = pixbuf_to_cogl_texture (pixbuf);
 | 
			
		||||
      g_object_unref (pixbuf);
 | 
			
		||||
 | 
			
		||||
      if (!texdata)
 | 
			
		||||
        goto out;
 | 
			
		||||
 | 
			
		||||
      if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
 | 
			
		||||
        {
 | 
			
		||||
          cogl_object_ref (texdata);
 | 
			
		||||
@@ -1304,7 +1327,7 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache        *cache,
 | 
			
		||||
 | 
			
		||||
  key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
 | 
			
		||||
 | 
			
		||||
  surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
 | 
			
		||||
  surface = g_hash_table_lookup (cache->priv->keyed_surface_cache, key);
 | 
			
		||||
 | 
			
		||||
  if (surface == NULL)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1318,7 +1341,8 @@ st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache        *cache,
 | 
			
		||||
      if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_surface_reference (surface);
 | 
			
		||||
          g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), surface);
 | 
			
		||||
          g_hash_table_insert (cache->priv->keyed_surface_cache,
 | 
			
		||||
                               g_strdup (key), surface);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,7 @@ typedef enum {
 | 
			
		||||
} StTextureCachePolicy;
 | 
			
		||||
 | 
			
		||||
StTextureCache* st_texture_cache_get_default (void);
 | 
			
		||||
void st_texture_cache_clear (StTextureCache *cache);
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
st_texture_cache_load_sliced_image (StTextureCache *cache,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user