Compare commits

..

3 Commits

Author SHA1 Message Date
Giovanni Campagna
60d87ef4ba Handle global keybindings in the shell
Handling global keybindings, such as volume and brightness keys
but also custom keybindings, directly in the compositor is the only way
to deal with grabs and modal operations that could be active (primarily
the overview, for which special policy was introduced in the last
commit)

https://bugzilla.gnome.org/show_bug.cgi?id=613543
2012-11-10 17:04:48 +01:00
Giovanni Campagna
d886dc17e1 Prefix keybinding names with 'internal-keybinding-'
This is what mutter does internally now, to disambiguate them with
custom keybindings introduced with display.add_keybinding().

https://bugzilla.gnome.org/show_bug.cgi?id=613543
2012-11-10 17:04:48 +01:00
Giovanni Campagna
9dd2a467ba Main: filter keybindings when the shell is modal
Mutter now handles some keybindings even when the compositor is
grabbed, so we need to filter the invocation at the handler level.
This allows to finally get rid of a old hack.

https://bugzilla.gnome.org/show_bug.cgi?id=613543
2012-11-10 16:22:03 +01:00
55 changed files with 1685 additions and 1345 deletions

67
NEWS
View File

@@ -1,70 +1,3 @@
3.7.2.1
=======
* Revert 490206b to not depend on NMGTK-0.9.7, which hasn't been released yet
3.7.2
=====
* Enforce RTL in he for messages that might end up as LTR [Florian; #686630]
* gdm: Move logo into the panel [Florian; #685852]
* Hide notifications when closed button is clicked [Jasper, Florian; #682237]
* Tweak screenShield animations [Rui; #686745]
* Restore Fittsability of summary items in message tray [Florian; #686474]
* Save screencasts as recent item [Ray; #680647]
* overview: Resize window captions on content change [Giovanni, Alex; #620874]
* App search: Match GenericName too [Matthias; #687121]
* runDialog: Better match style of other modal dialogs [Florian, Allan; #687127]
* Improve the button insensitive style [Stéphane; #687110]
* network: Don't use a global switch for all VPN connections [Giovanni; #682929]
* appMenu: Update on icon theme changes [Florian; #687224]
* Show 'Log out' in more situations [Matthias; #686736]
* Add a setting to force the 'Log out' menuitem [Matthias; #686057]
* overview: Improve styling of search box [Stéphane; #686479]
* Implement 'disable-user-list' in login screen [Ray; #660660]
* Fix auto-scroll to bottom in chat notifications [Sjoerd; #686571]
* Show feedback notifications when user is busy [Stéphane; #662900]
* Disable login button when there is no input [Stéphane; #687112]
* Use non-linear overview shade for background [Giovanni, Pierre-Eric; #669798]
* Reduce blocking in compositor thread [Simon, Jasper; #687465]
* network: new country-specific type to gather providers [Aleksander; #687356]
* Update man page [Matthias; #680601]
* st-entry: Change the pointer cursor on enter/leave events [Thomas; #687130]
* screenShield: Blur and desaturate the background [Giovanni, Cosimo; #682536]
* Change height of chat notifications to have more context [Carlos; #665255]
* screenShield: Account for motion velocity when hiding [Giovanni; #682537]
* screenShield: hide the cursor while the lock screen is on [Giovanni; #682535]
* Support remote search provider settings [Cosimo; #687491]
* unlockDialog: Improve label of confirmation button [Stéphane; #687656]
* userMenu: Rename "System Settings" item to "Settings" [Elad; #687738]
* messageTray: Add keybinding to focus current notification [Stéphane; #652082]
* Remove shell-screen-grabber [Neil; #685915]
* main: Stop using Metacity's keybinding files [Florian; #687672]
* Bluetooth: Remove ObexFTP functionality [Bastien; #688160]
* a11y: Also set WM theme when HighContrast is switched on [Cosimo; #688256]
* network: Rework multiple NIC support [Giovanni; #677142]
* Rework keybindings to allow selective blocking/processing [Florian; #688202]
* recorder: Show indicator on primary monitor [Adel; #688470]
* recorder: Set frame duration to fix broken video headers [Adel; #688487]
* Misc. bugfixes and cleanups [Florian, Jasper, Giovanni, Matthew, Stéphane,
Allan, Daiki, Owen, Alejandro, Jean-François, Cosimo, Sebastian, Adel, Alban;
#686484, #686728, #686805, #686574, #686763, #682428, #687132, #685239,
#687189, #687226, #658091, #670687, #687457, #687242, #687287, #687020,
#686583, #661194, #687491, #657315, #687958, #683986, #688089, #687708,
#686530, #684810, #688181, #688475, #688557, #688507, #638351]
Contributors:
Elad Alfassa, Matthew Barnes, Alban Browaeys, Giovanni Campagna,
Cosimo Cecchi, Matthias Clasen, Allan Day, Stéphane Démurget,
Jean-François Fortin Tam, Adel Gadllah, Alex Hultman, Sebastian Keller,
Rui Matos, Simon McVittie, Aleksander Morgado, Florian Müllner,
Bastien Nocera, Pierre-Eric Pelloux-Prayer, Alejandro Piñeiro, Neil Roberts,
Sjoerd Simons, Carlos Soriano Sánchez, Jasper St. Pierre, Ray Strode,
Owen Taylor, Daiki Ueno, Thomas Wood
Translations:
Dušan Kazik [sk], Pavol Klačanský [sk], Piotr Drąg [pl], Yuri Myasoedov [ru],
Marek Černocký [cs], Kjartan Maraas [nb], Wolfgang Stöggl [de],
Yaron Shahrabani [he], Fran Diéguez [gl], Mattias Põldaru [et]
3.7.1
=====
* Add shortcut to open application view directly [Jeremy; #685738]

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.7.2.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.7.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/shell-global.c])
@@ -65,7 +65,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
CLUTTER_MIN_VERSION=1.11.11
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
GJS_MIN_VERSION=1.33.2
MUTTER_MIN_VERSION=3.7.2
MUTTER_MIN_VERSION=3.7.1
GTK_MIN_VERSION=3.3.9
GIO_MIN_VERSION=2.35.0
LIBECAL_MIN_VERSION=3.5.3
@@ -124,7 +124,7 @@ PKG_CHECK_MODULES(GNOME_SHELL_JS, gio-2.0 gjs-internals-1.0 >= $GJS_MIN_VERSION)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 >= 0.6.8 x11)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.2)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.5.4)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],

View File

@@ -2129,7 +2129,7 @@ StScrollBar StButton#vhandle:active {
font-weight: bold;
text-align: left;
padding-left: 15px;
text-shadow: black 0px 4px 3px 0px;
text-shadow: black 4px 4px 3px 0px;
}
.login-dialog-prompt-layout {
@@ -2325,3 +2325,17 @@ StScrollBar StButton#vhandle:active {
padding-bottom: 0px;
}
.osd-window {
color: #ededed;
background-color: rgba(33, 37, 38, 0.80);
border-radius: 15px;
text-shadow: 0 1px rgba(0, 0, 0, 0.75);
padding: 40px;
spacing: 5px;
}
.osd-progress-bar {
height: 0.8em;
border: 1px solid;
}

View File

@@ -100,6 +100,7 @@ nobase_dist_js_DATA = \
ui/components/__init__.js \
ui/components/autorunManager.js \
ui/components/automountManager.js \
ui/components/mediaKeysManager.js \
ui/components/networkAgent.js \
ui/components/polkitAgent.js \
ui/components/recorder.js \

View File

@@ -660,7 +660,6 @@ const LoginDialog = new Lang.Class({
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
parentActor: parentActor,
keybindingMode: Main.KeybindingMode.LOGIN_SCREEN,
shouldFadeIn: false });
this.connect('destroy',
Lang.bind(this, this._onDestroy));
@@ -1288,7 +1287,7 @@ const LoginDialog = new Lang.Class({
_onOpened: function() {
Main.ctrlAltTabManager.addGroup(this.dialogLayout,
_("Login Window"),
'dialog-password-symbolic',
'dialog-password',
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
},
@@ -1296,6 +1295,6 @@ const LoginDialog = new Lang.Class({
close: function() {
this.parent();
Main.ctrlAltTabManager.removeGroup(this.dialogLayout);
Main.ctrlAltTabManager.removeGroup(this._group);
}
});

View File

@@ -17,6 +17,9 @@ const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager
<method name='Suspend'>
<arg type='b' direction='in'/>
</method>
<method name='Hibernate'>
<arg type='b' direction='in'/>
</method>
<method name='CanPowerOff'>
<arg type='s' direction='out'/>
</method>
@@ -26,6 +29,9 @@ const SystemdLoginManagerIface = <interface name='org.freedesktop.login1.Manager
<method name='CanSuspend'>
<arg type='s' direction='out'/>
</method>
<method name='CanHibernate'>
<arg type='s' direction='out'/>
</method>
</interface>;
const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
@@ -140,6 +146,15 @@ const LoginManagerSystemd = new Lang.Class({
});
},
canHibernate: function(asyncCallback) {
this._proxy.CanSuspendRemote(function(result, error) {
if (error)
asyncCallback(false);
else
asyncCallback(result[0] != 'no');
});
},
powerOff: function() {
this._proxy.PowerOffRemote(true);
},
@@ -150,6 +165,10 @@ const LoginManagerSystemd = new Lang.Class({
suspend: function() {
this._proxy.SuspendRemote(true);
},
hibernate: function() {
this._proxy.HibernateRemote(true);
}
});
@@ -215,6 +234,13 @@ const LoginManagerConsoleKit = new Lang.Class({
}));
},
canHibernate: function(asyncCallback) {
Mainloop.idle_add(Lang.bind(this, function() {
asyncCallback(this._upClient.get_can_hibernate());
return false;
}));
},
powerOff: function() {
this._proxy.StopRemote();
},
@@ -225,5 +251,9 @@ const LoginManagerConsoleKit = new Lang.Class({
suspend: function() {
this._upClient.suspend_sync(null);
},
hibernate: function() {
this._upClient.hibernate_sync(null);
}
});

View File

@@ -288,3 +288,31 @@ function insertSorted(array, val, cmp) {
return pos;
}
/**
* wrapKeybinding:
*
* Wrap a keybinding handler so that
* it ignores an invocation if the shell is modal, but
* not when the overview is active, or when global
* keybindings are allowed by session mode.
* This function is only useful for keybindings installed
* with Meta.KeybindingFlags.HANDLE_WHEN_GRABBED
*/
function wrapKeybinding(handler, onlyInOverview) {
return function() {
let handle;
if (onlyInOverview) {
handle = Main.sessionMode.allowKeybindingsWhenModal ||
Main.modalCount == (Main.overview.visible ? 1 : 0);
} else {
handle = true;
}
if (handle)
return handler.apply(this, arguments);
else
return false;
}
}

View File

@@ -172,7 +172,7 @@ const AltTabPopup = new Lang.Class({
if (!Main.pushModal(this.actor)) {
// Probably someone else has a pointer grab, try again with keyboard only
if (!Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED })) {
if (!Main.pushModal(this.actor, global.get_current_time(), Meta.ModalOptions.POINTER_ALREADY_GRABBED)) {
return false;
}
}
@@ -199,7 +199,7 @@ const AltTabPopup = new Lang.Class({
this.actor.get_allocation_box();
// Make the initial selection
if (binding == 'switch-group') {
if (binding == 'internal-keybinding-switch-group') {
if (backward) {
this._select(0, this._appIcons[0].cachedWindows.length - 1);
} else {
@@ -208,9 +208,9 @@ const AltTabPopup = new Lang.Class({
else
this._select(0, 0);
}
} else if (binding == 'switch-group-backward') {
} else if (binding == 'internal-keybinding-switch-group-backward') {
this._select(0, this._appIcons[0].cachedWindows.length - 1);
} else if (binding == 'switch-windows-backward') {
} else if (binding == 'internal-keybinding-switch-windows-backward') {
this._select(this._appIcons.length - 1);
} else if (this._appIcons.length == 1) {
this._select(0);

View File

@@ -0,0 +1,647 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const ShellMountOperation = imports.ui.shellMountOperation;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
const INTERFACE_SETTINGS = 'org.gnome.desktop.interface';
const POWER_SETTINGS = 'org.gnome.settings-daemon.plugins.power';
const XSETTINGS_SETTINGS = 'org.gnome.settings-daemon.plugins.xsettings';
const TOUCHPAD_SETTINGS = 'org.gnome.settings-daemon.peripherals.touchpad';
const KEYBINDING_SETTINGS = 'org.gnome.settings-daemon.plugins.media-keys';
const CUSTOM_KEYBINDING_SETTINGS = 'org.gnome.settings-daemon.plugins.media-keys.custom-keybinding';
const A11Y_SETTINGS = 'org.gnome.desktop.a11y.applications';
const MAGNIFIER_SETTINGS = 'org.gnome.desktop.a11y.magnifier';
const INPUT_SOURCE_SETTINGS = 'org.gnome.desktop.input-sources';
const MediaKeysInterface = <interface name='org.gnome.SettingsDaemon.MediaKeys'>
<method name='GrabMediaPlayerKeys'>
<arg name='application' direction='in' type='s'/>
<arg name='time' direction='in' type='u'/>
</method>
<method name='ReleaseMediaPlayerKeys'>
<arg name='application' direction='in' type='s'/>
</method>
<signal name='MediaPlayerKeyPressed'>
<arg name='application' type='s'/>
<arg name='key' type='s'/>
</signal>
</interface>;
/* [ actionName, setting, hardcodedKeysym, overviewOnly, args ] */
/* (overviewOnly means that the keybinding is handled when the shell is not
modal, or when the overview is active, but not when other modal operations
are active; otherwise the keybinding is always handled) */
const DEFAULT_KEYBINDINGS = [
[ 'doTouchpadToggle', null, 'XF86TouchpadToggle', false ],
[ 'doTouchpadSet', null, 'XF86TouchpadOn', false, [ true ] ],
[ 'doTouchpadSet', null, 'XF86TouchpadOff', false, [ false ] ],
[ 'doMute', 'volume-mute', null, false, [ false ] ],
[ 'doVolumeAdjust', 'volume-down', null, false, [ Clutter.ScrollDirection.DOWN, false ] ],
[ 'doVolumeAdjust', 'volume-up', null, false, [ Clutter.ScrollDirection.UP, false ] ],
[ 'doMute', null, '<Alt>XF86AudioMute', false, [ true ] ],
[ 'doVolumeAdjust', null, '<Alt>XF86AudioLowerVolume', false, [ Clutter.ScrollDirection.DOWN, true ] ],
[ 'doVolumeAdjust', null, '<Alt>XF86AudioRaiseVolume', false, [ Clutter.ScrollDirection.UP, true ] ],
[ 'doLogout', 'logout', null, true ],
[ 'doEject', 'eject', null, false ],
[ 'doHome', 'home', null, true ],
[ 'doLaunchMimeHandler', 'media', null, true, [ 'application/x-vorbis+ogg' ] ],
[ 'doLaunchApp', 'calculator', null, true, [ 'gcalcltool.desktop' ] ],
[ 'doLaunchApp', 'search', null, true, [ 'tracker-needle.desktop' ] ],
[ 'doLaunchMimeHandler', 'email', null, true, [ 'x-scheme-handler/mailto' ] ],
[ 'doScreensaver', 'screensaver', null, true ],
[ 'doScreensaver', null, 'XF86ScreenSaver', true ],
[ 'doLaunchApp', 'help', null, true, [ 'yelp.desktop' ] ],
[ 'doSpawn', 'screenshot', null, true, [ ['gnome-screenshot'] ] ],
[ 'doSpawn', 'window-screenshot', null, true, [ ['gnome-screenshot', '--window'] ] ],
[ 'doSpawn', 'area-screenshot', null, true, [ ['gnome-screenshot', '--area'] ] ],
[ 'doSpawn', 'screenshot-clip', null, true, [ ['gnome-screenshot', '--clipboard'] ] ],
[ 'doSpawn', 'window-screenshot-clip', null, true, [ ['gnome-screenshot', '--window', '--clipboard'] ] ],
[ 'doSpawn', 'area-screenshot-clip', null, true, [ ['gnome-screenshot', '--area', '--clipboard'] ] ],
[ 'doLaunchMimeHandler', 'www', null, true, [ 'x-scheme-handler/http' ] ],
[ 'doMediaKey', 'play', null, true, [ 'Play' ] ],
[ 'doMediaKey', 'pause', null, true, [ 'Pause' ] ],
[ 'doMediaKey', 'stop', null, true, [ 'Stop' ] ],
[ 'doMediaKey', 'previous', null, true, [ 'Previous' ] ],
[ 'doMediaKey', 'next', null, true, [ 'Next' ] ],
[ 'doMediaKey', null, 'XF86AudioRewind', true, [ 'Rewind' ] ],
[ 'doMediaKey', null, 'XF86AudioForward', true, [ 'FastForward' ] ],
[ 'doMediaKey', null, 'XF86AudioRepeat', true, [ 'Repeat' ] ],
[ 'doMediaKey', null, 'XF86AudioRandomPlay', true, [ 'Shuffle' ] ],
[ 'doXRandRAction', null, '<Super>p', false, [ 'VideoModeSwitch' ] ],
/* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
[ 'doXRandRAction', null, 'XF86Display', false, [ 'VideoModeSwitch' ] ],
/* Key code of the XF86RotateWindows key (present on some tablets) */
[ 'doXRandRAction', null, 'XF86RotateWindows', false, [ 'Rotate' ] ],
[ 'doA11yAction', 'magnifier', null, true, [ 'screen-magnifier-enabled' ] ],
[ 'doA11yAction', 'screenreader', null, true, [ 'screen-reader-enabled' ] ],
[ 'doA11yAction', 'on-screen-keyboard', null, true, [ 'screen-keyboard-enabled' ] ],
[ 'doTextSize', 'increase-text-size', null, true, [ 1 ] ],
[ 'doTextSize', 'decrease-text-size', null, true, [ -1 ] ],
[ 'doToggleContrast', 'toggle-contrast', null, true ],
[ 'doMagnifierZoom', 'magnifier-zoom-in', null, true, [ 1 ] ],
[ 'doMagnifierZoom', 'magnifier-zoom-out', null, true, [ -1 ] ],
[ 'doPowerAction', null, 'XF86PowerOff', true, [ 'button-power' ] ],
/* the kernel / Xorg names really are like this... */
[ 'doPowerAction', null, 'XF86Suspend', false, [ 'button-sleep' ] ],
[ 'doPowerAction', null, 'XF86Sleep', false, [ 'button-suspend' ] ],
[ 'doPowerAction', null, 'XF86Hibernate', false, [ 'button-hibernate' ] ],
[ 'doBrightness', null, 'XF86MonBrightnessUp', false, [ 'Screen', 'StepUp' ] ],
[ 'doBrightness', null, 'XF86MonBrightnessDown', false, [ 'Screen', 'StepDown' ] ],
[ 'doBrightness', null, 'XF86KbdBrightnessUp', false, [ 'Keyboard', 'StepUp' ] ],
[ 'doBrightness', null, 'XF86KbdBrightnessDown', false, [ 'Keyboard', 'StepDown' ] ],
[ 'doBrightnessToggle', null, 'XF86KbdLightOnOff', false, ],
[ 'doInputSource', 'switch-input-source', null, false, [ +1 ] ],
[ 'doInputSource', 'switch-input-source-backward', null, false, [ -1 ] ],
[ 'doLaunchApp', null, 'XF86Battery', true, [ 'gnome-power-statistics.desktop' ] ]
];
var osdWin;
const OSDWindow = new Lang.Class({
Name: 'OSDWindow',
FADE_TIMEOUT: 1500,
FADE_DURATION: 100,
_init: function(iconName, value) {
/* assume 130x130 on a 640x480 display and scale from there */
let monitor = Main.layoutManager.primaryMonitor;
let scalew = monitor.width / 640.0;
let scaleh = monitor.height / 480.0;
let scale = Math.min(scalew, scaleh);
let size = 130 * Math.max(1, scale);
this.actor = new St.BoxLayout({ style_class: 'osd-window',
vertical: true,
reactive: false,
visible: false,
width: size,
height: size,
});
this._icon = new St.Icon({ icon_name: iconName,
icon_size: size / 2,
});
this.actor.add(this._icon, { expand: true,
x_align: St.Align.MIDDLE,
y_align: St.Align.MIDDLE });
this._value = value;
this._progressBar = new St.DrawingArea({ style_class: 'osd-progress-bar' });
this._progressBar.connect('repaint', Lang.bind(this, this._drawProgress));
this.actor.add(this._progressBar, { expand: true, x_fill: true, y_fill: false });
this._progressBar.visible = value !== undefined;
Main.layoutManager.addChrome(this.actor);
/* Position in the middle of primary monitor */
let [width, height] = this.actor.get_size();
this.actor.x = ((monitor.width - width) / 2) + monitor.x;
this.actor.y = monitor.y + (monitor.height / 2) + (monitor.height / 2 - height) / 2;
},
show: function() {
this.actor.show();
Tweener.addTween(this.actor,
{ opacity: 255,
time: this.FADE_DURATION / 1000,
transition: 'easeInQuad' });
if (this._timeoutId)
GLib.source_remove(this._timeoutId);
this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, this.FADE_TIMEOUT, Lang.bind(this, this.hide));
},
hide: function() {
Tweener.addTween(this.actor,
{ opacity: 0,
time: this.FADE_DURATION / 1000,
transition: 'easeOutQuad',
onComplete: function() {
this.actor.destroy();
this.actor = null;
osdWin = null;
},
onCompleteScope: this });
return false;
},
setIcon: function(name) {
this._icon.icon_name = name;
},
setValue: function(value) {
if (value == this._value)
return;
this._value = value;
this._progressBar.visible = value !== undefined;
this._progressBar.queue_repaint();
},
_drawProgress: function(area) {
let cr = area.get_context();
let themeNode = this.actor.get_theme_node();
let color = themeNode.get_foreground_color();
Clutter.cairo_set_source_color(cr, color);
let [width, height] = area.get_surface_size();
width = width * this._value;
cr.moveTo(0,0);
cr.lineTo(width, 0);
cr.lineTo(width, height);
cr.lineTo(0, height);
cr.fill();
}
});
function showOSD(icon, value) {
if (osdWin) {
osdWin.setIcon(icon);
osdWin.setValue(value);
} else {
osdWin = new OSDWindow(icon, value);
}
osdWin.show();
}
const MediaKeysGrabber = new Lang.Class({
Name: 'MediaKeysGrabber',
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MediaKeysInterface, this);
this._apps = [];
},
enable: function() {
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SettingsDaemon/MediaKeys');
},
disable: function() {
this._dbusImpl.unexport();
},
GrabMediaPlayerKeysAsync: function(parameters, invocation) {
let [appName, time] = parameters;
/* I'm not sure of this code, but it is in gnome-settings-daemon
(letting alone that the introspection is wrong in glib...)
*/
if (time == Gdk.CURRENT_TIME) {
let tv = new GLib.TimeVal;
GLib.get_current_time(tv);
time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
let pos = -1;
for (let i = 0; i < this._apps.length; i++) {
if (this._apps[i].appName == appName) {
pos = i;
break;
}
}
if (pos != -1)
this._freeMediaPlayer(pos);
let app = {
appName: appName,
name: invocation.get_sender(),
time: time,
watchId: Gio.DBus.session.watch_name(invocation.get_sender(),
Gio.BusNameWatcherFlags.NONE,
null,
Lang.bind(this, this._onNameVanished)),
};
Util.insertSorted(this._apps, app, function(a, b) {
return b.time-a.time;
});
invocation.return_value(GLib.Variant.new('()', []));
},
ReleaseMediaPlayerAsync: function(parameters, invocation) {
let name = invocation.get_sender();
let [appName] = parameters;
let pos = -1;
for (let i = 0; i < this._apps.length; i++) {
if (this._apps[i].appName == appName) {
pos = i;
break;
}
}
if (pos == -1) {
for (let i = 0; i < this._apps.length; i++) {
if (this._apps[i].name == name) {
pos = i;
break;
}
}
}
if (pos != -1)
this._freeMediaPlayer(pos);
invocation.return_value(GLib.Variant.new('()', []));
},
_freeMediaPlayer: function(pos) {
let app = this._apps[pos];
Gio.bus_unwatch_name(app.watchId)
this._apps.splice(pos, 1);
},
mediaKeyPressed: function(key) {
if (this._apps.length == 0) {
showOSD('action-unavailable-symbolic');
return;
}
let app = this._apps[0];
Gio.DBus.session.emit_signal(app.name,
'/org/gnome/SettingsDaemon/MediaKeys',
'org.gnome.SettingsDaemon.MediaKeys',
'MediaPlayerKeyPressed',
GLib.Variant.new('(ss)', [app.appName || '',
key]));
},
});
const MediaKeysManager = new Lang.Class({
Name: 'MediaKeysManager',
_init: function() {
this._a11yControl = Main.panel.statusArea.a11y;
this._volumeControl = Main.panel.statusArea.volume;
this._userMenu = Main.panel.statusArea.userMenu;
this._mediaPlayerKeys = new MediaKeysGrabber();
this._keybindingSettings = new Gio.Settings({ schema: KEYBINDING_SETTINGS });
},
enable: function() {
for (let i = 0; i < DEFAULT_KEYBINDINGS.length; i++) {
let [action, setting, keyval, overviewOnly, args] = DEFAULT_KEYBINDINGS[i];
let func = this[action];
if (!func) {
log('Keybinding action %s is missing'.format(action));
continue;
}
let name = setting ? setting : 'media-keys-keybindings-%d'.format(i);
let ok;
func = Util.wrapKeybinding(Lang.bind.apply(null, [this, func].concat(args)), overviewOnly);
if (setting)
ok = global.display.add_keybinding(setting, this._keybindingSettings,
Meta.KeyBindingFlags.BUILTIN |
Meta.KeyBindingFlags.IS_SINGLE |
Meta.KeyBindingFlags.HANDLE_WHEN_GRABBED, func);
else
ok = global.display.add_grabbed_key(name, keyval,
Meta.KeyBindingFlags.HANDLE_WHEN_GRABBED, func);
if (!ok)
log('Installing keybinding %s failed'.format(name));
}
this._customKeybindings = [];
this._changedId = this._keybindingSettings.connect('changed::custom-keybindings',
Lang.bind(this, this._reloadCustomKeybindings));
this._reloadCustomKeybindings();
this._mediaPlayerKeys.enable();
},
disable: function() {
for (let i = 0; i < DEFAULT_KEYBINDINGS.length; i++) {
let [action, setting, keyval, overviewOnly, args] = DEFAULT_KEYBINDINGS[i];
let name = setting ? setting : 'media-keys-keybindings-%d'.format(i);
if (setting)
global.display.remove_keybinding(setting, this._keybindingSettings);
else
global.display.remove_grabbed_key(name);
}
this._clearCustomKeybindings();
this._keybindingSettings.disconnect(this._changedId);
this._mediaPlayerKeys.disable();
},
_clearCustomKeybindings: function() {
for (let i = 0; i < this._customKeybindings.length; i++)
global.display.remove_keybinding('binding', this._customKeybindings[i]);
this._customKeybindings = [];
},
_reloadCustomKeybindings: function() {
this._clearCustomKeybindings();
let paths = this._keybindingSettings.get_strv('custom-keybindings');
for (let i = 0; i < paths.length; i++) {
let setting = new Gio.Settings({ schema: CUSTOM_KEYBINDING_SETTINGS,
path: paths[i] });
let func = Util.wrapKeybinding(Lang.bind(this, this.doCustom, setting), true);
global.display.add_keybinding('binding', setting,
Meta.KeyBindingFlags.IS_SINGLE |
Meta.KeyBindingFlags.HANDLE_WHEN_GRABBED, func);
this._customKeybindings.push(setting);
}
},
doCustom: function(display, screen, window, binding, settings) {
let command = settings.get_string('command');
Util.spawnCommandLine(command);
},
doTouchpadToggle: function(display, screen, window, binding) {
let settings = new Gio.Settings({ schema: TOUCHPAD_SETTINGS });
let enabled = settings.get_boolean('touchpad-enabled');
this.doTouchpadSet(display, screen, window, binding, !enabled);
settings.set_boolean(!enabled);
return true;
},
doTouchpadSet: function(display, screen, window, binding, enabled) {
showOSD(enabled ? 'input-touchpad-symbolic' : 'touchpad-disabled-symbolic');
return true;
},
doMute: function(display, screen, window, binding, quiet) {
let [icon, value] = this._volumeControl.volumeMenu.toggleMute(quiet);
showOSD(icon, value);
return true;
},
doVolumeAdjust: function(display, screen, window, binding, direction, quiet) {
let [icon, value] = this._volumeControl.volumeMenu.scroll(direction, quiet);
showOSD(icon, value);
return true;
},
doLogout: function(display, screen, window, binding) {
this._userMenu.logOut();
return true;
},
doEject: function(display, screen, window, binding) {
let volumeMonitor = Gio.VolumeMonitor.get();
let drives = volumeMonitor.get_connected_drives();
let score = 0, drive;
for (let i = 0; i < drives.length; i++) {
if (!drives[i].can_eject())
continue;
if (!drives[i].is_media_removable())
continue;
if (score < 1) {
drive = drives[i];
score = 1;
}
if (!drives[i].has_media())
continue;
if (score < 2) {
drive = drives[i];
score = 2;
break;
}
}
showOSD('media-eject-custom-symbolic');
if (!drive)
return true;
let mountOp = new ShellMountOperation.ShellMountOperation(drive);
drive.eject_with_operation(Gio.MountUnmountFlags.FORCE,
mountOp.mountOp, null, null);
return true;
},
doHome: function() {
let homeFile = Gio.file_new_for_path (GLib.get_home_dir());
let homeUri = homeFile.get_uri();
Gio.app_info_launch_default_for_uri(homeUri, null);
return true;
},
doLaunchMimeHandler: function(display, screen, window, binding, mimeType) {
let gioApp = Gio.AppInfo.get_default_for_type(mimeType, false);
if (gioApp != null) {
let app = Shell.AppSystem.get_default().lookup_app(gioApp.get_id());
app.open_new_window(-1);
} else {
log('Could not find default application for \'%s\' mime-type'.format(mimeType));
}
return true;
},
doLaunchApp: function(display, screen, window, binding, appId) {
let app = Shell.AppSystem.get_default().lookup_app(appId);
app.open_new_window(-1);
return true;
},
doScreensaver: function() {
// FIXME: handled in house, to the screenshield!
return true;
},
doSpawn: function(display, screen, window, binding, argv) {
Util.spawn(argv);
return true;
},
doMediaKey: function(display, screen, window, binding, key) {
this._mediaPlayerKeys.mediaKeyPressed(key);
},
_onXRandRFinished: function(connection, result) {
connection.call_finish(result);
this._XRandRCancellable = null;
},
doXRandRAction: function(display, screen, window, binding, action) {
if (this._XRandRCancellable)
this._XRandRCancellable.cancel();
this._XRandRCancellable = new Gio.Cancellable();
Gio.DBus.session.call('org.gnome.SettingsDaemon',
'/org/gnome/SettingsDaemon/XRANDR',
'org.gnome.SettingsDaemon.XRANDR_2',
action,
GLib.Variant.new('(x)', [global.get_current_time()]),
null, /* reply type */
Gio.DBusCallFlags.NONE,
-1,
this._XRandRCancellable,
Lang.bind(this, this._onXRandRFinished));
},
doA11yAction: function(display, screen, window, binding, key) {
let settings = new Gio.Settings({ schema: A11Y_SETTINGS });
let enabled = settings.get_boolean(key);
settings.set_boolean(key, !enabled);
},
doTextSize: function(display, screen, window, binding, multiplier) {
// Same values used in the Seeing tab of the Universal Access panel
const FACTORS = [ 0.75, 1.0, 1.25, 1.5 ];
// Figure out the current DPI scaling factor
let settings = new Gio.Settings({ schema: INTERFACE_SETTINGS });
let factor = settings.get_double('text-scaling-factor');
factor += multiplier * 0.25;
/* Try to find a matching value */
let distance = 1e6;
let best = 1.0;
for (let i = 0; i < FACTORS.length; i++) {
let d = Math.abs(factor - FACTORS[i]);
if (d < distance) {
best = factors[i];
distance = d;
}
}
if (best == 1.0)
settings.reset('text-scaling-factor');
else
settings.set_double('text-scaling-factor', best);
},
doToggleContrast: function(display, screen, window, binding) {
this._a11yControl.toggleHighContrast();
},
doMagnifierZoom: function(display, screen, window, binding, offset) {
let settings = new Gio.Settings({ schema: MAGNIFIER_SETTINGS });
let value = settings.get_value('mag-factor');
value = Math.round(value + offset);
settings.set_value('mag-factor', value);
},
doPowerAction: function(display, screen, window, binding, action) {
let settings = new Gio.Settings({ schema: POWER_SETTINGS });
switch (settings.get_string(action)) {
case 'suspend':
this._userMenu.suspend();
break;
case 'interactive':
case 'shutdown':
this._userMenu.shutdown();
break;
case 'hibernate':
this._userMenu.hibernate();
break;
case 'blank':
case 'default':
default:
break;
}
},
_onBrightnessFinished: function(connection, result, kind) {
let [percentage] = connection.call_finish(result).deep_unpack();
let icon = kind == 'Keyboard' ? 'keyboard-brightness-symbolic' : 'display-brightness-symbolic';
showOSD(icon, percentage / 100);
},
doBrightness: function(display, screen, window, binding, kind, action) {
let iface = 'org.gnome.SettingsDaemon.Power.' + kind;
let objectPath = '/org/gnome/SettingsDaemon/Power';
Gio.DBus.session.call('org.gnome.SettingsDaemon',
objectPath, iface, action,
null, null, /* parameters, reply type */
Gio.DBusCallFlags.NONE, -1, null,
Lang.bind(this, this._onBrightnessFinished, kind));
},
doInputSource: function(display, screen, window, binding, offset) {
let settings = new Gio.Settings({ schema: INPUT_SOURCE_SETTINGS });
let current = settings.get_uint('current');
let max = settings.get_strv('sources').length - 1;
current += offset;
if (current < 0)
current = 0;
else if (current > max)
current = max;
settings.set_uint('current', current);
},
});
const Component = MediaKeysManager;

View File

@@ -49,7 +49,7 @@ const AuthenticationDialog = new Lang.Class({
let messageBox = new St.BoxLayout({ style_class: 'prompt-dialog-message-layout',
vertical: true });
mainContentBox.add(messageBox,
{ expand: true, y_align: St.Align.START });
{ y_align: St.Align.START });
this._subjectLabel = new St.Label({ style_class: 'prompt-dialog-headline',
text: _("Authentication Required") });

View File

@@ -1,6 +1,5 @@
const Lang = imports.lang;
const Main = imports.ui.main;
const Gio = imports.gi.Gio;
const Meta = imports.gi.Meta;
@@ -17,16 +16,13 @@ const Recorder = new Lang.Class({
},
enable: function() {
Main.wm.addKeybinding('toggle-recording',
this._bindingSettings,
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleRecorder));
global.display.add_keybinding('toggle-recording',
this._bindingSettings,
Meta.KeyBindingFlags.NONE, Lang.bind(this, this._toggleRecorder));
},
disable: function() {
Main.wm.removeKeybinding('toggle-recording');
global.display.remove_keybinding('toggle-recording');
},
_ensureRecorder: function() {
@@ -56,6 +52,8 @@ const Recorder = new Lang.Class({
Meta.disable_unredirect_for_screen(global.screen);
recorder.record();
}
return true;
}
});

View File

@@ -637,10 +637,8 @@ const Dash = new Lang.Class({
icon.setIconSize(this.iconSize);
// Don't animate the icon size change when the overview
// is transitioning, not visible or when initially filling
// the dash
if (!Main.overview.visible || Main.overview.animationInProgress ||
!this._shownInitially)
// is not visible or when initially filling the dash
if (!Main.overview.visible || !this._shownInitially)
continue;
let [targetWidth, targetHeight] = icon.icon.get_size();
@@ -764,9 +762,8 @@ const Dash = new Lang.Class({
for (let i = 0; i < removedActors.length; i++) {
let item = removedActors[i]._delegate;
// Don't animate item removal when the overview is transitioning
// or hidden
if (Main.overview.visible && !Main.overview.animationInProgress)
// Don't animate item removal when the overview is hidden
if (Main.overview.visible)
item.animateOutAndDestroy();
else
item.destroy();
@@ -781,9 +778,8 @@ const Dash = new Lang.Class({
return;
}
// Don't animate item addition when the overview is transitioning
// or hidden
if (!Main.overview.visible || Main.overview.animationInProgress)
// Don't animate item addition when the overview is hidden
if (!Main.overview.visible)
return;
for (let i = 0; i < addedItems.length; i++)

View File

@@ -23,7 +23,6 @@ function _navigateActor(actor) {
// GrabHelper:
// @owner: the actor that owns the GrabHelper
// @params: optional parameters to pass to Main.pushModal()
//
// Creates a new GrabHelper object, for dealing with keyboard and pointer grabs
// associated with a set of actors.
@@ -35,9 +34,8 @@ function _navigateActor(actor) {
const GrabHelper = new Lang.Class({
Name: 'GrabHelper',
_init: function(owner, params) {
_init: function(owner) {
this._owner = owner;
this._modalParams = params;
this._grabStack = [];
@@ -167,7 +165,7 @@ const GrabHelper = new Lang.Class({
_takeModalGrab: function() {
let firstGrab = (this._modalCount == 0);
if (firstGrab) {
if (!Main.pushModal(this._owner, this._modalParams))
if (!Main.pushModal(this._owner))
return false;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));

View File

@@ -1129,7 +1129,7 @@ const LookingGlass = new Lang.Class({
if (this._open)
return;
if (!Main.pushModal(this._entry, { keybindingMode: Main.KeybindingMode.LOOKING_GLASS }))
if (!Main.pushModal(this._entry))
return;
this._notebook.selectIndex(0);

View File

@@ -20,7 +20,6 @@ const Keyboard = imports.ui.keyboard;
const MessageTray = imports.ui.messageTray;
const Overview = imports.ui.overview;
const Panel = imports.ui.panel;
const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog;
const Layout = imports.ui.layout;
const LookingGlass = imports.ui.lookingGlass;
@@ -40,18 +39,6 @@ const Util = imports.misc.util;
const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides';
const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
const KeybindingMode = {
NONE: 0, // block all keybindings
NORMAL: 1 << 0, // window mode
OVERVIEW: 1 << 1,
LOCK_SCREEN: 1 << 2,
UNLOCK_SCREEN: 1 << 3,
LOGIN_SCREEN: 1 << 4,
MESSAGE_TRAY: 1 << 5,
SYSTEM_MODAL: 1 << 6,
LOOKING_GLASS: 1 << 7
};
let componentManager = null;
let panel = null;
let overview = null;
@@ -68,7 +55,6 @@ let shellDBusService = null;
let shellMountOpDBusService = null;
let screenSaverDBus = null;
let modalCount = 0;
let keybindingMode = KeybindingMode.NORMAL;
let modalActorFocusStack = [];
let uiGroup = null;
let magnifier = null;
@@ -83,17 +69,7 @@ let _overridesSettings = null;
let background = null;
function _sessionUpdated() {
wm.setCustomKeybindingHandler('panel-main-menu',
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasOverview ? Lang.bind(overview, overview.toggle) : null);
wm.allowKeybinding('overlay-key', KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW);
wm.setCustomKeybindingHandler('panel-run-dialog',
KeybindingMode.NORMAL |
KeybindingMode.OVERVIEW,
sessionMode.hasRunDialog ? openRunDialog : null);
Meta.keybindings_set_custom_handler('internal-keybinding-panel-run-dialog', sessionMode.hasRunDialog ? Util.wrapKeybinding(openRunDialog, true) : null);
if (sessionMode.isGreeter)
screenShield.showDialog();
}
@@ -179,7 +155,15 @@ function start() {
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
false, -1, 1);
global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
Meta.keybindings_set_custom_handler('internal-keybinding-panel-main-menu', Util.wrapKeybinding(Lang.bind(overview, function() {
this.toggle();
return true;
}), true));
global.display.connect('overlay-key', Util.wrapKeybinding(Lang.bind(overview, function() {
this.toggle();
return true;
}), true));
sessionMode.connect('update', _sessionUpdated);
_sessionUpdated();
@@ -500,7 +484,7 @@ function isInModalStack(actor) {
/**
* pushModal:
* @actor: #ClutterActor which will be given keyboard focus
* @params: optional parameters
* @timestamp: optional timestamp
*
* Ensure we are in a mode where all keyboard and mouse input goes to
* the stage, and focus @actor. Multiple calls to this function act in
@@ -511,27 +495,21 @@ function isInModalStack(actor) {
* modal stack returns to this actor, reset the focus to the actor
* which was focused at the time pushModal() was invoked.
*
* @params may be used to provide the following parameters:
* - timestamp: used to associate the call with a specific user initiated
* event. If not provided then the value of
* global.get_current_time() is assumed.
* @timestamp is optionally used to associate the call with a specific user
* initiated event. If not provided then the value of
* global.get_current_time() is assumed.
*
* - options: Meta.ModalOptions flags to indicate that the pointer is
* already grabbed
*
* - keybindingMode: used to set the current Main.KeybindingMode to filter
* global keybindings; the default of NONE will filter
* out all keybindings
* @options: optional Meta.ModalOptions flags to indicate that the
* pointer is alrady grabbed
*
* Returns: true iff we successfully acquired a grab or already had one
*/
function pushModal(actor, params) {
params = Params.parse(params, { timestamp: global.get_current_time(),
options: 0,
keybindingMode: KeybindingMode.NONE });
function pushModal(actor, timestamp, options) {
if (timestamp == undefined)
timestamp = global.get_current_time();
if (modalCount == 0) {
if (!global.begin_modal(params.timestamp, params.options)) {
if (!global.begin_modal(timestamp, options ? options : 0)) {
log('pushModal: invocation of begin_modal failed');
return false;
}
@@ -558,10 +536,8 @@ function pushModal(actor, params) {
modalActorFocusStack.push({ actor: actor,
focus: curFocus,
destroyId: actorDestroyId,
focusDestroyId: curFocusDestroyId,
keybindingMode: keybindingMode });
focusDestroyId: curFocusDestroyId });
keybindingMode = params.keybindingMode;
global.stage.set_key_focus(actor);
return true;
}
@@ -588,7 +564,6 @@ function popModal(actor, timestamp) {
global.stage.set_key_focus(null);
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
keybindingMode = KeybindingMode.NORMAL;
throw new Error('incorrect pop');
}
@@ -601,7 +576,6 @@ function popModal(actor, timestamp) {
if (focusIndex == modalActorFocusStack.length - 1) {
if (record.focus)
record.focus.disconnect(record.focusDestroyId);
keybindingMode = record.keybindingMode;
global.stage.set_key_focus(record.focus);
} else {
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
@@ -611,7 +585,6 @@ function popModal(actor, timestamp) {
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus;
modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId;
modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode;
}
}
modalActorFocusStack.splice(focusIndex, 1);
@@ -622,7 +595,6 @@ function popModal(actor, timestamp) {
global.end_modal(timestamp);
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
Meta.enable_unredirect_for_screen(global.screen);
keybindingMode = KeybindingMode.NORMAL;
}
function createLookingGlass() {
@@ -637,6 +609,8 @@ function openRunDialog() {
runDialog = new RunDialog.RunDialog();
}
runDialog.open();
return true;
}
/**

View File

@@ -1453,8 +1453,7 @@ const MessageTray = new Lang.Class({
this.idleMonitor = new GnomeDesktop.IdleMonitor();
this._grabHelper = new GrabHelper.GrabHelper(this.actor,
{ keybindingMode: Main.KeybindingMode.MESSAGE_TRAY });
this._grabHelper = new GrabHelper.GrabHelper(this.actor);
this._grabHelper.addActor(this._summaryBoxPointer.actor);
this._grabHelper.addActor(this.actor);
if (Main.panel.statusArea.activities)
@@ -1518,20 +1517,14 @@ const MessageTray = new Lang.Class({
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
Main.wm.addKeybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this.toggleAndNavigate));
Main.wm.addKeybinding('focus-active-notification',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.MESSAGE_TRAY |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._expandActiveNotification));
global.display.add_keybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this.toggleAndNavigate));
global.display.add_keybinding('focus-active-notification',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this._expandActiveNotification));
this._summaryItems = [];
this._chatSummaryItemsCount = 0;
@@ -2317,18 +2310,6 @@ const MessageTray = new Lang.Class({
},
_hideNotification: function() {
// HACK!
// There seems to be a reentrancy issue in calling .ungrab() here,
// which causes _updateState to be called before _notificationState
// becomes HIDING. That hides the notification again, nullifying the
// object but not setting _notificationState (and that's the weird part)
// As then _notificationState is stuck into SHOWN but _notification
// is null, every new _updateState fails and the message tray is
// lost forever.
//
// See more at https://bugzilla.gnome.org/show_bug.cgi?id=683986
this._notificationState = State.HIDING;
this._grabHelper.ungrab({ actor: this._notification.actor });
if (this._idleMonitorBecameActiveId) {
@@ -2405,13 +2386,8 @@ const MessageTray = new Lang.Class({
if (this._notificationWidget.y < expandedY) {
this._notificationWidget.y = expandedY;
} else if (this._notification.y != expandedY) {
// Tween also opacity here, to override a possible tween that's
// currently hiding the notification. This will ensure that the
// notification is not removed when the onComplete handler for this
// one triggers.
this._tween(this._notificationWidget, '_notificationState', State.SHOWN,
{ y: expandedY,
opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});

View File

@@ -37,12 +37,10 @@ const ModalDialog = new Lang.Class({
params = Params.parse(params, { shellReactive: false,
styleClass: null,
parentActor: Main.uiGroup,
keybindingMode: Main.KeybindingMode.SYSTEM_MODAL,
shouldFadeIn: true });
this.state = State.CLOSED;
this._hasModal = false;
this._keybindingMode = params.keybindingMode;
this._shellReactive = params.shellReactive;
this._shouldFadeIn = params.shouldFadeIn;
@@ -228,7 +226,7 @@ const ModalDialog = new Lang.Class({
if (this.state == State.OPENED || this.state == State.OPENING)
return true;
if (!this.pushModal({ timestamp: timestamp }))
if (!this.pushModal(timestamp))
return false;
this._fadeOpen(onPrimary);
@@ -278,8 +276,7 @@ const ModalDialog = new Lang.Class({
pushModal: function (timestamp) {
if (this._hasModal)
return true;
if (!Main.pushModal(this._group, { timestamp: timestamp,
keybindingMode: this._keybindingMode }))
if (!Main.pushModal(this._group, timestamp))
return false;
this._hasModal = true;

View File

@@ -591,7 +591,7 @@ const Overview = new Lang.Class({
if (this._shown)
return;
// Do this manually instead of using _syncInputMode, to handle failure
if (!Main.pushModal(this._group, { keybindingMode: Main.KeybindingMode.OVERVIEW }))
if (!Main.pushModal(this._group))
return;
this._modal = true;
this._animateVisible();
@@ -742,8 +742,7 @@ const Overview = new Lang.Class({
if (this._shown) {
if (!this._modal) {
if (Main.pushModal(this._group,
{ keybindingMode: Main.KeybindingMode.OVERVIEW }))
if (Main.pushModal(this._group))
this._modal = true;
else
this.hide();

View File

@@ -82,34 +82,26 @@ const AnimatedIcon = new Lang.Class({
_init: function(name, size) {
this.actor = new St.Bin({ visible: false });
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibleNotify));
this._isLoaded = false;
this._isPlaying = false;
this._timeoutId = 0;
this._frame = 0;
this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size,
Lang.bind(this, this._animationsLoaded));
this._animations = St.TextureCache.get_default().load_sliced_image (global.datadir + '/theme/' + name, size, size);
this.actor.set_child(this._animations);
},
play: function() {
if (this._isLoaded && this._timeoutId == 0) {
if (this._frame == 0)
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
}
this._isPlaying = true;
},
stop: function() {
_disconnectTimeout: function() {
if (this._timeoutId > 0) {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
}
},
this._isPlaying = false;
_onVisibleNotify: function() {
if (this.actor.visible)
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
else
this._disconnectTimeout();
},
_showFrame: function(frame) {
@@ -129,17 +121,8 @@ const AnimatedIcon = new Lang.Class({
return true;
},
_animationsLoaded: function() {
this._isLoaded = true;
if (this._isPlaying) {
this._showFrame(0);
this._timeoutId = Mainloop.timeout_add(ANIMATED_ICON_UPDATE_TIMEOUT, Lang.bind(this, this._update));
}
},
_onDestroy: function() {
this.stop();
this._disconnectTimeout();
}
});
@@ -384,7 +367,6 @@ const AppMenuButton = new Lang.Class({
transition: "easeOutQuad",
onCompleteScope: this,
onComplete: function() {
this._spinner.stop();
this._spinner.actor.opacity = 255;
this._spinner.actor.hide();
}
@@ -394,7 +376,6 @@ const AppMenuButton = new Lang.Class({
startAnimation: function() {
this._stop = false;
this.actor.reactive = false;
this._spinner.play();
this._spinner.actor.show();
},

View File

@@ -31,13 +31,10 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
function loadRemoteSearchProviders(addProviderCallback) {
let loadState = { loadedProviders: [],
objectPaths: {},
numLoading: 0,
addProviderCallback: addProviderCallback };
function loadRemoteSearchProviders(addProviderCallback) {
let dataDirs = GLib.get_system_data_dirs();
let loadedProviders = {};
for (let i = 0; i < dataDirs.length; i++) {
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']);
let dir = Gio.file_new_for_path(path);
@@ -55,13 +52,12 @@ function loadRemoteSearchProviders(addProviderCallback) {
if (!exists)
return;
loadState.numLoading++;
loadRemoteSearchProvidersFromDir(dir, loadState);
loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback);
});
}
};
function loadRemoteSearchProvidersFromDir(dir, loadState) {
function loadRemoteSearchProvidersFromDir(dir, loadedProviders, addProviderCallback) {
let dirPath = dir.get_path();
FileUtils.listDirAsync(dir, Lang.bind(this, function(files) {
for (let i = 0; i < files.length; i++) {
@@ -83,7 +79,7 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
let busName = keyfile.get_string(group, 'BusName');
let objectPath = keyfile.get_string(group, 'ObjectPath');
if (loadState.objectPaths[objectPath])
if (loadedProviders[objectPath])
continue;
let appInfo = null;
@@ -95,82 +91,31 @@ function loadRemoteSearchProvidersFromDir(dir, loadState) {
continue;
}
remoteProvider = new RemoteSearchProvider(appInfo,
remoteProvider = new RemoteSearchProvider(appInfo.get_name(),
appInfo.get_icon(),
busName,
objectPath);
loadState.objectPaths[objectPath] = remoteProvider;
loadState.loadedProviders.push(remoteProvider);
loadedProviders[objectPath] = remoteProvider;
} catch(e) {
log('Failed to add search provider %s: %s'.format(path, e.toString()));
continue;
}
}
remoteProvidersDirLoaded(loadState);
addProviderCallback(remoteProvider);
}
}));
};
function remoteProvidersDirLoaded(loadState) {
loadState.numLoading--;
if (loadState.numLoading > 0)
return;
let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
let sortOrder = searchSettings.get_strv('sort-order');
let numSorted = sortOrder.length;
loadState.loadedProviders.sort(
function(providerA, providerB) {
let idxA, idxB;
let appIdA, appIdB;
appIdA = providerA.appInfo.get_id();
appIdB = providerB.appInfo.get_id();
idxA = sortOrder.indexOf(appIdA);
idxB = sortOrder.indexOf(appIdB);
// if no provider is found in the order, use alphabetical order
if ((idxA == -1) && (idxB == -1))
return GLib.utf8_collate(providerA.title, providerB.title);
if (numSorted > 1) {
// if providerA is the last, it goes after everything
if ((idxA + 1) == numSorted)
return 1;
// if providerB is the last, it goes after everything
else if ((idxB + 1) == numSorted)
return -1;
}
// if providerA isn't found, it's sorted after providerB
if (idxA == -1)
return 1;
// if providerB isn't found, it's sorted after providerA
if (idxB == -1)
return -1;
// finally, if both providers are found, return their order in the list
return (idxA - idxB);
});
loadState.loadedProviders.forEach(
function(provider) {
loadState.addProviderCallback(provider);
});
}
const RemoteSearchProvider = new Lang.Class({
Name: 'RemoteSearchProvider',
Extends: Search.SearchProvider,
_init: function(appInfo, dbusName, dbusPath) {
_init: function(title, icon, dbusName, dbusPath) {
this._proxy = new SearchProviderProxy(Gio.DBus.session,
dbusName, dbusPath, Lang.bind(this, this._onProxyConstructed));
this.parent(appInfo.get_name().toUpperCase(), appInfo, true);
this.parent(title.toUpperCase());
this._cancellable = new Gio.Cancellable();
},

View File

@@ -51,11 +51,10 @@ const SHORT_FADE_TIME = 0.3;
function sample(offx, offy) {
return 'texel += texture2D (sampler, tex_coord.st + pixel_step * ' +
'vec2 (' + offx + ',' + offy + '));\n'
'vec2 (' + offx + ',' + offy + ') * 2.0);\n'
}
const GLSL_BLUR_EFFECT_DECLARATIONS = ' \
uniform vec2 pixel_step;\n \
uniform float desaturation;\n \
vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \
vec4 texel;\n \
texel = texture2D (sampler, tex_coord.st);\n'
@@ -63,6 +62,7 @@ vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \
+ sample( 0.0, -1.0)
+ sample(+1.0, -1.0)
+ sample(-1.0, 0.0)
+ sample( 0.0, 0.0)
+ sample(+1.0, 0.0)
+ sample(-1.0, +1.0)
+ sample( 0.0, +1.0)
@@ -70,7 +70,7 @@ vec4 apply_blur(in sampler2D sampler, in vec2 tex_coord) {\n \
texel /= 9.0;\n \
return texel;\n \
}\n \
vec3 desaturate (const vec3 color)\n \
vec3 desaturate (const vec3 color, const float desaturation)\n \
{\n \
const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n \
vec3 gray = vec3 (dot (gray_conv, color));\n \
@@ -78,7 +78,7 @@ vec3 desaturate (const vec3 color)\n \
}';
const GLSL_BLUR_EFFECT_CODE = ' \
cogl_texel = apply_blur(cogl_sampler, cogl_tex_coord.st);\n \
cogl_texel.rgb = desaturate(cogl_texel.rgb);\n';
cogl_texel.rgb = desaturate(cogl_texel.rgb, 0.6);\n';
const Clock = new Lang.Class({
@@ -398,7 +398,6 @@ const ScreenShield = new Lang.Class({
Lang.bind(this, this._onLockScreenKeyRelease));
this._lockScreenGroup.connect('scroll-event',
Lang.bind(this, this._onLockScreenScroll));
Main.ctrlAltTabManager.addGroup(this._lockScreenGroup, _("Lock"), 'changes-prevent-symbolic');
this._lockScreenContents = new St.Widget({ layout_manager: new Clutter.BinLayout(),
name: 'lockScreenContents' });
@@ -409,12 +408,6 @@ const ScreenShield = new Lang.Class({
GLSL_BLUR_EFFECT_DECLARATIONS,
GLSL_BLUR_EFFECT_CODE,
true);
backgroundActor.set_uniform_float('desaturation',
1, 1, [0.6]);
backgroundActor.connect('notify::size', function(actor) {
actor.set_uniform_float('pixel_step', 2, 1, [1/actor.width, 1/actor.height]);
});
this._background = new St.Bin({ style_class: 'screen-shield-background',
child: backgroundActor });
this._lockScreenGroup.add_actor(this._background);
@@ -618,7 +611,7 @@ const ScreenShield = new Lang.Class({
}
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
Main.pushModal(this.actor);
this._isModal = true;
}
@@ -720,15 +713,13 @@ const ScreenShield = new Lang.Class({
_ensureUnlockDialog: function(onPrimary) {
if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog;
if (!constructor) {
this._dialog = new constructor(this._lockDialogGroup);
if (!this._dialog) {
// This session mode has no locking capabilities
this.unlock();
return;
}
this._dialog = new constructor(this._lockDialogGroup);
let time = global.get_current_time();
this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open(time, onPrimary)) {
@@ -927,7 +918,7 @@ const ScreenShield = new Lang.Class({
lock: function(animate) {
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
Main.pushModal(this.actor);
this._isModal = true;
}

View File

@@ -10,8 +10,6 @@ const Util = imports.misc.util;
const FileUtils = imports.misc.fileUtils;
const Main = imports.ui.main;
const SEARCH_PROVIDERS_SCHEMA = 'org.gnome.desktop.search-providers';
// Not currently referenced by the search API, but
// this enumeration can be useful for provider
// implementations.
@@ -76,11 +74,9 @@ const SearchResultDisplay = new Lang.Class({
const SearchProvider = new Lang.Class({
Name: 'SearchProvider',
_init: function(title, appInfo, isRemoteProvider) {
_init: function(title) {
this.title = title;
this.appInfo = appInfo;
this.searchSystem = null;
this.isRemoteProvider = !!isRemoteProvider;
},
/**
@@ -176,16 +172,12 @@ const SearchSystem = new Lang.Class({
_init: function() {
this._providers = [];
this._remoteProviders = [];
this.reset();
},
registerProvider: function (provider) {
provider.searchSystem = this;
this._providers.push(provider);
if (provider.isRemoteProvider)
this._remoteProviders.push(provider);
},
unregisterProvider: function (provider) {
@@ -194,20 +186,12 @@ const SearchSystem = new Lang.Class({
return;
provider.searchSystem = null;
this._providers.splice(index, 1);
let remoteIndex = this._remoteProviders.indexOf(provider);
if (remoteIndex != -1)
this._remoteProviders.splice(index, 1);
},
getProviders: function() {
return this._providers;
},
getRemoteProviders: function() {
return this._remoteProviders;
},
getTerms: function() {
return this._previousTerms;
},

View File

@@ -14,6 +14,7 @@ const _modes = {
showCalendarEvents: false,
allowSettings: false,
allowExtensions: false,
allowKeybindingsWhenModal: false,
hasRunDialog: false,
hasWorkspaces: false,
hasWindows: false,
@@ -31,11 +32,12 @@ const _modes = {
},
'gdm': {
allowKeybindingsWhenModal: true,
hasNotifications: true,
isGreeter: true,
isPrimary: true,
unlockDialog: imports.gdm.loginDialog.LoginDialog,
components: ['polkitAgent'],
components: ['polkitAgent', 'mediaKeysManager'],
panel: {
left: ['logo'],
center: ['dateMenu'],
@@ -48,7 +50,7 @@ const _modes = {
isLocked: true,
isGreeter: undefined,
unlockDialog: undefined,
components: ['polkitAgent', 'telepathyClient'],
components: ['polkitAgent', 'telepathyClient', 'mediaKeysManager'],
panel: {
left: ['userMenu'],
center: [],
@@ -59,7 +61,7 @@ const _modes = {
'unlock-dialog': {
isLocked: true,
unlockDialog: undefined,
components: ['polkitAgent', 'telepathyClient'],
components: ['polkitAgent', 'telepathyClient', 'mediaKeysManager'],
panel: {
left: ['userMenu'],
center: [],
@@ -69,7 +71,7 @@ const _modes = {
'initial-setup': {
isPrimary: true,
components: ['keyring'],
components: ['keyring', 'mediaKeysManager'],
panel: {
left: [],
center: ['dateMenu'],
@@ -89,8 +91,9 @@ const _modes = {
isLocked: false,
isPrimary: true,
unlockDialog: imports.ui.unlockDialog.UnlockDialog,
components: ['networkAgent', 'polkitAgent', 'telepathyClient',
'keyring', 'recorder', 'autorunManager', 'automountManager'],
components: ['networkAgent', 'polkitAgent', 'telepathyClient', 'keyring',
'recorder', 'autorunManager', 'automountManager',
'mediaKeysManager'],
panel: {
left: ['activities', 'appMenu'],
center: ['dateMenu'],

View File

@@ -27,7 +27,6 @@ const KEY_VISUAL_BELL = 'visual-bell';
const DESKTOP_INTERFACE_SCHEMA = 'org.gnome.desktop.interface';
const KEY_GTK_THEME = 'gtk-theme';
const KEY_ICON_THEME = 'icon-theme';
const KEY_WM_THEME = 'theme';
const KEY_TEXT_SCALING_FACTOR = 'text-scaling-factor';
const HIGH_CONTRAST_THEME = 'HighContrast';
@@ -39,8 +38,8 @@ const ATIndicator = new Lang.Class({
_init: function() {
this.parent('preferences-desktop-accessibility-symbolic', _("Accessibility"));
let highContrast = this._buildHCItem();
this.menu.addMenuItem(highContrast);
this._highContrast = this._buildHCItem();
this.menu.addMenuItem(this._highContrast);
let magnifier = this._buildItem(_("Zoom"), APPLICATIONS_SCHEMA,
'screen-magnifier-enabled');
@@ -102,35 +101,28 @@ const ATIndicator = new Lang.Class({
},
_buildHCItem: function() {
let interfaceSettings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA });
let wmSettings = new Gio.Settings({ schema: WM_SCHEMA });
let gtkTheme = interfaceSettings.get_string(KEY_GTK_THEME);
let iconTheme = interfaceSettings.get_string(KEY_ICON_THEME);
let wmTheme = wmSettings.get_string(KEY_WM_THEME);
let settings = new Gio.Settings({ schema: DESKTOP_INTERFACE_SCHEMA });
let gtkTheme = settings.get_string(KEY_GTK_THEME);
let iconTheme = settings.get_string(KEY_ICON_THEME);
let hasHC = (gtkTheme == HIGH_CONTRAST_THEME);
let highContrast = this._buildItemExtended(
_("High Contrast"),
hasHC,
interfaceSettings.is_writable(KEY_GTK_THEME) &&
interfaceSettings.is_writable(KEY_ICON_THEME) &&
wmSettings.is_writable(KEY_WM_THEME),
settings.is_writable(KEY_GTK_THEME) && settings.is_writable(KEY_ICON_THEME),
function (enabled) {
if (enabled) {
interfaceSettings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
interfaceSettings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
wmSettings.set_string(KEY_WM_THEME, HIGH_CONTRAST_THEME);
settings.set_string(KEY_GTK_THEME, HIGH_CONTRAST_THEME);
settings.set_string(KEY_ICON_THEME, HIGH_CONTRAST_THEME);
} else if(!hasHC) {
interfaceSettings.set_string(KEY_GTK_THEME, gtkTheme);
interfaceSettings.set_string(KEY_ICON_THEME, iconTheme);
wmSettings.set_string(KEY_WM_THEME, wmTheme);
settings.set_string(KEY_GTK_THEME, gtkTheme);
settings.set_string(KEY_ICON_THEME, iconTheme);
} else {
interfaceSettings.reset(KEY_GTK_THEME);
interfaceSettings.reset(KEY_ICON_THEME);
wmSettings.reset(KEY_WM_THEME);
settings.reset(KEY_GTK_THEME);
settings.reset(KEY_ICON_THEME);
}
});
interfaceSettings.connect('changed::' + KEY_GTK_THEME, function() {
let value = interfaceSettings.get_string(KEY_GTK_THEME);
settings.connect('changed::' + KEY_GTK_THEME, function() {
let value = settings.get_string(KEY_GTK_THEME);
if (value == HIGH_CONTRAST_THEME) {
highContrast.setToggleState(true);
} else {
@@ -138,16 +130,11 @@ const ATIndicator = new Lang.Class({
gtkTheme = value;
}
});
interfaceSettings.connect('changed::' + KEY_ICON_THEME, function() {
let value = interfaceSettings.get_string(KEY_ICON_THEME);
settings.connect('changed::' + KEY_ICON_THEME, function() {
let value = settings.get_string(KEY_ICON_THEME);
if (value != HIGH_CONTRAST_THEME)
iconTheme = value;
});
wmSettings.connect('changed::' + KEY_WM_THEME, function() {
let value = wmSettings.get_string(KEY_WM_THEME);
if (value != HIGH_CONTRAST_THEME)
wmTheme = value;
});
return highContrast;
},
@@ -172,5 +159,9 @@ const ATIndicator = new Lang.Class({
widget.setToggleState(active);
});
return widget;
}
},
toggleHighContrast: function() {
this._highContrast.toggle();
},
});

View File

@@ -239,6 +239,22 @@ const Indicator = new Lang.Class({
this._applet.send_to_address(device.bdaddr, device.alias);
}));
}
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_FILE_TRANSFER) {
item.menu.addAction(_("Browse Files..."), Lang.bind(this, function(event) {
this._applet.browse_address(device.bdaddr, event.get_time(),
Lang.bind(this, function(applet, result) {
try {
applet.browse_address_finish(result);
} catch (e) {
this._ensureSource();
this._source.notify(new MessageTray.Notification(this._source,
_("Bluetooth"),
_("Error browsing device"),
{ body: _("The requested device cannot be browsed, error is '%s'").format(e) }));
}
}));
}));
}
switch (device.type) {
case GnomeBluetoothApplet.Type.KEYBOARD:
@@ -353,7 +369,6 @@ const ConfirmNotification = new Lang.Class({
_init: function(source, applet, device_path, name, long_name, pin) {
this.parent(source,
_("Bluetooth"),
/* Translators: argument is the device short name */
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.setResident(true);
@@ -363,7 +378,6 @@ const ConfirmNotification = new Lang.Class({
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the PIN '%06d' matches the one on the device.").format(pin));
/* Translators: this is the verb, not the noun */
this.addButton('matches', _("Matches"));
this.addButton('does-not-match', _("Does not match"));

View File

@@ -66,7 +66,21 @@ const VolumeMenu = new Lang.Class({
this._onControlStateChanged();
},
scroll: function(direction) {
toggleMute: function(quiet) {
let muted = this._output.is_muted;
this._output.change_is_muted(!muted);
if (muted && !quiet)
this._notifyVolumeChange();
if (!muted)
return ['audio-volume-muted-symbolic', 0];
else
return [this._volumeToIcon(this._output.volume),
this._output.volume / this._volumeMax];
},
scroll: function(direction, quiet) {
let currentVolume = this._output.volume;
if (direction == Clutter.ScrollDirection.DOWN) {
@@ -85,7 +99,14 @@ const VolumeMenu = new Lang.Class({
this._output.push_volume();
}
this._notifyVolumeChange();
if (!quiet)
this._notifyVolumeChange();
if (this._output.is_muted)
return ['audio-volume-muted-symbolic', 0];
else
return [this._volumeToIcon(this._output.volume),
this._output.volume / this._volumeMax];
},
_onControlStateChanged: function() {
@@ -221,14 +242,14 @@ const Indicator = new Lang.Class({
this.parent('audio-volume-muted-symbolic', _("Volume"));
this._control = getMixerControl();
this._volumeMenu = new VolumeMenu(this._control);
this._volumeMenu.connect('icon-changed', Lang.bind(this, function(menu, icon) {
this.volumeMenu = new VolumeMenu(this._control);
this.volumeMenu.connect('icon-changed', Lang.bind(this, function(menu, icon) {
this._hasPulseAudio = (icon != null);
this.setIcon(icon);
this._syncVisibility();
}));
this.menu.addMenuItem(this._volumeMenu);
this.menu.addMenuItem(this.volumeMenu);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addSettingsAction(_("Sound Settings"), 'gnome-sound-panel.desktop');
@@ -242,6 +263,6 @@ const Indicator = new Lang.Class({
},
_onScrollEvent: function(actor, event) {
this._volumeMenu.scroll(event.get_scroll_direction());
}
this.volumeMenu.scroll(event.get_scroll_direction(), false);
},
});

View File

@@ -113,7 +113,6 @@ const UnlockDialog = new Lang.Class({
_init: function(parentActor) {
this.parent({ shellReactive: true,
styleClass: 'login-dialog',
keybindingMode: Main.KeybindingMode.UNLOCK_SCREEN,
parentActor: parentActor
});
@@ -200,8 +199,6 @@ const UnlockDialog = new Lang.Class({
return false;
}));
Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic');
this._idleMonitor = new GnomeDesktop.IdleMonitor();
this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
},

View File

@@ -572,6 +572,7 @@ const UserMenuButton = new Lang.Class({
this._updateHaveShutdown();
this._updateHaveSuspend();
this._updateHaveHibernate();
}));
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
Lang.bind(this, this._updateHaveShutdown));
@@ -655,6 +656,13 @@ const UserMenuButton = new Lang.Class({
}));
},
_updateHaveHibernate: function() {
this._loginManager.canHibernate(Lang.bind(this,
function(result) {
this._haveHibernate = result;
}));
},
_updateSuspendOrPowerOff: function() {
if (!this._suspendOrPowerOffItem)
return;
@@ -766,7 +774,7 @@ const UserMenuButton = new Lang.Class({
this._loginScreenItem = item;
item = new PopupMenu.PopupMenuItem(_("Log Out"));
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
item.connect('activate', Lang.bind(this, this.logOut));
this.menu.addMenuItem(item);
this._logoutItem = item;
@@ -835,7 +843,7 @@ const UserMenuButton = new Lang.Class({
Gdm.goto_login_session_sync(null);
},
_onQuitSessionActivate: function() {
logOut: function() {
Main.overview.hide();
this._session.LogoutRemote(0);
},
@@ -847,25 +855,60 @@ const UserMenuButton = new Lang.Class({
this._session.RebootRemote();
},
shutdown: function() {
this._session.ShutdownRemote();
},
suspend: function() {
if (!this._haveSuspend)
return false;
// Ensure we only suspend after locking the screen
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
this._loginManager.suspend();
}));
this.menu.close(BoxPointer.PopupAnimation.NONE);
Main.screenShield.lock(true);
} else {
this._loginManager.suspend();
}
return true;
},
hibernate: function() {
if (!this._haveHibernate)
return false;
// Ensure we only suspend after locking the screen
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
this._loginManager.hibernate();
}));
this.menu.close(BoxPointer.PopupAnimation.NONE);
Main.screenShield.lock(true);
} else {
this._loginManager.hibernate();
}
return true;
},
_onSuspendOrPowerOffActivate: function() {
Main.overview.hide();
if (this._haveShutdown &&
this._suspendOrPowerOffItem.state == PopupMenu.PopupAlternatingMenuItemState.DEFAULT) {
this._session.ShutdownRemote();
this.shutdown();
} else {
if (this._screenSaverSettings.get_boolean(LOCK_ENABLED_KEY)) {
let tmpId = Main.screenShield.connect('lock-screen-shown', Lang.bind(this, function() {
Main.screenShield.disconnect(tmpId);
this._loginManager.suspend();
}));
this.menu.close(BoxPointer.PopupAnimation.NONE);
Main.screenShield.lock(true);
} else {
this._loginManager.suspend();
}
this.suspend();
}
}
});

View File

@@ -94,11 +94,6 @@ const ViewSelector = new Lang.Class({
this._searchPage = this._addPage(this._searchResults.actor, this._entry,
_("Search"), 'edit-find-symbolic');
this._searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
this._searchSettings.connect('changed::disabled', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::disable-external', Lang.bind(this, this._reloadRemoteProviders));
this._searchSettings.connect('changed::sort-order', Lang.bind(this, this._reloadRemoteProviders));
// Default search providers
// Wanda comes obviously first
this.addSearchProvider(new Wanda.WandaSearchProvider());
@@ -149,17 +144,15 @@ const ViewSelector = new Lang.Class({
this.constrainHeight = new Clutter.BindConstraint({ source: this._pageArea,
coordinate: Clutter.BindCoordinate.HEIGHT });
Main.wm.addKeybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._toggleAppsPage));
global.display.add_keybinding('toggle-application-view',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this._showWithAppsPage));
},
_toggleAppsPage: function() {
_showWithAppsPage: function() {
Main.overview.show();
this._showAppsButton.checked = !this._showAppsButton.checked;
this._showAppsButton.set_checked(true);
},
show: function() {
@@ -440,32 +433,7 @@ const ViewSelector = new Lang.Class({
this._showPage(this._searchPage);
},
_shouldUseSearchProvider: function(provider) {
// the disable-external GSetting only affects remote providers
if (!provider.isRemoteProvider)
return true;
if (this._searchSettings.get_boolean('disable-external'))
return false;
let appId = provider.appInfo.get_id();
let disable = this._searchSettings.get_strv('disabled');
return disable.indexOf(appId) == -1;
},
_reloadRemoteProviders: function() {
// removeSearchProvider() modifies the provider list we iterate on,
// so make a copy first
let remoteProviders = this._searchSystem.getRemoteProviders().slice(0);
remoteProviders.forEach(Lang.bind(this, this.removeSearchProvider));
RemoteSearch.loadRemoteSearchProviders(Lang.bind(this, this.addSearchProvider));
},
addSearchProvider: function(provider) {
if (!this._shouldUseSearchProvider(provider))
return;
this._searchSystem.registerProvider(provider);
this._searchResults.createProviderMeta(provider);
},

View File

@@ -12,6 +12,7 @@ const AltTab = imports.ui.altTab;
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const WINDOW_ANIMATION_TIME = 0.25;
@@ -83,8 +84,6 @@ const WindowManager = new Lang.Class({
this._animationBlockCount = 0;
this._allowedKeybindings = {};
this._switchData = null;
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
@@ -101,66 +100,38 @@ const WindowManager = new Lang.Class({
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
this._workspaceSwitcherPopup = null;
this.setCustomKeybindingHandler('switch-to-workspace-left',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-right',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-up',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-to-workspace-down',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-left',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-right',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-up',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('move-to-workspace-down',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW,
Lang.bind(this, this._showWorkspaceSwitcher));
this.setCustomKeybindingHandler('switch-windows',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-windows-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-group-backward',
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._startAppSwitcher));
this.setCustomKeybindingHandler('switch-panels',
Main.KeybindingMode.NORMAL |
Main.KeybindingMode.OVERVIEW |
Main.KeybindingMode.LOCK_SCREEN |
Main.KeybindingMode.UNLOCK_SCREEN |
Main.KeybindingMode.LOGIN_SCREEN,
Lang.bind(this, this._startA11ySwitcher));
this.addKeybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Main.KeybindingMode.NORMAL,
Lang.bind(this, this._openAppMenu));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-to-workspace-left',
Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-to-workspace-right',
Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-to-workspace-up',
Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-to-workspace-down',
Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true));
Meta.keybindings_set_custom_handler('internal-keybinding-move-to-workspace-left',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-move-to-workspace-right',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-move-to-workspace-up',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-move-to-workspace-down',
Lang.bind(this, this._showWorkspaceSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-windows',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-group',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-windows-backward',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-group-backward',
Lang.bind(this, this._startAppSwitcher));
Meta.keybindings_set_custom_handler('internal-keybinding-switch-panels',
Util.wrapKeybinding(Lang.bind(this, this._startA11ySwitcher), true));
global.display.add_keybinding('open-application-menu',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
Meta.KeyBindingFlags.NONE,
Lang.bind(this, this._openAppMenu));
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
@@ -172,25 +143,6 @@ const WindowManager = new Lang.Class({
}));
},
setCustomKeybindingHandler: function(name, modes, handler) {
if (Meta.keybindings_set_custom_handler(name, handler))
this.allowKeybinding(name, modes);
},
addKeybinding: function(name, settings, flags, modes, handler) {
if (global.display.add_keybinding(name, settings, flags, handler))
this.allowKeybinding(name, modes);
},
removeKeybinding: function(name) {
if (global.display.remove_keybinding(name))
this.allowKeybinding(name, Main.KeybindingMode.NONE);
},
allowKeybinding: function(name, modes) {
this._allowedKeybindings[name] = modes;
},
blockAnimations: function() {
this._animationBlockCount++;
},
@@ -473,21 +425,6 @@ const WindowManager = new Lang.Class({
}
},
_filterKeybinding: function(shellwm, binding) {
if (Main.keybindingMode == Main.KeybindingMode.NONE)
return true;
// There's little sense in implementing a keybinding in mutter and
// not having it work in NORMAL mode; handle this case generically
// so we don't have to explicitly allow all builtin keybindings in
// NORMAL mode.
if (Main.keybindingMode == Main.KeybindingMode.NORMAL &&
binding.is_builtin())
return false;
return !(this._allowedKeybindings[binding.get_name()] & Main.keybindingMode);
},
_switchWorkspace : function(shellwm, from, to, direction) {
if (!this._shouldAnimate()) {
shellwm.completed_switch_workspace();
@@ -616,30 +553,32 @@ const WindowManager = new Lang.Class({
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
if (!tabPopup.show(backwards, binding.get_name(), binding.get_mask()))
tabPopup.destroy();
return true;
},
_startA11ySwitcher : function(display, screen, window, binding) {
let modifiers = binding.get_modifiers();
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
Main.ctrlAltTabManager.popup(backwards, binding.get_mask());
return true;
},
_openAppMenu : function(display, screen, window, event, binding) {
Main.panel.openAppMenu();
return true;
},
_showWorkspaceSwitcher : function(display, screen, window, binding) {
if (screen.n_workspaces == 1)
return;
return false;
let [action,,,direction] = binding.get_name().split('-');
let [,,action,,,direction] = binding.get_name().split('-');
let direction = Meta.MotionDirection[direction.toUpperCase()];
let newWs;
if (direction != Meta.MotionDirection.UP &&
direction != Meta.MotionDirection.DOWN)
return;
return false;
if (action == 'switch')
newWs = this.actionMoveWorkspace(direction);
@@ -655,6 +594,8 @@ const WindowManager = new Lang.Class({
}
this._workspaceSwitcherPopup.display(direction, newWs.index());
}
return true;
},
actionMoveWorkspace: function(direction) {

158
po/et.po
View File

@@ -13,8 +13,8 @@ msgstr ""
"Project-Id-Version: gnome-shell MASTER\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2012-11-16 18:27+0000\n"
"PO-Revision-Date: 2012-11-16 20:40+0300\n"
"POT-Creation-Date: 2012-09-22 22:24+0000\n"
"PO-Revision-Date: 2012-09-23 08:48+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
"Language-Team: Estonian <>\n"
"Language: et\n"
@@ -37,15 +37,6 @@ msgstr "Arvuti"
msgid "Show the message tray"
msgstr "Teateala näitamine"
msgid "Focus the active notification"
msgstr "Aktiivse märguande fokuseerimine"
msgid "Show all applications"
msgstr "Kõigi rakenduste kuvamine"
msgid "Open the application menu"
msgstr "Rakenduste menüü avamine"
msgid "GNOME Shell"
msgstr "GNOME Shell"
@@ -125,16 +116,6 @@ msgstr ""
"Kasutatakse kasutaja poolt viimati vahetult määratud kiirsuhtluse oleku "
"salvestamiseks. See väärtus pärineb GsmPresenceStatus nummerdusest."
msgid "Always show the 'Log out' menuitem in the user menu."
msgstr "Kasutajamenüüs näidatakse alati 'Logi välja' menüükirjet."
msgid ""
"This key overrides the automatic hiding of the 'Log out' menuitem in single-"
"user, single-session situations."
msgstr ""
"See võti keelab automaatse 'Logi välja' menüükirje peitmise, kui arvutis on "
"üks kasutaja ning avatud üks seanss."
msgid "Show the week date in the calendar"
msgstr "Kalendris näidatakse kuupäeva nädalavormingus"
@@ -147,25 +128,12 @@ msgstr "Rakenduste menüü avamise kiirklahv"
msgid "Keybinding to open the application menu."
msgstr "Kiirklahv rakenduste menüü avamiseks."
msgid "Keybinding to open the \"Show Applications\" view"
msgstr "\"Rakenduste vaate\" avamise kiirklahv"
msgid ""
"Keybinding to open the \"Show Applications\" view of the Activities Overview."
msgstr "\"Rakenduste vaate\" avamise kiirklahv tegevuste ülevaates."
msgid "Keybinding to toggle the visibility of the message tray"
msgstr "Teateala nähtavuse muutmise kiirklahv"
msgid "Keybinding to toggle the visibility of the message tray."
msgstr "Kiirklahv teateala nähtavuse muutmiseks."
msgid "Keybinding to focus the active notification"
msgstr "Aktiivse teate fokuseerimise kiirklahv"
msgid "Keybinding to focus the active notification."
msgstr "Aktiivse teate fokuseerimise kiirklahv."
msgid "Keybinding to toggle the screen recorder"
msgstr "Erkaanilindistaja lülitamise kiirklahv"
@@ -227,34 +195,6 @@ msgstr ""
"konteinervormingusse salvestades tuleks ka sellele vormingule vastav laiend "
"määrata."
msgid "Attach modal dialog to the parent window"
msgstr "Modaaldialoog kuulub vanemakna juurde"
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.mutter suhtes, kui kasutatakse GNOME "
"Shelli."
msgid "Arrangement of buttons on the titlebar"
msgstr "Nuppude järjekord tiitliribal"
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"See võti on ülimuslik võtme org.gnome.desktop.wm.preferences suhtes, kui "
"kasutatakse GNOME Shelli."
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr "Akende lohistamisel ekraani serva lubatakse serva paigutamine"
msgid "Workspaces are managed dynamically"
msgstr "Tööalasid hallatakse dünaamiliselt"
msgid "Workspaces only on primary monitor"
msgstr "Tööalad peamisel monitoril"
#, c-format
msgid "There was an error loading the preferences dialog for %s:"
msgstr "%s jaoks eelistuste dialoogi laadimisel esines viga:"
@@ -285,22 +225,9 @@ msgctxt "button"
msgid "Sign In"
msgstr "Logi sisse"
msgid "Next"
msgstr "Järgmine"
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Login Window"
msgstr "Sisselogimisaken"
#. Translators: accessible name of the power menu in the login screen
msgid "Power"
msgstr "Vool"
msgid "Suspend"
msgstr "Uinak"
@@ -510,6 +437,12 @@ msgstr "Parool: "
msgid "Key: "
msgstr "Võti: "
#. TTLS and PEAP are actually much more complicated, but this complication
#. is not visible here since we only care about phase2 authentication
#. (and don't even care of which one)
msgid "Username: "
msgstr "Kasutajanimi: "
msgid "Identity: "
msgstr "Identiteet: "
@@ -600,27 +533,24 @@ msgstr "Heli peale"
msgid "Mute"
msgstr "Heli maha"
#. Translators: this is a time format string followed by the word "Yesterday". i.e. "14:30 on Yesterday"
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#, no-c-format
msgid "<b>%H:%M</b> on Yesterday"
msgstr "Eile <b>%H:%M</b>"
msgid "Sent at <b>%X</b> on <b>%A</b>"
msgstr "Saadetud: <b>%A</b>, <b>%X</b>"
#. Translators: this is a time format string followed by a week day name. i.e. "14:30 on Monday
#. Translators: this is a time format in the style of "Wednesday, May 25",
#. shown when you get a chat message in the same year.
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>"
msgstr "<b>%H:%M</b>, <b>%A</b>"
msgid "Sent on <b>%A</b>, <b>%B %d</b>"
msgstr "Saadeti <b>%A</b>, <b>%B %d</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25",
#. shown when you get a chat message in the same year
#. Translators: this is a time format in the style of "Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year.
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b>"
#. Translators: this is a time format in the style of "14:30 on Wednesday, May 25, 2012",
#. shown when you get a chat message in a different year
#, no-c-format
msgid "<b>%H:%M</b> on <b>%A</b>, <b>%B</b> <b>%d</b>, %Y"
msgstr "<b>%H:%M</b>, <b>%A</b>, <b>%d. %B</b> %Y"
msgid "Sent on <b>%A</b>, <b>%B %d</b>, %Y"
msgstr "Saadeti <b>%A</b>, <b>%B %d</b>, %Y"
#. Translators: this is the other person changing their old IM name to their new
#. IM name.
@@ -657,6 +587,9 @@ msgstr "%s tahab alustada videokõnet"
msgid "Call from %s"
msgstr "%s helistab"
msgid "Reject"
msgstr "Lükka tagasi"
#. translators: this is a button label (verb), not a noun
msgid "Answer"
msgstr "Vasta"
@@ -964,11 +897,8 @@ msgstr "Ülemine riba"
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
msgid "Enter a Command"
msgstr "Palun sisesta käsk"
msgid "Close"
msgstr "Sulge"
msgid "Please enter a command:"
msgstr "Palun sisesta käsk:"
#. Translators: This is a time format for a date in
#. long format
@@ -1081,6 +1011,16 @@ msgstr "ühendumine..."
msgid "Send Files..."
msgstr "Failide saatmine..."
msgid "Browse Files..."
msgstr "Failide sirvimine..."
msgid "Error browsing device"
msgstr "Viga seadme sirvimisel"
#, c-format
msgid "The requested device cannot be browsed, error is '%s'"
msgstr "Küsitud seadet pole võimalik sirvida, viga on '%s'"
msgid "Keyboard Settings"
msgstr "Klaviatuurisätted"
@@ -1104,9 +1044,6 @@ msgstr "Luba alati"
msgid "Grant this time only"
msgstr "Luba ainult seekord"
msgid "Reject"
msgstr "Lükka tagasi"
#, c-format
msgid "Pairing confirmation for %s"
msgstr "Paardumise kinnitus seadmele %s"
@@ -1217,6 +1154,9 @@ msgstr "Juhtmeta"
msgid "Mobile broadband"
msgstr "Mobiiliühendus"
msgid "VPN Connections"
msgstr "VPN-ühendused"
msgid "Network Settings"
msgstr "Võrgusätted"
@@ -1334,17 +1274,20 @@ msgstr "Eemal"
msgid "Idle"
msgstr "Jõude"
msgid "Offline"
msgstr "Ühendamata"
msgid "Unavailable"
msgstr "Pole saadaval"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "Switch Session"
msgstr "Vaheta seanssi"
msgid "Notifications"
msgstr "Märguanded"
msgid "Settings"
msgstr "Sätted"
msgid "Switch User"
msgstr "Vaheta kasutajat"
msgid "System Settings"
msgstr "Süsteemi sätted"
msgid "Log Out"
msgstr "Logi välja"
@@ -1461,6 +1404,9 @@ msgstr "Kasutaja katkestas autentimisdialoogi"
#~ msgid "If true, display date in the clock, in addition to time."
#~ msgstr "Kui määratud, siis kuvatakse kellaaja kõrval ka kuupäeva."
#~ msgid "Offline"
#~ msgstr "Ühendamata"
#~ msgid "CONTACTS"
#~ msgstr "KONTAKTID"

551
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@@ -119,6 +119,7 @@ shell_public_headers_h = \
shell-network-agent.h \
shell-perf-log.h \
shell-screenshot.h \
shell-screen-grabber.h \
shell-slicer.h \
shell-stack.h \
shell-tp-client.h \
@@ -166,6 +167,7 @@ libgnome_shell_la_SOURCES = \
shell-polkit-authentication-agent.h \
shell-polkit-authentication-agent.c \
shell-screenshot.c \
shell-screen-grabber.c \
shell-secure-text-buffer.c \
shell-secure-text-buffer.h \
shell-slicer.c \
@@ -230,6 +232,8 @@ test_recorder_LDADD = $(TEST_SHELL_RECORDER_LIBS)
test_recorder_SOURCES = \
$(shell_recorder_sources) $(shell_recorder_private_sources) \
shell-screen-grabber.c \
shell-screen-grabber.h \
test-recorder.c
endif BUILD_RECORDER

View File

@@ -1035,6 +1035,8 @@ main (int argc,
name_owner_id = 0;
stdin_channel = NULL;
g_type_init ();
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL);

View File

@@ -72,9 +72,6 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin *plugin);
static gboolean gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
XEvent *event);
static gboolean gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding);
static const MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin);
@@ -129,9 +126,8 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
plugin_class->kill_window_effects = gnome_shell_plugin_kill_window_effects;
plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
plugin_class->xevent_filter = gnome_shell_plugin_xevent_filter;
plugin_class->plugin_info = gnome_shell_plugin_plugin_info;
}
static void
@@ -341,13 +337,6 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}
static gboolean
gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
MetaKeyBinding *binding)
{
return _shell_wm_filter_keybinding (get_shell_wm (), binding);
}
static const
MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
{

View File

@@ -38,7 +38,7 @@ extern GType gnome_shell_plugin_get_type (void);
#define OVERRIDES_SCHEMA "org.gnome.shell.overrides"
#define WM_NAME "GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell"
#define GNOME_WM_KEYBINDINGS "Metacity,Mutter,GNOME Shell"
static gboolean is_gdm_mode = FALSE;
static char *session_mode = NULL;

View File

@@ -14,9 +14,6 @@ struct _ShellRecorderSrc
GMutex mutex_data;
GMutex *mutex;
GstClock *clock;
GstClockTime last_frame_time;
GstCaps *caps;
GAsyncQueue *queue;
gboolean closed;
@@ -44,10 +41,6 @@ static void
shell_recorder_src_init (ShellRecorderSrc *src)
{
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
src->clock = gst_system_clock_obtain ();
src->last_frame_time = 0;
src->queue = g_async_queue_new ();
src->mutex = &src->mutex_data;
@@ -96,10 +89,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
return GST_FLOW_EOS;
buffer = g_async_queue_pop (src->queue);
if (src->last_frame_time == 0)
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
if (buffer == RECORDER_QUEUE_END)
{
/* Returning UNEXPECTED here will cause a EOS message to be sent */
@@ -111,9 +100,6 @@ shell_recorder_src_create (GstPushSrc *push_src,
- (int)(gst_buffer_get_size(buffer) / 1024));
*buffer_out = buffer;
GST_BUFFER_DURATION(*buffer_out) = GST_CLOCK_DIFF (src->last_frame_time, gst_clock_get_time (GST_CLOCK (src->clock)));
src->last_frame_time = gst_clock_get_time (GST_CLOCK (src->clock));
return GST_FLOW_OK;
}
@@ -155,8 +141,6 @@ shell_recorder_src_finalize (GObject *object)
g_mutex_clear (src->mutex);
gst_object_unref (src->clock);
G_OBJECT_CLASS (shell_recorder_src_parent_class)->finalize (object);
}

View File

@@ -12,10 +12,10 @@
#include <gst/gst.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "shell-recorder-src.h"
#include "shell-recorder.h"
#include "shell-screen-grabber.h"
#include <clutter/x11/clutter-x11.h>
#include <X11/extensions/Xfixes.h>
@@ -48,7 +48,7 @@ struct _ShellRecorder {
int stage_width;
int stage_height;
GdkScreen *gdk_screen;
ShellScreenGrabber *grabber;
gboolean have_pointer;
int pointer_x;
@@ -259,11 +259,11 @@ shell_recorder_init (ShellRecorder *recorder)
shell_recorder_src_register ();
recorder->gdk_screen = gdk_screen_get_default ();
recorder->recording_icon = create_recording_icon ();
recorder->memory_target = get_memory_target();
recorder->grabber = shell_screen_grabber_new ();
recorder->state = RECORDER_STATE_CLOSED;
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
}
@@ -283,6 +283,8 @@ shell_recorder_finalize (GObject *object)
recorder_set_pipeline (recorder, NULL);
recorder_set_file_template (recorder, NULL);
g_object_unref (recorder->grabber);
cogl_handle_unref (recorder->recording_icon);
G_OBJECT_CLASS (shell_recorder_parent_class)->finalize (object);
@@ -460,12 +462,6 @@ static void
recorder_draw_buffer_meter (ShellRecorder *recorder)
{
int fill_level;
GdkRectangle primary_monitor;
float rects[16];
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
recorder_update_memory_used (recorder, FALSE);
@@ -480,27 +476,14 @@ recorder_draw_buffer_meter (ShellRecorder *recorder)
fill_level = MIN (60, (recorder->memory_used * 60) / recorder->memory_target);
/* A hollow rectangle filled from the left to fill_level */
rects[0] = primary_monitor.x + primary_monitor.width - 64;
rects[1] = primary_monitor.y + primary_monitor.height - 10;
rects[2] = primary_monitor.x + primary_monitor.width - 2;
rects[3] = primary_monitor.y + primary_monitor.height - 9;
rects[4] = primary_monitor.x + primary_monitor.width - 64;
rects[5] = primary_monitor.y + primary_monitor.height - 9;
rects[6] = primary_monitor.x + primary_monitor.width - (63 - fill_level);
rects[7] = primary_monitor.y + primary_monitor.height - 3;
rects[8] = primary_monitor.x + primary_monitor.width - 3;
rects[9] = primary_monitor.y + primary_monitor.height - 9;
rects[10] = primary_monitor.x + primary_monitor.width - 2;
rects[11] = primary_monitor.y + primary_monitor.height - 3;
rects[12] = primary_monitor.x + primary_monitor.width - 64;
rects[13] = primary_monitor.y + primary_monitor.height - 3;
rects[14] = primary_monitor.x + primary_monitor.width - 2;
rects[15] = primary_monitor.y + primary_monitor.height - 2;
cogl_rectangles (rects, 4);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 10,
recorder->stage_width - 2, recorder->stage_height - 9);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 9,
recorder->stage_width - (63 - fill_level), recorder->stage_height - 3);
cogl_rectangle (recorder->stage_width - 3, recorder->stage_height - 9,
recorder->stage_width - 2, recorder->stage_height - 3);
cogl_rectangle (recorder->stage_width - 64, recorder->stage_height - 3,
recorder->stage_width - 2, recorder->stage_height - 2);
}
/* We want to time-stamp each frame based on the actual time it was
@@ -550,13 +533,8 @@ recorder_record_frame (ShellRecorder *recorder)
size = recorder->stage_width * recorder->stage_height * 4;
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
cogl_read_pixels (0, 0, /* x/y */
recorder->stage_width,
recorder->stage_height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
data = shell_screen_grabber_grab (recorder->grabber,
0, 0, recorder->stage_width, recorder->stage_height);
buffer = gst_buffer_new();
gst_buffer_insert_memory (buffer, -1,
@@ -584,17 +562,12 @@ recorder_on_stage_paint (ClutterActor *actor,
{
if (recorder->state == RECORDER_STATE_RECORDING)
{
GdkRectangle primary_monitor;
gdk_screen_get_monitor_geometry (recorder->gdk_screen,
gdk_screen_get_primary_monitor (recorder->gdk_screen),
&primary_monitor);
if (!recorder->only_paint)
recorder_record_frame (recorder);
cogl_set_source_texture (recorder->recording_icon);
cogl_rectangle (primary_monitor.x + primary_monitor.width - 32, primary_monitor.y + primary_monitor.height - 42,
primary_monitor.x + primary_monitor.width, primary_monitor.y + primary_monitor.height - 10);
cogl_rectangle (recorder->stage_width - 32, recorder->stage_height - 42,
recorder->stage_width, recorder->stage_height - 10);
}
if (recorder->state == RECORDER_STATE_RECORDING || recorder->memory_used != 0)
@@ -1730,6 +1703,9 @@ shell_recorder_close (ShellRecorder *recorder)
recorder->repaint_hook_id = 0;
}
recorder_remove_redraw_timeout (recorder);
recorder_close_pipeline (recorder);
recorder->state = RECORDER_STATE_CLOSED;
/* Release the refcount we took when we started recording */

210
src/shell-screen-grabber.c Normal file
View File

@@ -0,0 +1,210 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include <string.h>
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glext.h>
#include "shell-screen-grabber.h"
PFNGLBINDBUFFERARBPROC pf_glBindBufferARB;
PFNGLBUFFERDATAARBPROC pf_glBufferDataARB;
PFNGLDELETEBUFFERSARBPROC pf_glDeleteBuffersARB;
PFNGLGENBUFFERSARBPROC pf_glGenBuffersARB;
PFNGLMAPBUFFERARBPROC pf_glMapBufferARB;
PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB;
struct _ShellScreenGrabberClass
{
GObjectClass parent_class;
};
struct _ShellScreenGrabber
{
GObject parent_instance;
int have_pixel_buffers;
int have_pack_invert;
int width, height;
GLuint pixel_buffer;
};
G_DEFINE_TYPE(ShellScreenGrabber, shell_screen_grabber, G_TYPE_OBJECT);
static void
shell_screen_grabber_finalize (GObject *gobject)
{
ShellScreenGrabber *grabber = SHELL_SCREEN_GRABBER (gobject);
if (grabber->pixel_buffer != 0)
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
}
static void
shell_screen_grabber_class_init (ShellScreenGrabberClass *grabber_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (grabber_class);
gobject_class->finalize = shell_screen_grabber_finalize;
}
static void
shell_screen_grabber_init (ShellScreenGrabber *grabber)
{
grabber->have_pixel_buffers = -1;
grabber->width = -1;
grabber->height= -1;
grabber->pixel_buffer = 0;
}
ShellScreenGrabber *
shell_screen_grabber_new (void)
{
return g_object_new (SHELL_TYPE_SCREEN_GRABBER, NULL);
}
/**
* shell_screen_grabber_grab:
* x: X coordinate of the rectangle to grab
* y: Y coordinate of the rectangle to grab
* width: width of the rectangle to grab
* height: heigth of the rectangle to grab
*
* Grabs pixel data from a portion of the screen.
*
* Return value: buffer holding the grabbed data. The data is stored as 32-bit
* words with native-endian xRGB pixels (i.e., the same as CAIRO_FORMAT_RGB24)
* with no padding on the rows. So, the size of the buffer is width * height * 4
* bytes. Free with g_free().
**/
guchar *
shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height)
{
guchar *data;
gsize row_bytes;
gsize data_size;
row_bytes = width * 4;
data_size = row_bytes * height;
data = g_malloc (data_size);
if (grabber->have_pixel_buffers == -1)
{
const GLubyte* extensions = glGetString (GL_EXTENSIONS);
grabber->have_pixel_buffers = strstr ((const char *)extensions, "GL_EXT_pixel_buffer_object") != NULL;
grabber->have_pack_invert = strstr ((const char *)extensions, "GL_MESA_pack_invert") != NULL;
}
if (grabber->have_pixel_buffers)
{
GLubyte *mapped_data;
GLint old_swap_bytes, old_lsb_first, old_row_length, old_skip_pixels, old_skip_rows, old_alignment;
GLint old_pack_invert = GL_FALSE;
GLint vp_size[4];
guchar *src_row, *dest_row;
int i;
cogl_flush ();
if (pf_glBindBufferARB == NULL)
{
pf_glBindBufferARB = (PFNGLBINDBUFFERARBPROC) cogl_get_proc_address ("glBindBufferARB");
pf_glBufferDataARB = (PFNGLBUFFERDATAARBPROC) cogl_get_proc_address ("glBufferDataARB");
pf_glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) cogl_get_proc_address ("glDeleteBuffersARB");
pf_glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) cogl_get_proc_address ("glGenBuffersARB");
pf_glMapBufferARB = (PFNGLMAPBUFFERARBPROC) cogl_get_proc_address ("glMapBufferARB");
pf_glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC) cogl_get_proc_address ("glUnmapBufferARB");
}
glGetIntegerv (GL_PACK_SWAP_BYTES, &old_swap_bytes);
glGetIntegerv (GL_PACK_LSB_FIRST, &old_lsb_first);
glGetIntegerv (GL_PACK_ROW_LENGTH, &old_row_length);
glGetIntegerv (GL_PACK_SKIP_PIXELS, &old_skip_pixels);
glGetIntegerv (GL_PACK_SKIP_ROWS, &old_skip_rows);
glGetIntegerv (GL_PACK_ALIGNMENT, &old_alignment);
glPixelStorei (GL_PACK_SWAP_BYTES, GL_FALSE);
glPixelStorei (GL_PACK_LSB_FIRST, GL_FALSE);
glPixelStorei (GL_PACK_ROW_LENGTH, 0);
glPixelStorei (GL_PACK_SKIP_PIXELS, 0);
glPixelStorei (GL_PACK_SKIP_ROWS, 0);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
if (grabber->have_pack_invert)
{
glGetIntegerv (GL_PACK_INVERT_MESA, &old_pack_invert);
glPixelStorei (GL_PACK_INVERT_MESA, GL_FALSE);
}
if (grabber->pixel_buffer != 0 &&
(grabber->width != width ||
grabber->height != height))
{
pf_glDeleteBuffersARB (1, &grabber->pixel_buffer);
grabber->pixel_buffer = 0;
}
if (grabber->pixel_buffer == 0)
{
pf_glGenBuffersARB (1, &grabber->pixel_buffer);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
pf_glBufferDataARB (GL_PIXEL_PACK_BUFFER_ARB, data_size, 0, GL_STREAM_READ_ARB);
grabber->width = width;
grabber->height = height;
}
else
{
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, grabber->pixel_buffer);
}
/* In OpenGL, (x,y) specifies the bottom-left corner rather than the
* top-left */
glGetIntegerv (GL_VIEWPORT, vp_size);
y = vp_size[3] - (y + height);
glReadPixels (x, y, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
mapped_data = pf_glMapBufferARB (GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
src_row = mapped_data + (height - 1) * row_bytes;
dest_row = data;
for (i = 0; i < height; i++)
{
memcpy (dest_row, src_row, row_bytes);
src_row -= row_bytes;
dest_row += row_bytes;
}
pf_glUnmapBufferARB (GL_PIXEL_PACK_BUFFER_ARB);
pf_glBindBufferARB (GL_PIXEL_PACK_BUFFER_ARB, 0);
glPixelStorei (GL_PACK_SWAP_BYTES, old_swap_bytes);
glPixelStorei (GL_PACK_LSB_FIRST, old_lsb_first);
glPixelStorei (GL_PACK_ROW_LENGTH, old_row_length);
glPixelStorei (GL_PACK_SKIP_PIXELS, old_skip_pixels);
glPixelStorei (GL_PACK_SKIP_ROWS, old_skip_rows);
glPixelStorei (GL_PACK_ALIGNMENT, old_alignment);
if (grabber->have_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, old_pack_invert);
}
else
{
cogl_read_pixels (x, y,
width, height,
COGL_READ_PIXELS_COLOR_BUFFER,
CLUTTER_CAIRO_FORMAT_ARGB32,
data);
}
return data;
}

View File

@@ -0,0 +1,44 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef __SHELL_SCREEN_GRABBER_H__
#define __SHELL_SCREEN_GRABBER_H__
#include <glib-object.h>
G_BEGIN_DECLS
/**
* SECTION:shell-screen-grabber
* @short_description: Grab pixel data from the screen
*
* The #ShellScreenGrabber object is used to download previous drawn
* content to the screen. It internally uses pixel-buffer objects if
* available, otherwise falls back to cogl_read_pixels().
*
* If you are repeatedly grabbing images of the same size from the
* screen, it makes sense to create one #ShellScreenGrabber and keep
* it around. Otherwise, it's fine to simply create one as needed and
* then get rid of it.
*/
typedef struct _ShellScreenGrabber ShellScreenGrabber;
typedef struct _ShellScreenGrabberClass ShellScreenGrabberClass;
#define SHELL_TYPE_SCREEN_GRABBER (shell_screen_grabber_get_type ())
#define SHELL_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabber))
#define SHELL_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
#define SHELL_IS_SCREEN_GRABBER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_IS_SCREEN_GRABBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_SCREEN_GRABBER))
#define SHELL_SCREEN_GRABBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_SCREEN_GRABBER, ShellScreenGrabberClass))
GType shell_screen_grabber_get_type (void) G_GNUC_CONST;
ShellScreenGrabber *shell_screen_grabber_new (void);
guchar * shell_screen_grabber_grab (ShellScreenGrabber *grabber,
int x,
int y,
int width,
int height);
G_END_DECLS
#endif /* __SHELL_SCREEN_GRABBER_H__ */

View File

@@ -1,8 +1,5 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#define COGL_ENABLE_EXPERIMENTAL_API
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <X11/extensions/Xfixes.h>
#include <clutter/x11/clutter-x11.h>
#include <clutter/clutter.h>
@@ -13,6 +10,7 @@
#include <meta/meta-shaped-texture.h>
#include "shell-global.h"
#include "shell-screen-grabber.h"
#include "shell-screenshot.h"
struct _ShellScreenshotClass
@@ -92,33 +90,18 @@ do_grab_screenshot (_screenshot_data *screenshot_data,
int width,
int height)
{
CoglBitmap *bitmap;
ClutterBackend *backend;
CoglContext *context;
int stride;
ShellScreenGrabber *grabber;
static const cairo_user_data_key_t key;
guchar *data;
backend = clutter_get_default_backend ();
context = clutter_backend_get_cogl_context (backend);
grabber = shell_screen_grabber_new ();
data = shell_screen_grabber_grab (grabber, x, y, width, height);
g_object_unref (grabber);
screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
width, height);
data = cairo_image_surface_get_data (screenshot_data->image);
stride = cairo_image_surface_get_stride (screenshot_data->image);
bitmap = cogl_bitmap_new_for_data (context,
width,
height,
CLUTTER_CAIRO_FORMAT_ARGB32,
stride,
data);
cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (),
x, y,
COGL_READ_PIXELS_COLOR_BUFFER,
bitmap);
cogl_object_unref (bitmap);
screenshot_data->image = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
width, height, width * 4);
cairo_surface_set_user_data (screenshot_data->image, &key,
data, (cairo_destroy_func_t)g_free);
}
static void

View File

@@ -35,9 +35,6 @@ void _shell_wm_kill_window_effects (ShellWM *wm,
MetaWindowActor *actor);
void _shell_wm_kill_switch_workspace (ShellWM *wm);
gboolean _shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding);
G_END_DECLS
#endif /* __SHELL_WM_PRIVATE_H__ */

View File

@@ -26,7 +26,6 @@ enum
SWITCH_WORKSPACE,
KILL_SWITCH_WORKSPACE,
KILL_WINDOW_EFFECTS,
FILTER_KEYBINDING,
LAST_SIGNAL
};
@@ -116,14 +115,6 @@ shell_wm_class_init (ShellWMClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 1,
META_TYPE_WINDOW_ACTOR);
shell_wm_signals[FILTER_KEYBINDING] =
g_signal_new ("filter-keybinding",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
g_signal_accumulator_true_handled, NULL, NULL,
G_TYPE_BOOLEAN, 1,
META_TYPE_KEY_BINDING);
}
void
@@ -276,17 +267,6 @@ _shell_wm_destroy (ShellWM *wm,
g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
}
gboolean
_shell_wm_filter_keybinding (ShellWM *wm,
MetaKeyBinding *binding)
{
gboolean rv;
g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
return rv;
}
/**
* shell_wm_new:
* @plugin: the #MetaPlugin

View File

@@ -1073,8 +1073,6 @@ typedef struct {
gchar *path;
gint grid_width, grid_height;
ClutterActor *actor;
GFunc load_callback;
gpointer load_callback_data;
} AsyncImageData;
static void
@@ -1091,7 +1089,6 @@ on_sliced_image_loaded (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GObject *cache = source_object;
AsyncImageData *data = (AsyncImageData *)user_data;
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
GList *list;
@@ -1105,9 +1102,6 @@ on_sliced_image_loaded (GObject *source_object,
clutter_actor_hide (actor);
clutter_actor_add_child (data->actor, actor);
}
if (data->load_callback != NULL)
data->load_callback (cache, data->load_callback_data);
}
static void
@@ -1162,8 +1156,6 @@ load_sliced_image (GSimpleAsyncResult *result,
* @path: Path to a filename
* @grid_width: Width in pixels
* @grid_height: Height in pixels
* @load_callback: (scope async) (allow-none): Function called when the image is loaded, or %NULL
* @user_data: Data to pass to the load callback
*
* This function reads a single image file which contains multiple images internally.
* The image file will be divided using @grid_width and @grid_height;
@@ -1173,12 +1165,10 @@ load_sliced_image (GSimpleAsyncResult *result,
* Returns: (transfer none): A new #ClutterActor
*/
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height,
GFunc load_callback,
gpointer user_data)
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height)
{
AsyncImageData *data;
GSimpleAsyncResult *result;
@@ -1189,8 +1179,6 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
data->grid_height = grid_height;
data->path = g_strdup (path);
data->actor = actor;
data->load_callback = load_callback;
data->load_callback_data = user_data;
g_object_ref (G_OBJECT (actor));
result = g_simple_async_result_new (G_OBJECT (cache), on_sliced_image_loaded, data, st_texture_cache_load_sliced_image);

View File

@@ -69,12 +69,10 @@ GType st_texture_cache_get_type (void) G_GNUC_CONST;
StTextureCache* st_texture_cache_get_default (void);
ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height,
GFunc load_callback,
gpointer user_data);
st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path,
gint grid_width,
gint grid_height);
ClutterActor *st_texture_cache_bind_pixbuf_property (StTextureCache *cache,
GObject *object,

View File

@@ -31,9 +31,6 @@ struct _StThemeContext {
PangoFontDescription *font;
StThemeNode *root_node;
StTheme *theme;
/* set of StThemeNode */
GHashTable *nodes;
};
struct _StThemeContextClass {
@@ -69,8 +66,6 @@ st_theme_context_finalize (GObject *object)
(gpointer) st_theme_context_changed,
context);
if (context->nodes)
g_hash_table_unref (context->nodes);
if (context->root_node)
g_object_unref (context->root_node);
if (context->theme)
@@ -110,10 +105,6 @@ st_theme_context_init (StThemeContext *context)
"resolution-changed",
G_CALLBACK (st_theme_context_changed),
context);
context->nodes = g_hash_table_new_full ((GHashFunc) st_theme_node_hash,
(GEqualFunc) st_theme_node_equal,
g_object_unref, NULL);
}
/**
@@ -155,7 +146,6 @@ st_theme_context_changed (StThemeContext *context)
{
StThemeNode *old_root = context->root_node;
context->root_node = NULL;
g_hash_table_remove_all (context->nodes);
emit_changed (context);
@@ -309,27 +299,3 @@ st_theme_context_get_root_node (StThemeContext *context)
return context->root_node;
}
/**
* st_theme_context_intern_node:
* @context: a #StThemeContext
* @node: a #StThemeNode
*
* Return an existing node matching @node, or if that isn't possible,
* @node itself.
*
* Return value: (transfer none): a node with the same properties as @node
*/
StThemeNode *
st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node)
{
StThemeNode *mine = g_hash_table_lookup (context->nodes, node);
/* this might be node or not - it doesn't actually matter */
if (mine != NULL)
return mine;
g_hash_table_add (context->nodes, g_object_ref (node));
return node;
}

View File

@@ -62,9 +62,6 @@ const PangoFontDescription *st_theme_context_get_font (StThemeContext
StThemeNode * st_theme_context_get_root_node (StThemeContext *context);
StThemeNode * st_theme_context_intern_node (StThemeContext *context,
StThemeNode *node);
G_END_DECLS
#endif /* __ST_THEME_CONTEXT_H__ */

View File

@@ -1553,7 +1553,7 @@ st_theme_node_paint_borders (StThemeNode *node,
{
ClutterColor effective_border;
gboolean skip_corner_1, skip_corner_2;
float rects[16];
float x1, y1, x2, y2;
over (&border_color, &node->background_color, &effective_border);
alpha = paint_opacity * effective_border.alpha / 255;
@@ -1569,44 +1569,46 @@ st_theme_node_paint_borders (StThemeNode *node,
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_TOPRIGHT] > 0;
rects[0] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
rects[1] = 0;
rects[2] = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
rects[3] = border_width[ST_SIDE_TOP];
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT] : 0;
y1 = 0;
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_TOPRIGHT] : width;
y2 = border_width[ST_SIDE_TOP];
cogl_rectangle (x1, y1, x2, y2);
/* EAST */
skip_corner_1 = border_radius[ST_CORNER_TOPRIGHT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[4] = width - border_width[ST_SIDE_RIGHT];
rects[5] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT]
x1 = width - border_width[ST_SIDE_RIGHT];
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPRIGHT]
: border_width[ST_SIDE_TOP];
rects[6] = width;
rects[7] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
x2 = width;
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: height - border_width[ST_SIDE_BOTTOM];
cogl_rectangle (x1, y1, x2, y2);
/* SOUTH */
skip_corner_1 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMRIGHT] > 0;
rects[8] = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
rects[9] = height - border_width[ST_SIDE_BOTTOM];
rects[10] = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
x1 = skip_corner_1 ? max_width_radius[ST_CORNER_BOTTOMLEFT] : 0;
y1 = height - border_width[ST_SIDE_BOTTOM];
x2 = skip_corner_2 ? width - max_width_radius[ST_CORNER_BOTTOMRIGHT]
: width;
rects[11] = height;
y2 = height;
cogl_rectangle (x1, y1, x2, y2);
/* WEST */
skip_corner_1 = border_radius[ST_CORNER_TOPLEFT] > 0;
skip_corner_2 = border_radius[ST_CORNER_BOTTOMLEFT] > 0;
rects[12] = 0;
rects[13] = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT]
x1 = 0;
y1 = skip_corner_1 ? max_width_radius[ST_CORNER_TOPLEFT]
: border_width[ST_SIDE_TOP];
rects[14] = border_width[ST_SIDE_LEFT];
rects[15] = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
x2 = border_width[ST_SIDE_LEFT];
y2 = skip_corner_2 ? height - max_width_radius[ST_CORNER_BOTTOMLEFT]
: height - border_width[ST_SIDE_BOTTOM];
cogl_rectangles (rects, 4);
cogl_rectangle (x1, y1, x2, y2);
}
}
@@ -1873,7 +1875,6 @@ st_theme_node_paint_outline (StThemeNode *node,
{
float width, height;
int outline_width;
float rects[16];
ClutterColor outline_color, effective_outline;
width = box->x2 - box->x1;
@@ -1898,30 +1899,20 @@ st_theme_node_paint_outline (StThemeNode *node,
*/
/* NORTH */
rects[0] = -outline_width;
rects[1] = -outline_width;
rects[2] = width + outline_width;
rects[3] = 0;
cogl_rectangle (-outline_width, -outline_width,
width + outline_width, 0);
/* EAST */
rects[4] = width;
rects[5] = 0;
rects[6] = width + outline_width;
rects[7] = height;
cogl_rectangle (width, 0,
width + outline_width, height);
/* SOUTH */
rects[8] = -outline_width;
rects[9] = height;
rects[10] = width + outline_width;
rects[11] = height + outline_width;
cogl_rectangle (-outline_width, height,
width + outline_width, height + outline_width);
/* WEST */
rects[12] = -outline_width;
rects[13] = 0;
rects[14] = 0;
rects[15] = height;
cogl_rectangles (rects, 4);
cogl_rectangle (-outline_width, 0,
0, height);
}
void
@@ -2069,9 +2060,6 @@ st_theme_node_copy_cached_paint_state (StThemeNode *node,
g_return_if_fail (ST_IS_THEME_NODE (node));
g_return_if_fail (ST_IS_THEME_NODE (other));
if (node == other)
return;
/* Check omitted for speed: */
/* g_return_if_fail (st_theme_node_paint_equal (node, other)); */

View File

@@ -77,8 +77,8 @@ struct _StThemeNode {
GType element_type;
char *element_id;
GStrv element_classes;
GStrv pseudo_classes;
char *element_class;
char *pseudo_class;
char *inline_style;
CRDeclaration **properties;

View File

@@ -41,6 +41,7 @@ struct _StThemeNodeTransitionPrivate {
CoglHandle material;
ClutterAlpha *alpha;
ClutterTimeline *timeline;
guint timeline_completed_id;
@@ -90,6 +91,7 @@ st_theme_node_transition_new (StThemeNode *from_node,
transition->priv->old_theme_node = g_object_ref (from_node);
transition->priv->new_theme_node = g_object_ref (to_node);
transition->priv->alpha = clutter_alpha_new ();
transition->priv->timeline = clutter_timeline_new (duration);
transition->priv->timeline_completed_id =
@@ -99,7 +101,9 @@ st_theme_node_transition_new (StThemeNode *from_node,
g_signal_connect (transition->priv->timeline, "new-frame",
G_CALLBACK (on_timeline_new_frame), transition);
clutter_timeline_set_progress_mode (transition->priv->timeline, CLUTTER_EASE_IN_OUT_QUAD);
clutter_alpha_set_mode (transition->priv->alpha, CLUTTER_EASE_IN_OUT_QUAD);
clutter_alpha_set_timeline (transition->priv->alpha,
transition->priv->timeline);
clutter_timeline_start (transition->priv->timeline);
@@ -330,7 +334,7 @@ st_theme_node_transition_paint (StThemeNodeTransition *transition,
}
cogl_color_set_from_4f (&constant, 0., 0., 0.,
clutter_timeline_get_progress (priv->timeline));
clutter_alpha_get_alpha (priv->alpha));
cogl_material_set_layer_combine_constant (priv->material, 1, &constant);
cogl_material_set_color4ub (priv->material,
@@ -408,6 +412,12 @@ st_theme_node_transition_dispose (GObject *object)
priv->timeline_completed_id = 0;
priv->timeline_new_frame_id = 0;
if (priv->alpha)
{
g_object_unref (priv->alpha);
priv->alpha = NULL;
}
G_OBJECT_CLASS (st_theme_node_transition_parent_class)->dispose (object);
}
@@ -426,6 +436,8 @@ st_theme_node_transition_init (StThemeNodeTransition *transition)
transition->priv->new_offscreen = NULL;
transition->priv->needs_setup = TRUE;
transition->priv->alpha = NULL;
}
static void

View File

@@ -96,8 +96,8 @@ st_theme_node_finalize (GObject *object)
StThemeNode *node = ST_THEME_NODE (object);
g_free (node->element_id);
g_strfreev (node->element_classes);
g_strfreev (node->pseudo_classes);
g_free (node->element_class);
g_free (node->pseudo_class);
g_free (node->inline_style);
if (node->properties)
@@ -145,33 +145,6 @@ st_theme_node_finalize (GObject *object)
G_OBJECT_CLASS (st_theme_node_parent_class)->finalize (object);
}
static GStrv
split_on_whitespace (const gchar *s)
{
gchar *cur;
gchar *l;
gchar *temp;
GPtrArray *arr;
if (s == NULL)
return NULL;
arr = g_ptr_array_new ();
l = g_strdup (s);
cur = strtok_r (l, " \t\f\r\n", &temp);
while (cur != NULL)
{
g_ptr_array_add (arr, g_strdup (cur));
cur = strtok_r (NULL, " \t\f\r\n", &temp);
}
g_free (l);
g_ptr_array_add (arr, NULL);
return (GStrv) g_ptr_array_free (arr, FALSE);
}
/**
* st_theme_node_new:
* @context: the context representing global state for this themed tree
@@ -228,8 +201,8 @@ st_theme_node_new (StThemeContext *context,
node->element_type = element_type;
node->element_id = g_strdup (element_id);
node->element_classes = split_on_whitespace (element_class);
node->pseudo_classes = split_on_whitespace (pseudo_class);
node->element_class = g_strdup (element_class);
node->pseudo_class = g_strdup (pseudo_class);
node->inline_style = g_strdup (inline_style);
return node;
@@ -284,30 +257,20 @@ st_theme_node_get_element_id (StThemeNode *node)
return node->element_id;
}
/**
* st_theme_node_get_element_classes:
*
* Returns: (transfer none): the element's classes
*/
GStrv
st_theme_node_get_element_classes (StThemeNode *node)
const char *
st_theme_node_get_element_class (StThemeNode *node)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->element_classes;
return node->element_class;
}
/**
* st_theme_node_get_pseudo_classes:
*
* Returns: (transfer none): the element's pseudo-classes
*/
GStrv
st_theme_node_get_pseudo_classes (StThemeNode *node)
const char *
st_theme_node_get_pseudo_class (StThemeNode *node)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
return node->pseudo_classes;
return node->pseudo_class;
}
/**
@@ -341,91 +304,16 @@ gboolean
st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b)
{
g_return_val_if_fail (ST_IS_THEME_NODE (node_a), FALSE);
if (node_a == node_b)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (node_b), FALSE);
if (node_a->parent_node != node_b->parent_node ||
node_a->context != node_b->context ||
node_a->theme != node_b->theme ||
node_a->element_type != node_b->element_type ||
g_strcmp0 (node_a->element_id, node_b->element_id) ||
g_strcmp0 (node_a->inline_style, node_b->inline_style))
return FALSE;
if ((node_a->element_classes == NULL) != (node_b->element_classes == NULL))
return FALSE;
if ((node_a->pseudo_classes == NULL) != (node_b->pseudo_classes == NULL))
return FALSE;
if (node_a->element_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->element_classes[i],
node_b->element_classes[i]))
return FALSE;
if (node_a->element_classes[i] == NULL)
break;
}
}
if (node_a->pseudo_classes != NULL)
{
int i;
for (i = 0; ; i++)
{
if (g_strcmp0 (node_a->pseudo_classes[i],
node_b->pseudo_classes[i]))
return FALSE;
if (node_a->pseudo_classes[i] == NULL)
break;
}
}
return TRUE;
}
guint
st_theme_node_hash (StThemeNode *node)
{
guint hash = GPOINTER_TO_UINT (node->parent_node);
hash = hash * 33 + GPOINTER_TO_UINT (node->context);
hash = hash * 33 + GPOINTER_TO_UINT (node->theme);
hash = hash * 33 + ((guint) node->element_type);
if (node->element_id != NULL)
hash = hash * 33 + g_str_hash (node->element_id);
if (node->inline_style != NULL)
hash = hash * 33 + g_str_hash (node->inline_style);
if (node->element_classes != NULL)
{
gchar **it;
for (it = node->element_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
if (node->pseudo_classes != NULL)
{
gchar **it;
for (it = node->pseudo_classes; *it != NULL; it++)
hash = hash * 33 + g_str_hash (*it) + 1;
}
return hash;
return node_a->parent_node == node_b->parent_node &&
node_a->context == node_b->context &&
node_a->theme == node_b->theme &&
node_a->element_type == node_b->element_type &&
!g_strcmp0 (node_a->element_id, node_b->element_id) &&
!g_strcmp0 (node_a->element_class, node_b->element_class) &&
!g_strcmp0 (node_a->pseudo_class, node_b->pseudo_class) &&
!g_strcmp0 (node_a->inline_style, node_b->inline_style);
}
static void
@@ -3552,10 +3440,6 @@ st_theme_node_geometry_equal (StThemeNode *node,
StSide side;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_geometry (node);
@@ -3600,10 +3484,6 @@ st_theme_node_paint_equal (StThemeNode *node,
int i;
g_return_val_if_fail (ST_IS_THEME_NODE (node), FALSE);
if (node == other)
return TRUE;
g_return_val_if_fail (ST_IS_THEME_NODE (other), FALSE);
_st_theme_node_ensure_background (node);

View File

@@ -110,12 +110,11 @@ StThemeNode *st_theme_node_get_parent (StThemeNode *node);
StTheme *st_theme_node_get_theme (StThemeNode *node);
gboolean st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b);
guint st_theme_node_hash (StThemeNode *node);
GType st_theme_node_get_element_type (StThemeNode *node);
const char *st_theme_node_get_element_id (StThemeNode *node);
GStrv st_theme_node_get_element_classes (StThemeNode *node);
GStrv st_theme_node_get_pseudo_classes (StThemeNode *node);
const char *st_theme_node_get_element_class (StThemeNode *node);
const char *st_theme_node_get_pseudo_class (StThemeNode *node);
/* Generic getters ... these are not cached so are less efficient. The other
* reason for adding the more specific version is that we can handle the

View File

@@ -448,20 +448,28 @@ st_theme_new (const char *application_stylesheet,
static gboolean
string_in_list (GString *stryng,
GStrv list)
const char *list)
{
gchar **it;
char *cur;
char *l = g_strdup (list);
char *temp;
gboolean found = FALSE;
if (list == NULL)
return FALSE;
for (it = list; *it != NULL; it++)
cur = strtok_r (l, " \t\f\r\n", &temp);
while (cur != NULL)
{
if (!strqcmp (*it, stryng->str, stryng->len))
return TRUE;
if (!strqcmp (cur, stryng->str, stryng->len))
{
found = TRUE;
goto out;
}
cur = strtok_r (NULL, " \t\f\r\n", &temp);
}
return FALSE;
out:
g_free (l);
return found;
}
static gboolean
@@ -469,7 +477,7 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
CRAdditionalSel *a_add_sel,
StThemeNode *a_node)
{
GStrv node_pseudo_classes;
const char *node_pseudo_class;
g_return_val_if_fail (a_this
&& a_add_sel
@@ -479,10 +487,12 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
&& a_add_sel->content.pseudo->name->stryng->str
&& a_node, FALSE);
node_pseudo_classes = st_theme_node_get_pseudo_classes (a_node);
node_pseudo_class = st_theme_node_get_pseudo_class (a_node);
return string_in_list (a_add_sel->content.pseudo->name->stryng,
node_pseudo_classes);
if (node_pseudo_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.pseudo->name->stryng, node_pseudo_class);
}
/**
@@ -497,7 +507,7 @@ static gboolean
class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
StThemeNode *a_node)
{
GStrv element_classes;
const char *element_class;
g_return_val_if_fail (a_add_sel
&& a_add_sel->type == CLASS_ADD_SELECTOR
@@ -506,10 +516,11 @@ class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
&& a_add_sel->content.class_name->stryng->str
&& a_node, FALSE);
element_classes = st_theme_node_get_element_classes (a_node);
element_class = st_theme_node_get_element_class (a_node);
if (element_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.class_name->stryng,
element_classes);
return string_in_list (a_add_sel->content.class_name->stryng, element_class);
}
/*

View File

@@ -589,8 +589,6 @@ st_widget_get_theme_node (StWidget *widget)
if (priv->theme_node == NULL)
{
StThemeContext *context;
StThemeNode *tmp_node;
StThemeNode *parent_node = NULL;
ClutterStage *stage = NULL;
ClutterActor *parent;
@@ -631,20 +629,16 @@ st_widget_get_theme_node (StWidget *widget)
else
pseudo_class = direction_pseudo_class;
context = st_theme_context_get_for_stage (stage);
tmp_node = st_theme_node_new (context, parent_node, priv->theme,
G_OBJECT_TYPE (widget),
clutter_actor_get_name (CLUTTER_ACTOR (widget)),
priv->style_class,
pseudo_class,
priv->inline_style);
priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage),
parent_node, priv->theme,
G_OBJECT_TYPE (widget),
clutter_actor_get_name (CLUTTER_ACTOR (widget)),
priv->style_class,
pseudo_class,
priv->inline_style);
if (pseudo_class != direction_pseudo_class)
g_free (pseudo_class);
priv->theme_node = g_object_ref (st_theme_context_intern_node (context,
tmp_node));
g_object_unref (tmp_node);
}
return priv->theme_node;
@@ -1532,12 +1526,6 @@ st_widget_recompute_style (StWidget *widget,
int transition_duration;
gboolean paint_equal;
if (new_theme_node == old_theme_node)
{
widget->priv->is_style_dirty = FALSE;
return;
}
if (!old_theme_node ||
!st_theme_node_geometry_equal (old_theme_node, new_theme_node))
clutter_actor_queue_relayout ((ClutterActor *) widget);

View File

@@ -47,7 +47,7 @@ on_stage_realized (ClutterActor *stage,
gpointer data)
{
recorder = shell_recorder_new (CLUTTER_STAGE (stage));
shell_recorder_set_file_template (recorder, "test-recorder.webm");
shell_recorder_set_file_template (recorder, "test-recorder.ogg");
shell_recorder_record (recorder);
}