Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
fab02ae82f | |||
d43c5ec27a | |||
f7de35b852 | |||
cde0045851 | |||
f844613292 | |||
ff2e44de53 | |||
17aa8e0488 | |||
a33df9b046 | |||
c25f399f7c | |||
bd47d07fbc | |||
72282237e1 | |||
dfb44aa51d | |||
5516cad087 | |||
ab60c31629 | |||
52dd030087 | |||
98240c2857 | |||
65bfd6c6d2 | |||
1034e33c35 | |||
d7528b878c | |||
eb2e66c539 | |||
30e9a2a7d0 | |||
e842694316 | |||
b33d87a762 | |||
0ff3599d91 | |||
28d79a1235 | |||
522d21154b | |||
7c231916c1 | |||
a40bb67fc6 | |||
4c350b90c7 | |||
47dee22b05 | |||
13c0e575f6 | |||
ea8736b13a | |||
303d53e7f5 | |||
31295dfe83 | |||
69ea4553cb | |||
0d8d77356e | |||
8b78032248 | |||
ad277a563c | |||
db26fb201e | |||
9f00be50d6 | |||
77d21e53d0 | |||
ba0b4ba590 | |||
b9fc7a3050 | |||
aa053a906d |
31
NEWS
31
NEWS
@ -1,3 +1,34 @@
|
|||||||
|
3.8.2
|
||||||
|
=====
|
||||||
|
* Fix hotcorner regression in RTL locales [Jasper; #698884]
|
||||||
|
* Allow some keybindings to work while a top bar menu is open [Florian; #698938]
|
||||||
|
* Make open-app-menu keybinding a toggle action [Florian; #686756]
|
||||||
|
* ctrlAltTab: Use symbolic icons for desktop windows [Matthias; #697914]
|
||||||
|
* gdm: Fix regression where domain login hint not shown [Stef; #698200]
|
||||||
|
* Hide "Open Calendar" item when no calendar app is installed [Lionel; #697725]
|
||||||
|
* Update how branding appears on login screen [Florian; #694912, #699877]
|
||||||
|
* Allow OSD popups to grow if necessary [Marta; #696523]
|
||||||
|
* Fix offset of shadow offscreen rendering [Lionel; #698301]
|
||||||
|
* Fix insensitive button preventing empty keyring password [Stef; #696304]
|
||||||
|
* Allow cancelling keyring dialog between prompts [Stef; #682830]
|
||||||
|
* modalDialog: Show spinner while working [Stef; #684438]
|
||||||
|
* Provide a DBus API for screencasting [Florian; #696247]
|
||||||
|
* Implement app folder keynav and shortcuts [Florian; #695314]
|
||||||
|
* polkitAgent: Allow retrying after mistyped passwords [Stef; #684431]
|
||||||
|
* Add input purpose and hints to StEntry and StIMText [Daiki; #691392]
|
||||||
|
* Set input-purpose property for password entries [Rui; #700043]
|
||||||
|
* Misc fixes and cleanups [Jasper, Florian, Giovanni, Tim, Rui; #697203,
|
||||||
|
#698959, #696720, #698531, #676285, #698812, #699189]
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
Giovanni Campagna, Matthias Clasen, Lionel Landwerlin, Tim Lunn, Rui Matos,
|
||||||
|
Simon McVittie, Marta Milakovic, Florian Müllner, Jasper St. Pierre,
|
||||||
|
Daiki Ueno, Stef Walter
|
||||||
|
|
||||||
|
Translations:
|
||||||
|
Muhammet Kara [tr], Nik Kalach [ia], Žygimantas Beručka [lt],
|
||||||
|
Kjartan Maraas [nb]
|
||||||
|
|
||||||
3.8.1
|
3.8.1
|
||||||
=====
|
=====
|
||||||
* Clip window group during startup animation [Jasper; #696323]
|
* Clip window group during startup animation [Jasper; #696323]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AC_PREREQ(2.63)
|
AC_PREREQ(2.63)
|
||||||
AC_INIT([gnome-shell],[3.8.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
AC_INIT([gnome-shell],[3.8.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||||
@ -63,7 +63,7 @@ AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
|||||||
CLUTTER_MIN_VERSION=1.13.4
|
CLUTTER_MIN_VERSION=1.13.4
|
||||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
GOBJECT_INTROSPECTION_MIN_VERSION=0.10.1
|
||||||
GJS_MIN_VERSION=1.35.4
|
GJS_MIN_VERSION=1.35.4
|
||||||
MUTTER_MIN_VERSION=3.8.1
|
MUTTER_MIN_VERSION=3.8.2
|
||||||
GTK_MIN_VERSION=3.7.9
|
GTK_MIN_VERSION=3.7.9
|
||||||
GIO_MIN_VERSION=2.35.0
|
GIO_MIN_VERSION=2.35.0
|
||||||
LIBECAL_MIN_VERSION=3.5.3
|
LIBECAL_MIN_VERSION=3.5.3
|
||||||
|
@ -15,6 +15,7 @@ desktop_DATA = gnome-shell.desktop gnome-shell-extension-prefs.desktop
|
|||||||
|
|
||||||
introspectiondir = $(datadir)/dbus-1/interfaces
|
introspectiondir = $(datadir)/dbus-1/interfaces
|
||||||
introspection_DATA = \
|
introspection_DATA = \
|
||||||
|
org.gnome.Shell.Screencast.xml \
|
||||||
org.gnome.Shell.Screenshot.xml \
|
org.gnome.Shell.Screenshot.xml \
|
||||||
org.gnome.ShellSearchProvider.xml \
|
org.gnome.ShellSearchProvider.xml \
|
||||||
org.gnome.ShellSearchProvider2.xml
|
org.gnome.ShellSearchProvider2.xml
|
||||||
|
96
data/org.gnome.Shell.Screencast.xml
Normal file
96
data/org.gnome.Shell.Screencast.xml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<!DOCTYPE node PUBLIC
|
||||||
|
'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
|
||||||
|
'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
|
||||||
|
<node>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
org.gnome.Shell.Screencast:
|
||||||
|
@short_description: Screencast interface
|
||||||
|
|
||||||
|
The interface used to record screen contents.
|
||||||
|
-->
|
||||||
|
<interface name="org.gnome.Shell.Screencast">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Screencast:
|
||||||
|
@file_template: the template for the filename to use
|
||||||
|
@options: a dictionary of optional parameters
|
||||||
|
@success: whether the screencast was started successfully
|
||||||
|
@filename_used: the file where the screencast is being saved
|
||||||
|
|
||||||
|
Records a screencast of the whole screen and saves it
|
||||||
|
(by default) as webm video under a filename derived from
|
||||||
|
@file_template. The template is either a relative or absolute
|
||||||
|
filename which may contain some escape sequences - %d and %t
|
||||||
|
will be replaced by the start date and time of the recording.
|
||||||
|
If a relative name is used, the screencast will be saved in the
|
||||||
|
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
|
||||||
|
The actual filename of the saved video is returned in @filename_used.
|
||||||
|
The set of optional parameters in @options currently consists of:
|
||||||
|
'draw-cursor'(b): whether the cursor should be included in the
|
||||||
|
recording (true)
|
||||||
|
'framerate'(i): the number of frames per second that should be
|
||||||
|
recorded if possible (30)
|
||||||
|
'pipeline'(s): the GStreamer pipeline used to encode recordings
|
||||||
|
in gst-launch format; if not specified, the
|
||||||
|
recorder will produce vp8 (webm) video (unset)
|
||||||
|
-->
|
||||||
|
<method name="Screencast">
|
||||||
|
<arg type="s" direction="in" name="file_template"/>
|
||||||
|
<arg type="a{sv}" direction="in" name="options"/>
|
||||||
|
<arg type="b" direction="in" name="flash"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ScreencastArea:
|
||||||
|
@x: the X coordinate of the area to capture
|
||||||
|
@y: the Y coordinate of the area to capture
|
||||||
|
@width: the width of the area to capture
|
||||||
|
@height: the height of the area to capture
|
||||||
|
@file_template: the template for the filename to use
|
||||||
|
@options: a dictionary of optional parameters
|
||||||
|
@success: whether the screencast was started successfully
|
||||||
|
@filename_used: the file where the screencast is being saved
|
||||||
|
|
||||||
|
Records a screencast of the passed in area and saves it
|
||||||
|
(by default) as webm video under a filename derived from
|
||||||
|
@file_template. The template is either a relative or absolute
|
||||||
|
filename which may contain some escape sequences - %d and %t
|
||||||
|
will be replaced by the start date and time of the recording.
|
||||||
|
If a relative name is used, the screencast will be saved in the
|
||||||
|
$XDG_VIDEOS_DIR if it exists, or the home directory otherwise.
|
||||||
|
The actual filename of the saved video is returned in @filename_used.
|
||||||
|
The set of optional parameters in @options currently consists of:
|
||||||
|
'draw-cursor'(b): whether the cursor should be included in the
|
||||||
|
recording (true)
|
||||||
|
'framerate'(i): the number of frames per second that should be
|
||||||
|
recorded if possible (30)
|
||||||
|
'pipeline'(s): the GStreamer pipeline used to encode recordings
|
||||||
|
in gst-launch format; if not specified, the
|
||||||
|
recorder will produce vp8 (webm) video (unset)
|
||||||
|
-->
|
||||||
|
<method name="ScreencastArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
<arg type="s" direction="in" name="file_template"/>
|
||||||
|
<arg type="a{sv}" direction="in" name="options"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
StopScreencast:
|
||||||
|
@success: whether stopping the recording was successful
|
||||||
|
|
||||||
|
Stop the recording started by either Screencast or ScreencastArea.
|
||||||
|
-->
|
||||||
|
<method name="StopScreencast">
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
</node>
|
@ -2386,6 +2386,10 @@ StScrollBar StButton#vhandle:active {
|
|||||||
height: .75em;
|
height: .75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-dialog-logo-bin {
|
||||||
|
padding: 24px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.login-dialog .modal-dialog-button-box {
|
.login-dialog .modal-dialog-button-box {
|
||||||
spacing: 3px;
|
spacing: 3px;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/popupMenu.js \
|
ui/popupMenu.js \
|
||||||
ui/remoteSearch.js \
|
ui/remoteSearch.js \
|
||||||
ui/runDialog.js \
|
ui/runDialog.js \
|
||||||
|
ui/screencast.js \
|
||||||
ui/screenshot.js \
|
ui/screenshot.js \
|
||||||
ui/screenShield.js \
|
ui/screenShield.js \
|
||||||
ui/scripting.js \
|
ui/scripting.js \
|
||||||
|
@ -28,6 +28,7 @@ const Mainloop = imports.mainloop;
|
|||||||
const Meta = imports.gi.Meta;
|
const Meta = imports.gi.Meta;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Pango = imports.gi.Pango;
|
const Pango = imports.gi.Pango;
|
||||||
|
const Realmd = imports.gdm.realmd;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -39,7 +40,6 @@ const GdmUtil = imports.gdm.util;
|
|||||||
const Lightbox = imports.ui.lightbox;
|
const Lightbox = imports.ui.lightbox;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
const ModalDialog = imports.ui.modalDialog;
|
||||||
const Panel = imports.ui.panel;
|
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const UserMenu = imports.ui.userMenu;
|
const UserMenu = imports.ui.userMenu;
|
||||||
@ -48,44 +48,10 @@ const UserWidget = imports.ui.userWidget;
|
|||||||
const _FADE_ANIMATION_TIME = 0.25;
|
const _FADE_ANIMATION_TIME = 0.25;
|
||||||
const _SCROLL_ANIMATION_TIME = 0.5;
|
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||||
const _LOGO_ICON_HEIGHT = 16;
|
const _LOGO_ICON_HEIGHT = 48;
|
||||||
|
|
||||||
const WORK_SPINNER_ICON_SIZE = 24;
|
|
||||||
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
|
||||||
const WORK_SPINNER_ANIMATION_TIME = 0.3;
|
|
||||||
|
|
||||||
let _loginDialog = null;
|
let _loginDialog = null;
|
||||||
|
|
||||||
const LogoMenuButton = new Lang.Class({
|
|
||||||
Name: 'LogoMenuButton',
|
|
||||||
Extends: PanelMenu.Button,
|
|
||||||
|
|
||||||
_init: function() {
|
|
||||||
this.parent(0.0, null, true);
|
|
||||||
|
|
||||||
this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
|
||||||
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
||||||
Lang.bind(this, this._updateLogo));
|
|
||||||
|
|
||||||
this._iconBin = new St.Bin();
|
|
||||||
this.actor.add_actor(this._iconBin);
|
|
||||||
|
|
||||||
this._updateLogo();
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateLogo: function() {
|
|
||||||
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
|
||||||
let icon = null;
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
let file = Gio.file_new_for_path(path);
|
|
||||||
let cache = St.TextureCache.get_default();
|
|
||||||
icon = cache.load_uri_async(file.get_uri(), -1, _LOGO_ICON_HEIGHT);
|
|
||||||
}
|
|
||||||
this._iconBin.set_child(icon);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const UserListItem = new Lang.Class({
|
const UserListItem = new Lang.Class({
|
||||||
Name: 'UserListItem',
|
Name: 'UserListItem',
|
||||||
|
|
||||||
@ -552,6 +518,12 @@ const LoginDialog = new Lang.Class({
|
|||||||
Lang.bind(this, this._updateBanner));
|
Lang.bind(this, this._updateBanner));
|
||||||
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
||||||
Lang.bind(this, this._updateDisableUserList));
|
Lang.bind(this, this._updateDisableUserList));
|
||||||
|
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
||||||
|
Lang.bind(this, this._updateLogo));
|
||||||
|
|
||||||
|
this._textureCache = St.TextureCache.get_default();
|
||||||
|
this._textureCache.connect('texture-file-changed',
|
||||||
|
Lang.bind(this, this._updateLogoTexture));
|
||||||
|
|
||||||
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
@ -609,7 +581,6 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptBox.add(this._promptLoginHint);
|
this._promptBox.add(this._promptLoginHint);
|
||||||
|
|
||||||
this._signInButton = null;
|
this._signInButton = null;
|
||||||
this._workSpinner = null;
|
|
||||||
|
|
||||||
this._sessionList = new SessionList();
|
this._sessionList = new SessionList();
|
||||||
this._sessionList.connect('session-activated',
|
this._sessionList.connect('session-activated',
|
||||||
@ -644,6 +615,11 @@ const LoginDialog = new Lang.Class({
|
|||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
x_fill: true });
|
x_fill: true });
|
||||||
|
|
||||||
|
this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true });
|
||||||
|
this._logoBin.set_y_align(Clutter.ActorAlign.END);
|
||||||
|
this.backgroundStack.add_actor(this._logoBin);
|
||||||
|
this._updateLogo();
|
||||||
|
|
||||||
if (!this._userManager.is_loaded)
|
if (!this._userManager.is_loaded)
|
||||||
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
this._userManagerLoadedId = this._userManager.connect('notify::is-loaded',
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
@ -690,6 +666,24 @@ const LoginDialog = new Lang.Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_updateLogoTexture: function(cache, uri) {
|
||||||
|
if (this._logoFileUri != uri)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let icon = null;
|
||||||
|
if (this._logoFileUri)
|
||||||
|
icon = this._textureCache.load_uri_async(this._logoFileUri,
|
||||||
|
-1, _LOGO_ICON_HEIGHT);
|
||||||
|
this._logoBin.set_child(icon);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateLogo: function() {
|
||||||
|
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
||||||
|
|
||||||
|
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null;
|
||||||
|
this._updateLogoTexture(this._textureCache, this._logoFileUri);
|
||||||
|
},
|
||||||
|
|
||||||
_reset: function() {
|
_reset: function() {
|
||||||
this._userVerifier.clear();
|
this._userVerifier.clear();
|
||||||
|
|
||||||
@ -708,7 +702,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptEntry.text = '';
|
this._promptEntry.text = '';
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._setWorking(false);
|
this.setWorking(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDefaultSessionChanged: function(client, sessionId) {
|
_onDefaultSessionChanged: function(client, sessionId) {
|
||||||
@ -774,11 +768,6 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_prepareDialog: function(forSecret, hold) {
|
_prepareDialog: function(forSecret, hold) {
|
||||||
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
|
||||||
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
|
|
||||||
this._workSpinner.actor.opacity = 0;
|
|
||||||
this._workSpinner.actor.show();
|
|
||||||
|
|
||||||
this.buttonLayout.visible = true;
|
this.buttonLayout.visible = true;
|
||||||
this.clearButtons();
|
this.clearButtons();
|
||||||
|
|
||||||
@ -791,8 +780,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
this.buttonLayout.add(this._workSpinner.actor,
|
this.placeSpinner({ expand: false,
|
||||||
{ expand: false,
|
|
||||||
x_fill: false,
|
x_fill: false,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.END,
|
x_align: St.Align.END,
|
||||||
@ -849,7 +837,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptEntryActivateId = 0;
|
this._promptEntryActivateId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._setWorking(false);
|
this.setWorking(false);
|
||||||
this._promptBox.hide();
|
this._promptBox.hide();
|
||||||
this._promptLoginHint.hide();
|
this._promptLoginHint.hide();
|
||||||
|
|
||||||
@ -862,36 +850,9 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._promptLoginHint.hide();
|
this._promptLoginHint.hide();
|
||||||
|
|
||||||
this.clearButtons();
|
this.clearButtons();
|
||||||
this._workSpinner = null;
|
|
||||||
this._signInButton = null;
|
this._signInButton = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setWorking: function(working) {
|
|
||||||
if (!this._workSpinner)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (working) {
|
|
||||||
this._workSpinner.play();
|
|
||||||
Tweener.addTween(this._workSpinner.actor,
|
|
||||||
{ opacity: 255,
|
|
||||||
delay: WORK_SPINNER_ANIMATION_DELAY,
|
|
||||||
time: WORK_SPINNER_ANIMATION_TIME,
|
|
||||||
transition: 'linear'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Tweener.addTween(this._workSpinner.actor,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: WORK_SPINNER_ANIMATION_TIME,
|
|
||||||
transition: 'linear',
|
|
||||||
onCompleteScope: this,
|
|
||||||
onComplete: function() {
|
|
||||||
if (this._workSpinner)
|
|
||||||
this._workSpinner.stop();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_askQuestion: function(verifier, serviceName, question, passwordChar) {
|
_askQuestion: function(verifier, serviceName, question, passwordChar) {
|
||||||
this._promptLabel.set_text(question);
|
this._promptLabel.set_text(question);
|
||||||
|
|
||||||
@ -906,7 +867,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
function() {
|
function() {
|
||||||
let text = this._promptEntry.get_text();
|
let text = this._promptEntry.get_text();
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this._setWorking(true);
|
this.setWorking(true);
|
||||||
this._userVerifier.answerQuery(serviceName, text);
|
this._userVerifier.answerQuery(serviceName, text);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@ -914,17 +875,40 @@ const LoginDialog = new Lang.Class({
|
|||||||
return batch.run();
|
return batch.run();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_showRealmLoginHint: function(realmManager, hint) {
|
||||||
|
if (!hint)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hint = hint.replace(/%U/g, 'user');
|
||||||
|
hint = hint.replace(/%D/g, 'DOMAIN');
|
||||||
|
hint = hint.replace(/%[^UD]/g, '');
|
||||||
|
|
||||||
|
// Translators: this message is shown below the username entry field
|
||||||
|
// to clue the user in on how to login to the local network realm
|
||||||
|
this._showLoginHint(null, _("(e.g., user or %s)").format(hint));
|
||||||
|
},
|
||||||
|
|
||||||
_askForUsernameAndLogIn: function() {
|
_askForUsernameAndLogIn: function() {
|
||||||
this._promptLabel.set_text(_("Username: "));
|
this._promptLabel.set_text(_("Username: "));
|
||||||
this._promptEntry.set_text('');
|
this._promptEntry.set_text('');
|
||||||
this._promptEntry.clutter_text.set_password_char('');
|
this._promptEntry.clutter_text.set_password_char('');
|
||||||
|
|
||||||
|
let realmManager = new Realmd.Manager();
|
||||||
|
let signalId = realmManager.connect('login-format-changed',
|
||||||
|
Lang.bind(this, this._showRealmLoginHint));
|
||||||
|
this._showRealmLoginHint(realmManager.loginFormat);
|
||||||
|
|
||||||
let tasks = [this._showPrompt,
|
let tasks = [this._showPrompt,
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
let userName = this._promptEntry.get_text();
|
let userName = this._promptEntry.get_text();
|
||||||
this._promptEntry.reactive = false;
|
this._promptEntry.reactive = false;
|
||||||
return this._beginVerificationForUser(userName);
|
return this._beginVerificationForUser(userName);
|
||||||
|
},
|
||||||
|
|
||||||
|
function() {
|
||||||
|
realmManager.disconnect(signalId)
|
||||||
|
realmManager.release();
|
||||||
}];
|
}];
|
||||||
|
|
||||||
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
let batch = new Batch.ConsecutiveBatch(this, tasks);
|
||||||
|
@ -63,7 +63,7 @@ const Manager = new Lang.Class({
|
|||||||
Lang.bind(this, this._reloadRealms))
|
Lang.bind(this, this._reloadRealms))
|
||||||
this._realms = {};
|
this._realms = {};
|
||||||
|
|
||||||
this._aggregateProvider.connect('g-properties-changed',
|
this._signalId = this._aggregateProvider.connect('g-properties-changed',
|
||||||
Lang.bind(this, function(proxy, properties) {
|
Lang.bind(this, function(proxy, properties) {
|
||||||
if ('Realms' in properties.deep_unpack())
|
if ('Realms' in properties.deep_unpack())
|
||||||
this._reloadRealms();
|
this._reloadRealms();
|
||||||
@ -106,7 +106,7 @@ const Manager = new Lang.Class({
|
|||||||
realm.connect('g-properties-changed',
|
realm.connect('g-properties-changed',
|
||||||
Lang.bind(this, function(proxy, properties) {
|
Lang.bind(this, function(proxy, properties) {
|
||||||
if ('Configured' in properties.deep_unpack())
|
if ('Configured' in properties.deep_unpack())
|
||||||
this._reloadRealm();
|
this._reloadRealm(realm);
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -134,6 +134,18 @@ const Manager = new Lang.Class({
|
|||||||
this._updateLoginFormat();
|
this._updateLoginFormat();
|
||||||
|
|
||||||
return this._loginFormat;
|
return this._loginFormat;
|
||||||
|
},
|
||||||
|
|
||||||
|
release: function() {
|
||||||
|
Service(Gio.DBus.system,
|
||||||
|
'org.freedesktop.realmd',
|
||||||
|
'/org/freedesktop/realmd',
|
||||||
|
function(service) {
|
||||||
|
service.ReleaseRemote();
|
||||||
|
});
|
||||||
|
this._aggregateProvider.disconnect(this._signalId);
|
||||||
|
this._realms = { };
|
||||||
|
this._updateLoginFormat();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(Manager.prototype)
|
Signals.addSignalMethods(Manager.prototype)
|
||||||
|
@ -9,7 +9,6 @@ const Signals = imports.signals;
|
|||||||
|
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
const Fprint = imports.gdm.fingerprint;
|
const Fprint = imports.gdm.fingerprint;
|
||||||
const Realmd = imports.gdm.realmd;
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
@ -117,7 +116,6 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA });
|
||||||
|
|
||||||
this._fprintManager = new Fprint.FprintManager();
|
this._fprintManager = new Fprint.FprintManager();
|
||||||
this._realmManager = new Realmd.Manager();
|
|
||||||
this._messageQueue = [];
|
this._messageQueue = [];
|
||||||
this._messageQueueTimeoutId = 0;
|
this._messageQueueTimeoutId = 0;
|
||||||
this.hasPendingMessages = false;
|
this.hasPendingMessages = false;
|
||||||
@ -377,30 +375,11 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
this._queueMessage(problem, 'login-dialog-message-warning');
|
this._queueMessage(problem, 'login-dialog-message-warning');
|
||||||
},
|
},
|
||||||
|
|
||||||
_showRealmLoginHint: function() {
|
|
||||||
if (this._realmManager.loginFormat) {
|
|
||||||
let hint = this._realmManager.loginFormat;
|
|
||||||
|
|
||||||
hint = hint.replace(/%U/g, 'user');
|
|
||||||
hint = hint.replace(/%D/g, 'DOMAIN');
|
|
||||||
hint = hint.replace(/%[^UD]/g, '');
|
|
||||||
|
|
||||||
// Translators: this message is shown below the username entry field
|
|
||||||
// to clue the user in on how to login to the local network realm
|
|
||||||
this.emit('show-login-hint',
|
|
||||||
_("(e.g., user or %s)").format(hint));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onInfoQuery: function(client, serviceName, question) {
|
_onInfoQuery: function(client, serviceName, question) {
|
||||||
// We only expect questions to come from the main auth service
|
// We only expect questions to come from the main auth service
|
||||||
if (serviceName != PASSWORD_SERVICE_NAME)
|
if (serviceName != PASSWORD_SERVICE_NAME)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._showRealmLoginHint();
|
|
||||||
this._realmLoginHintSignalId = this._realmManager.connect('login-format-changed',
|
|
||||||
Lang.bind(this, this._showRealmLoginHint));
|
|
||||||
|
|
||||||
this.emit('ask-question', serviceName, question, '');
|
this.emit('ask-question', serviceName, question, '');
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -476,11 +455,6 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.emit('hide-login-hint');
|
this.emit('hide-login-hint');
|
||||||
|
|
||||||
if (this._realmLoginHintSignalId) {
|
|
||||||
this._realmManager.disconnect(this._realmLoginHintSignalId);
|
|
||||||
this._realmLoginHintSignalId = 0;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
||||||
|
@ -625,10 +625,24 @@ const AppFolderPopup = new Lang.Class({
|
|||||||
this._boxPointer.actor.bind_property('opacity', closeButton, 'opacity',
|
this._boxPointer.actor.bind_property('opacity', closeButton, 'opacity',
|
||||||
GObject.BindingFlags.SYNC_CREATE);
|
GObject.BindingFlags.SYNC_CREATE);
|
||||||
|
|
||||||
|
global.focus_manager.add_group(this.actor);
|
||||||
|
|
||||||
source.actor.connect('destroy', Lang.bind(this,
|
source.actor.connect('destroy', Lang.bind(this,
|
||||||
function() {
|
function() {
|
||||||
this.actor.destroy();
|
this.actor.destroy();
|
||||||
}));
|
}));
|
||||||
|
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyPress: function(actor, event) {
|
||||||
|
if (!this._isOpen)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (event.get_key_symbol() != Clutter.KEY_Escape)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.popdown();
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
@ -643,6 +657,7 @@ const AppFolderPopup = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
this.actor.show();
|
this.actor.show();
|
||||||
|
this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
|
|
||||||
this._boxPointer.setArrowActor(this._source.actor);
|
this._boxPointer.setArrowActor(this._source.actor);
|
||||||
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
|
this._boxPointer.show(BoxPointer.PopupAnimation.FADE |
|
||||||
|
@ -46,8 +46,10 @@ function addBackgroundMenu(actor) {
|
|||||||
clickAction.connect('long-press', function(action, actor, state) {
|
clickAction.connect('long-press', function(action, actor, state) {
|
||||||
if (state == Clutter.LongPressState.QUERY)
|
if (state == Clutter.LongPressState.QUERY)
|
||||||
return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
|
return action.get_button() == 1 && !actor._backgroundMenu.isOpen;
|
||||||
if (state == Clutter.LongPressState.ACTIVATE)
|
if (state == Clutter.LongPressState.ACTIVATE) {
|
||||||
openMenu();
|
openMenu();
|
||||||
|
actor._backgroundManager.ignoreRelease();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
clickAction.connect('clicked', function(action) {
|
clickAction.connect('clicked', function(action) {
|
||||||
|
@ -25,7 +25,7 @@ const KeyringDialog = new Lang.Class({
|
|||||||
this.prompt = new Shell.KeyringPrompt();
|
this.prompt = new Shell.KeyringPrompt();
|
||||||
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
|
this.prompt.connect('show-password', Lang.bind(this, this._onShowPassword));
|
||||||
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
|
this.prompt.connect('show-confirm', Lang.bind(this, this._onShowConfirm));
|
||||||
this.prompt.connect('hide-prompt', Lang.bind(this, this._onHidePrompt));
|
this.prompt.connect('prompt-close', Lang.bind(this, this._onHidePrompt));
|
||||||
|
|
||||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||||
vertical: false });
|
vertical: false });
|
||||||
@ -63,11 +63,17 @@ const KeyringDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._cancelButton = this.addButton({ label: '',
|
this._cancelButton = this.addButton({ label: '',
|
||||||
action: Lang.bind(this, this._onCancelButton),
|
action: Lang.bind(this, this._onCancelButton),
|
||||||
key: Clutter.Escape });
|
key: Clutter.Escape },
|
||||||
|
{ expand: true, x_fill: false, x_align: St.Align.START });
|
||||||
|
this.placeSpinner({ expand: false,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
this._continueButton = this.addButton({ label: '',
|
this._continueButton = this.addButton({ label: '',
|
||||||
action: Lang.bind(this, this._onContinueButton),
|
action: Lang.bind(this, this._onContinueButton),
|
||||||
default: true },
|
default: true },
|
||||||
{ expand: true, x_fill: false, x_align: St.Align.END });
|
{ expand: false, x_fill: false, x_align: St.Align.END });
|
||||||
|
|
||||||
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
this.prompt.bind_property('cancel-label', this._cancelButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||||
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
this.prompt.bind_property('continue-label', this._continueButton, 'label', GObject.BindingFlags.SYNC_CREATE);
|
||||||
@ -143,11 +149,19 @@ const KeyringDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateSensitivity: function(sensitive) {
|
_updateSensitivity: function(sensitive) {
|
||||||
|
if (this._passwordEntry) {
|
||||||
this._passwordEntry.reactive = sensitive;
|
this._passwordEntry.reactive = sensitive;
|
||||||
this._passwordEntry.clutter_text.editable = sensitive;
|
this._passwordEntry.clutter_text.editable = sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._confirmEntry) {
|
||||||
|
this._confirmEntry.reactive = sensitive;
|
||||||
|
this._confirmEntry.clutter_text.editable = sensitive;
|
||||||
|
}
|
||||||
|
|
||||||
this._continueButton.can_focus = sensitive;
|
this._continueButton.can_focus = sensitive;
|
||||||
this._continueButton.reactive = sensitive;
|
this._continueButton.reactive = sensitive;
|
||||||
|
this.setWorking(!sensitive);
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureOpen: function() {
|
_ensureOpen: function() {
|
||||||
|
@ -31,7 +31,6 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
this.message = message;
|
this.message = message;
|
||||||
this.userNames = userNames;
|
this.userNames = userNames;
|
||||||
this._wasDismissed = false;
|
this._wasDismissed = false;
|
||||||
this._completed = false;
|
|
||||||
|
|
||||||
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
let mainContentBox = new St.BoxLayout({ style_class: 'prompt-dialog-main-layout',
|
||||||
vertical: false });
|
vertical: false });
|
||||||
@ -161,26 +160,32 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._cancelButton = this.addButton({ label: _("Cancel"),
|
this._cancelButton = this.addButton({ label: _("Cancel"),
|
||||||
action: Lang.bind(this, this.cancel),
|
action: Lang.bind(this, this.cancel),
|
||||||
key: Clutter.Escape });
|
key: Clutter.Escape },
|
||||||
|
{ expand: true, x_fill: false, x_align: St.Align.START });
|
||||||
|
this.placeSpinner({ expand: false,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
this._okButton = this.addButton({ label: _("Authenticate"),
|
this._okButton = this.addButton({ label: _("Authenticate"),
|
||||||
action: Lang.bind(this, this._onAuthenticateButtonPressed),
|
action: Lang.bind(this, this._onAuthenticateButtonPressed),
|
||||||
default: true },
|
default: true },
|
||||||
{ expand: true, x_fill: false, x_align: St.Align.END });
|
{ expand: false, x_fill: false, x_align: St.Align.END });
|
||||||
|
|
||||||
this._doneEmitted = false;
|
this._doneEmitted = false;
|
||||||
|
|
||||||
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
|
this._identityToAuth = Polkit.UnixUser.new_for_name(userName);
|
||||||
this._cookie = cookie;
|
this._cookie = cookie;
|
||||||
|
},
|
||||||
|
|
||||||
|
performAuthentication: function() {
|
||||||
|
this.destroySession();
|
||||||
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
|
this._session = new PolkitAgent.Session({ identity: this._identityToAuth,
|
||||||
cookie: this._cookie });
|
cookie: this._cookie });
|
||||||
this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
|
this._session.connect('completed', Lang.bind(this, this._onSessionCompleted));
|
||||||
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
|
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
|
||||||
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
|
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
|
||||||
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
|
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
|
||||||
},
|
|
||||||
|
|
||||||
startAuthentication: function() {
|
|
||||||
this._session.initiate();
|
this._session.initiate();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -202,14 +207,14 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
log('polkitAuthenticationAgent: Failed to show modal dialog.' +
|
log('polkitAuthenticationAgent: Failed to show modal dialog.' +
|
||||||
' Dismissing authentication request for action-id ' + this.actionId +
|
' Dismissing authentication request for action-id ' + this.actionId +
|
||||||
' cookie ' + this._cookie);
|
' cookie ' + this._cookie);
|
||||||
this._emitDone(false, true);
|
this._emitDone(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_emitDone: function(keepVisible, dismissed) {
|
_emitDone: function(dismissed) {
|
||||||
if (!this._doneEmitted) {
|
if (!this._doneEmitted) {
|
||||||
this._doneEmitted = true;
|
this._doneEmitted = true;
|
||||||
this.emit('done', keepVisible, dismissed);
|
this.emit('done', dismissed);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -219,6 +224,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._okButton.can_focus = sensitive;
|
this._okButton.can_focus = sensitive;
|
||||||
this._okButton.reactive = sensitive;
|
this._okButton.reactive = sensitive;
|
||||||
|
this.setWorking(!sensitive);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onEntryActivate: function() {
|
_onEntryActivate: function() {
|
||||||
@ -237,12 +243,16 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onSessionCompleted: function(session, gainedAuthorization) {
|
_onSessionCompleted: function(session, gainedAuthorization) {
|
||||||
if (this._completed)
|
if (this._completed || this._doneEmitted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._completed = true;
|
this._completed = true;
|
||||||
|
|
||||||
if (!gainedAuthorization) {
|
/* Yay, all done */
|
||||||
|
if (gainedAuthorization) {
|
||||||
|
this._emitDone(false);
|
||||||
|
|
||||||
|
} else {
|
||||||
/* Unless we are showing an existing error message from the PAM
|
/* Unless we are showing an existing error message from the PAM
|
||||||
* module (the PAM module could be reporting the authentication
|
* module (the PAM module could be reporting the authentication
|
||||||
* error providing authentication-method specific information),
|
* error providing authentication-method specific information),
|
||||||
@ -258,8 +268,10 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
this._infoMessageLabel.hide();
|
this._infoMessageLabel.hide();
|
||||||
this._nullMessageLabel.hide();
|
this._nullMessageLabel.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try and authenticate again */
|
||||||
|
this.performAuthentication();
|
||||||
}
|
}
|
||||||
this._emitDone(!gainedAuthorization, false);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onSessionRequest: function(session, request, echo_on) {
|
_onSessionRequest: function(session, request, echo_on) {
|
||||||
@ -303,6 +315,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
if (this._session) {
|
if (this._session) {
|
||||||
if (!this._completed)
|
if (!this._completed)
|
||||||
this._session.cancel();
|
this._session.cancel();
|
||||||
|
this._completed = false;
|
||||||
this._session = null;
|
this._session = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -317,7 +330,7 @@ const AuthenticationDialog = new Lang.Class({
|
|||||||
cancel: function() {
|
cancel: function() {
|
||||||
this._wasDismissed = true;
|
this._wasDismissed = true;
|
||||||
this.close(global.get_current_time());
|
this.close(global.get_current_time());
|
||||||
this._emitDone(false, true);
|
this._emitDone(true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(AuthenticationDialog.prototype);
|
Signals.addSignalMethods(AuthenticationDialog.prototype);
|
||||||
@ -327,7 +340,6 @@ const AuthenticationAgent = new Lang.Class({
|
|||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
this._currentDialog = null;
|
this._currentDialog = null;
|
||||||
this._isCompleting = false;
|
|
||||||
this._handle = null;
|
this._handle = null;
|
||||||
this._native = new Shell.PolkitAuthenticationAgent();
|
this._native = new Shell.PolkitAuthenticationAgent();
|
||||||
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
|
this._native.connect('initiate', Lang.bind(this, this._onInitiate));
|
||||||
@ -364,45 +376,24 @@ const AuthenticationAgent = new Lang.Class({
|
|||||||
// discussion.
|
// discussion.
|
||||||
|
|
||||||
this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
|
this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
|
||||||
this._currentDialog.startAuthentication();
|
this._currentDialog.performAuthentication();
|
||||||
},
|
},
|
||||||
|
|
||||||
_onCancel: function(nativeAgent) {
|
_onCancel: function(nativeAgent) {
|
||||||
this._completeRequest(false, false);
|
this._completeRequest(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDialogDone: function(dialog, keepVisible, dismissed) {
|
_onDialogDone: function(dialog, dismissed) {
|
||||||
this._completeRequest(keepVisible, dismissed);
|
this._completeRequest(dismissed);
|
||||||
},
|
},
|
||||||
|
|
||||||
_reallyCompleteRequest: function(dismissed) {
|
_completeRequest: function(dismissed) {
|
||||||
this._currentDialog.close();
|
this._currentDialog.close();
|
||||||
this._currentDialog.destroySession();
|
this._currentDialog.destroySession();
|
||||||
this._currentDialog = null;
|
this._currentDialog = null;
|
||||||
this._isCompleting = false;
|
|
||||||
|
|
||||||
this._native.complete(dismissed)
|
this._native.complete(dismissed);
|
||||||
},
|
},
|
||||||
|
|
||||||
_completeRequest: function(keepVisible, wasDismissed) {
|
|
||||||
if (this._isCompleting)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._isCompleting = true;
|
|
||||||
|
|
||||||
if (keepVisible) {
|
|
||||||
// Give the user 2 seconds to read 'Authentication Failure' before
|
|
||||||
// dismissing the dialog
|
|
||||||
Mainloop.timeout_add(2000,
|
|
||||||
Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
this._reallyCompleteRequest(wasDismissed);
|
|
||||||
return false;
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
this._reallyCompleteRequest(wasDismissed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const Component = AuthenticationAgent;
|
const Component = AuthenticationAgent;
|
||||||
|
@ -89,19 +89,25 @@ const CtrlAltTabManager = new Lang.Class({
|
|||||||
let items = this._items.filter(function (item) { return item.proxy.mapped; });
|
let items = this._items.filter(function (item) { return item.proxy.mapped; });
|
||||||
|
|
||||||
// And add the windows metacity would show in its Ctrl-Alt-Tab list
|
// And add the windows metacity would show in its Ctrl-Alt-Tab list
|
||||||
if (!Main.overview.visible) {
|
if (Main.sessionMode.hasWindows && !Main.overview.visible) {
|
||||||
let screen = global.screen;
|
let screen = global.screen;
|
||||||
let display = screen.get_display();
|
let display = screen.get_display();
|
||||||
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
|
let windows = display.get_tab_list(Meta.TabList.DOCKS, screen, screen.get_active_workspace ());
|
||||||
let windowTracker = Shell.WindowTracker.get_default();
|
let windowTracker = Shell.WindowTracker.get_default();
|
||||||
let textureCache = St.TextureCache.get_default();
|
let textureCache = St.TextureCache.get_default();
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
let icon;
|
let icon = null;
|
||||||
|
let iconName = null;
|
||||||
|
if (windows[i].get_window_type () == Meta.WindowType.DESKTOP) {
|
||||||
|
iconName = 'video-display-symbolic';
|
||||||
|
} else {
|
||||||
let app = windowTracker.get_window_app(windows[i]);
|
let app = windowTracker.get_window_app(windows[i]);
|
||||||
if (app)
|
if (app)
|
||||||
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
icon = app.create_icon_texture(POPUP_APPICON_SIZE);
|
||||||
else
|
else
|
||||||
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
icon = textureCache.bind_pixbuf_property(windows[i], 'icon');
|
||||||
|
}
|
||||||
|
|
||||||
items.push({ name: windows[i].title,
|
items.push({ name: windows[i].title,
|
||||||
proxy: windows[i].get_compositor_private(),
|
proxy: windows[i].get_compositor_private(),
|
||||||
focusCallback: Lang.bind(windows[i],
|
focusCallback: Lang.bind(windows[i],
|
||||||
@ -109,6 +115,7 @@ const CtrlAltTabManager = new Lang.Class({
|
|||||||
Main.activateWindow(this, timestamp);
|
Main.activateWindow(this, timestamp);
|
||||||
}),
|
}),
|
||||||
iconActor: icon,
|
iconActor: icon,
|
||||||
|
iconName: iconName,
|
||||||
sortGroup: SortGroup.MIDDLE });
|
sortGroup: SortGroup.MIDDLE });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,6 @@ const DateMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
Shell.AppSystem.get_default().connect('installed-changed',
|
Shell.AppSystem.get_default().connect('installed-changed',
|
||||||
Lang.bind(this, this._appInstalledChanged));
|
Lang.bind(this, this._appInstalledChanged));
|
||||||
this._appInstalledChanged();
|
|
||||||
|
|
||||||
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
|
item = this.menu.addSettingsAction(_("Date & Time Settings"), 'gnome-datetime-panel.desktop');
|
||||||
if (item) {
|
if (item) {
|
||||||
@ -157,14 +156,16 @@ const DateMenuButton = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_appInstalledChanged: function() {
|
_appInstalledChanged: function() {
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
|
this._calendarApp = undefined;
|
||||||
this._openClocksItem.actor.visible = app !== null;
|
this._updateEventsVisibility();
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateEventsVisibility: function() {
|
_updateEventsVisibility: function() {
|
||||||
let visible = this._eventSource.hasCalendars;
|
let visible = this._eventSource.hasCalendars;
|
||||||
this._openCalendarItem.actor.visible = visible;
|
this._openCalendarItem.actor.visible = visible &&
|
||||||
this._openClocksItem.actor.visible = visible;
|
(this._getCalendarApp() != null);
|
||||||
|
this._openClocksItem.actor.visible = visible &&
|
||||||
|
(this._getClockApp() != null);
|
||||||
this._separator.visible = visible;
|
this._separator.visible = visible;
|
||||||
if (visible) {
|
if (visible) {
|
||||||
let alignment = 0.25;
|
let alignment = 0.25;
|
||||||
@ -217,18 +218,34 @@ const DateMenuButton = new Lang.Class({
|
|||||||
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
this._date.set_text(displayDate.toLocaleFormat(dateFormat));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getCalendarApp: function() {
|
||||||
|
if (this._calendarApp !== undefined)
|
||||||
|
return this._calendarApp;
|
||||||
|
|
||||||
|
let apps = Gio.AppInfo.get_recommended_for_type('text/calendar');
|
||||||
|
if (apps && (apps.length > 0))
|
||||||
|
this._calendarApp = apps[0];
|
||||||
|
else
|
||||||
|
this._calendarApp = null;
|
||||||
|
return this._calendarApp;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getClockApp: function() {
|
||||||
|
return Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
|
||||||
|
},
|
||||||
|
|
||||||
_onOpenCalendarActivate: function() {
|
_onOpenCalendarActivate: function() {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
|
|
||||||
let app = Gio.AppInfo.get_default_for_type('text/calendar', false);
|
let app = this._getCalendarApp();
|
||||||
if (app.get_id() == 'evolution')
|
if (app.get_id() == 'evolution.desktop')
|
||||||
app = Gio.DesktopAppInfo.new('evolution-calendar');
|
app = Gio.DesktopAppInfo.new('evolution-calendar.desktop');
|
||||||
app.launch([], global.create_app_launch_context());
|
app.launch([], global.create_app_launch_context());
|
||||||
},
|
},
|
||||||
|
|
||||||
_onOpenClocksActivate: function() {
|
_onOpenClocksActivate: function() {
|
||||||
this.menu.close();
|
this.menu.close();
|
||||||
let app = Shell.AppSystem.get_default().lookup_app('gnome-clocks.desktop');
|
let app = this._getClockApp();
|
||||||
app.activate();
|
app.activate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1092,12 +1092,21 @@ const HotCorner = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) {
|
||||||
|
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
|
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||||
|
directions: Meta.BarrierDirection.NEGATIVE_X });
|
||||||
|
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
|
x1: this._x - size, x2: this._x, y1: this._y, y2: this._y,
|
||||||
|
directions: Meta.BarrierDirection.POSITIVE_Y });
|
||||||
|
} else {
|
||||||
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
this._verticalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
x1: this._x, x2: this._x, y1: this._y, y2: this._y + size,
|
||||||
directions: Meta.BarrierDirection.POSITIVE_X });
|
directions: Meta.BarrierDirection.POSITIVE_X });
|
||||||
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
this._horizontalBarrier = new Meta.Barrier({ display: global.display,
|
||||||
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
|
x1: this._x, x2: this._x + size, y1: this._y, y2: this._y,
|
||||||
directions: Meta.BarrierDirection.POSITIVE_Y });
|
directions: Meta.BarrierDirection.POSITIVE_Y });
|
||||||
|
}
|
||||||
|
|
||||||
this._pressureBarrier.addBarrier(this._verticalBarrier);
|
this._pressureBarrier.addBarrier(this._verticalBarrier);
|
||||||
this._pressureBarrier.addBarrier(this._horizontalBarrier);
|
this._pressureBarrier.addBarrier(this._horizontalBarrier);
|
||||||
|
@ -22,6 +22,10 @@ const Tweener = imports.ui.tweener;
|
|||||||
const OPEN_AND_CLOSE_TIME = 0.1;
|
const OPEN_AND_CLOSE_TIME = 0.1;
|
||||||
const FADE_OUT_DIALOG_TIME = 1.0;
|
const FADE_OUT_DIALOG_TIME = 1.0;
|
||||||
|
|
||||||
|
const WORK_SPINNER_ICON_SIZE = 24;
|
||||||
|
const WORK_SPINNER_ANIMATION_DELAY = 1.0;
|
||||||
|
const WORK_SPINNER_ANIMATION_TIME = 0.3;
|
||||||
|
|
||||||
const State = {
|
const State = {
|
||||||
OPENED: 0,
|
OPENED: 0,
|
||||||
CLOSED: 1,
|
CLOSED: 1,
|
||||||
@ -65,7 +69,9 @@ const ModalDialog = new Lang.Class({
|
|||||||
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
this._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
|
||||||
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
|
this._group.connect('key-release-event', Lang.bind(this, this._onKeyReleaseEvent));
|
||||||
|
|
||||||
this._backgroundBin = new St.Bin();
|
this.backgroundStack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||||
|
this._backgroundBin = new St.Bin({ child: this.backgroundStack,
|
||||||
|
x_fill: true, y_fill: true });
|
||||||
this._monitorConstraint = new Layout.MonitorConstraint();
|
this._monitorConstraint = new Layout.MonitorConstraint();
|
||||||
this._backgroundBin.add_constraint(this._monitorConstraint);
|
this._backgroundBin.add_constraint(this._monitorConstraint);
|
||||||
this._group.add_actor(this._backgroundBin);
|
this._group.add_actor(this._backgroundBin);
|
||||||
@ -81,15 +87,10 @@ const ModalDialog = new Lang.Class({
|
|||||||
{ inhibitEvents: true });
|
{ inhibitEvents: true });
|
||||||
this._lightbox.highlight(this._backgroundBin);
|
this._lightbox.highlight(this._backgroundBin);
|
||||||
|
|
||||||
let stack = new Shell.Stack();
|
|
||||||
this._backgroundBin.child = stack;
|
|
||||||
|
|
||||||
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
this._eventBlocker = new Clutter.Actor({ reactive: true });
|
||||||
stack.add_actor(this._eventBlocker);
|
this.backgroundStack.add_actor(this._eventBlocker);
|
||||||
stack.add_actor(this.dialogLayout);
|
|
||||||
} else {
|
|
||||||
this._backgroundBin.child = this.dialogLayout;
|
|
||||||
}
|
}
|
||||||
|
this.backgroundStack.add_actor(this.dialogLayout);
|
||||||
|
|
||||||
|
|
||||||
this.contentLayout = new St.BoxLayout({ vertical: true });
|
this.contentLayout = new St.BoxLayout({ vertical: true });
|
||||||
@ -110,6 +111,8 @@ const ModalDialog = new Lang.Class({
|
|||||||
this._initialKeyFocus = this.dialogLayout;
|
this._initialKeyFocus = this.dialogLayout;
|
||||||
this._initialKeyFocusDestroyId = 0;
|
this._initialKeyFocusDestroyId = 0;
|
||||||
this._savedKeyFocus = null;
|
this._savedKeyFocus = null;
|
||||||
|
|
||||||
|
this._workSpinner = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -183,6 +186,44 @@ const ModalDialog = new Lang.Class({
|
|||||||
return button;
|
return button;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
placeSpinner: function(layoutInfo) {
|
||||||
|
/* This is here because of recursive imports */
|
||||||
|
const Panel = imports.ui.panel;
|
||||||
|
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
||||||
|
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
|
||||||
|
this._workSpinner.actor.opacity = 0;
|
||||||
|
this._workSpinner.actor.show();
|
||||||
|
|
||||||
|
this.buttonLayout.add(this._workSpinner.actor, layoutInfo);
|
||||||
|
},
|
||||||
|
|
||||||
|
setWorking: function(working) {
|
||||||
|
if (!this._workSpinner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Tweener.removeTweens(this._workSpinner.actor);
|
||||||
|
if (working) {
|
||||||
|
this._workSpinner.play();
|
||||||
|
Tweener.addTween(this._workSpinner.actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
delay: WORK_SPINNER_ANIMATION_DELAY,
|
||||||
|
time: WORK_SPINNER_ANIMATION_TIME,
|
||||||
|
transition: 'linear'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Tweener.addTween(this._workSpinner.actor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: WORK_SPINNER_ANIMATION_TIME,
|
||||||
|
transition: 'linear',
|
||||||
|
onCompleteScope: this,
|
||||||
|
onComplete: function() {
|
||||||
|
if (this._workSpinner)
|
||||||
|
this._workSpinner.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onKeyPressEvent: function(object, event) {
|
_onKeyPressEvent: function(object, event) {
|
||||||
this._pressedKey = event.get_key_symbol();
|
this._pressedKey = event.get_key_symbol();
|
||||||
},
|
},
|
||||||
|
@ -8,6 +8,7 @@ const Layout = imports.ui.layout;
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
|
|
||||||
const HIDE_TIMEOUT = 1500;
|
const HIDE_TIMEOUT = 1500;
|
||||||
const FADE_TIME = 0.1;
|
const FADE_TIME = 0.1;
|
||||||
@ -71,6 +72,7 @@ const OsdWindow = new Lang.Class({
|
|||||||
Name: 'OsdWindow',
|
Name: 'OsdWindow',
|
||||||
|
|
||||||
_init: function() {
|
_init: function() {
|
||||||
|
this._popupSize = 0;
|
||||||
this.actor = new St.Widget({ x_expand: true,
|
this.actor = new St.Widget({ x_expand: true,
|
||||||
y_expand: true,
|
y_expand: true,
|
||||||
x_align: Clutter.ActorAlign.CENTER,
|
x_align: Clutter.ActorAlign.CENTER,
|
||||||
@ -80,6 +82,15 @@ const OsdWindow = new Lang.Class({
|
|||||||
vertical: true });
|
vertical: true });
|
||||||
this.actor.add_actor(this._box);
|
this.actor.add_actor(this._box);
|
||||||
|
|
||||||
|
this._box.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
||||||
|
this._box.connect('notify::height', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._box.width = this._box.height;
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
|
||||||
this._icon = new St.Icon();
|
this._icon = new St.Icon();
|
||||||
this._box.add(this._icon, { expand: true });
|
this._box.add(this._icon, { expand: true });
|
||||||
|
|
||||||
@ -169,11 +180,25 @@ const OsdWindow = new Lang.Class({
|
|||||||
let scalew = monitor.width / 640.0;
|
let scalew = monitor.width / 640.0;
|
||||||
let scaleh = monitor.height / 480.0;
|
let scaleh = monitor.height / 480.0;
|
||||||
let scale = Math.min(scalew, scaleh);
|
let scale = Math.min(scalew, scaleh);
|
||||||
let size = 110 * Math.max(1, scale);
|
this._popupSize = 110 * Math.max(1, scale);
|
||||||
|
|
||||||
this._box.set_size(size, size);
|
|
||||||
this._box.translation_y = monitor.height / 4;
|
this._box.translation_y = monitor.height / 4;
|
||||||
|
this._icon.icon_size = this._popupSize / 2;
|
||||||
|
this._box.style_changed();
|
||||||
|
},
|
||||||
|
|
||||||
this._icon.icon_size = size / 2;
|
_onStyleChanged: function() {
|
||||||
|
let themeNode = this._box.get_theme_node();
|
||||||
|
let horizontalPadding = themeNode.get_horizontal_padding();
|
||||||
|
let verticalPadding = themeNode.get_vertical_padding();
|
||||||
|
let topBorder = themeNode.get_border_width(St.Side.TOP);
|
||||||
|
let bottomBorder = themeNode.get_border_width(St.Side.BOTTOM);
|
||||||
|
let leftBorder = themeNode.get_border_width(St.Side.LEFT);
|
||||||
|
let rightBorder = themeNode.get_border_width(St.Side.RIGHT);
|
||||||
|
|
||||||
|
let minWidth = this._popupSize - verticalPadding - leftBorder - rightBorder;
|
||||||
|
let minHeight = this._popupSize - horizontalPadding - topBorder - bottomBorder;
|
||||||
|
|
||||||
|
this._box.style = 'min-height: %dpx;'.format(Math.max(minWidth, minHeight));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -289,10 +289,10 @@ const AppMenuButton = new Lang.Class({
|
|||||||
this._visible = !Main.overview.visible;
|
this._visible = !Main.overview.visible;
|
||||||
if (!this._visible)
|
if (!this._visible)
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
Main.overview.connect('hiding', Lang.bind(this, function () {
|
this._overviewHidingId = Main.overview.connect('hiding', Lang.bind(this, function () {
|
||||||
this.show();
|
this.show();
|
||||||
}));
|
}));
|
||||||
Main.overview.connect('showing', Lang.bind(this, function () {
|
this._overviewShowingId = Main.overview.connect('showing', Lang.bind(this, function () {
|
||||||
this.hide();
|
this.hide();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -302,9 +302,11 @@ const AppMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
let tracker = Shell.WindowTracker.get_default();
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
let appSys = Shell.AppSystem.get_default();
|
let appSys = Shell.AppSystem.get_default();
|
||||||
|
this._focusAppNotifyId =
|
||||||
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
|
tracker.connect('notify::focus-app', Lang.bind(this, this._focusAppChanged));
|
||||||
|
this._appStateChangedSignalId =
|
||||||
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
appSys.connect('app-state-changed', Lang.bind(this, this._onAppStateChanged));
|
||||||
|
this._switchWorkspaceNotifyId =
|
||||||
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
|
global.window_manager.connect('switch-workspace', Lang.bind(this, this._sync));
|
||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
@ -637,6 +639,33 @@ const AppMenuButton = new Lang.Class({
|
|||||||
|
|
||||||
this.setMenu(menu);
|
this.setMenu(menu);
|
||||||
this._menuManager.addMenu(menu);
|
this._menuManager.addMenu(menu);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
if (this._appStateChangedSignalId > 0) {
|
||||||
|
let appSys = Shell.AppSystem.get_default();
|
||||||
|
appSys.disconnect(this._appStateChangedSignalId);
|
||||||
|
this._appStateChangedSignalId = 0;
|
||||||
|
}
|
||||||
|
if (this._focusAppNotifyId > 0) {
|
||||||
|
let tracker = Shell.WindowTracker.get_default();
|
||||||
|
tracker.disconnect(this._focusAppNotifyId);
|
||||||
|
this._focusAppNotifyId = 0;
|
||||||
|
}
|
||||||
|
if (this._overviewHidingId > 0) {
|
||||||
|
Main.overview.disconnect(this._overviewHidingId);
|
||||||
|
this._overviewHidingId = 0;
|
||||||
|
}
|
||||||
|
if (this._overviewShowingId > 0) {
|
||||||
|
Main.overview.disconnect(this._overviewShowingId);
|
||||||
|
this._overviewShowingId = 0;
|
||||||
|
}
|
||||||
|
if (this._switchWorkspaceNotifyId > 0) {
|
||||||
|
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||||
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -894,7 +923,6 @@ const PANEL_ITEM_IMPLEMENTATIONS = {
|
|||||||
'volume': imports.ui.status.volume.Indicator,
|
'volume': imports.ui.status.volume.Indicator,
|
||||||
'battery': imports.ui.status.power.Indicator,
|
'battery': imports.ui.status.power.Indicator,
|
||||||
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
|
||||||
'logo': imports.gdm.loginDialog.LogoMenuButton,
|
|
||||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||||
'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
|
'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
|
||||||
'userMenu': imports.ui.userMenu.UserMenuButton
|
'userMenu': imports.ui.userMenu.UserMenuButton
|
||||||
@ -923,7 +951,7 @@ const Panel = new Lang.Class({
|
|||||||
|
|
||||||
this.statusArea = {};
|
this.statusArea = {};
|
||||||
|
|
||||||
this.menuManager = new PopupMenu.PopupMenuManager(this);
|
this.menuManager = new PopupMenu.PopupMenuManager(this, { keybindingMode: Shell.KeyBindingMode.TOPBAR_POPUP });
|
||||||
|
|
||||||
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
|
||||||
this.actor.add_actor(this._leftBox);
|
this.actor.add_actor(this._leftBox);
|
||||||
@ -1077,16 +1105,17 @@ const Panel = new Lang.Class({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
openAppMenu: function() {
|
toggleAppMenu: function() {
|
||||||
let indicator = this.statusArea.appMenu;
|
let indicator = this.statusArea.appMenu;
|
||||||
if (!indicator) // appMenu not supported by current session mode
|
if (!indicator) // appMenu not supported by current session mode
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let menu = indicator.menu;
|
let menu = indicator.menu;
|
||||||
if (!indicator.actor.reactive || menu.isOpen)
|
if (!indicator.actor.reactive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu.open();
|
menu.toggle();
|
||||||
|
if (menu.isOpen)
|
||||||
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2052,9 +2052,9 @@ const RemoteMenu = new Lang.Class({
|
|||||||
const PopupMenuManager = new Lang.Class({
|
const PopupMenuManager = new Lang.Class({
|
||||||
Name: 'PopupMenuManager',
|
Name: 'PopupMenuManager',
|
||||||
|
|
||||||
_init: function(owner) {
|
_init: function(owner, grabParams) {
|
||||||
this._owner = owner;
|
this._owner = owner;
|
||||||
this._grabHelper = new GrabHelper.GrabHelper(owner.actor);
|
this._grabHelper = new GrabHelper.GrabHelper(owner.actor, grabParams);
|
||||||
this._menus = [];
|
this._menus = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2124,6 +2124,8 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
|
|
||||||
_onMenuOpenState: function(menu, open) {
|
_onMenuOpenState: function(menu, open) {
|
||||||
if (open) {
|
if (open) {
|
||||||
|
if (this.activeMenu)
|
||||||
|
this.activeMenu.close(BoxPointer.PopupAnimation.FADE);
|
||||||
this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor,
|
this._grabHelper.grab({ actor: menu.actor, modal: true, focus: menu.sourceActor,
|
||||||
onUngrab: Lang.bind(this, this._closeMenu, menu) });
|
onUngrab: Lang.bind(this, this._closeMenu, menu) });
|
||||||
} else {
|
} else {
|
||||||
@ -2140,13 +2142,8 @@ const PopupMenuManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_changeMenu: function(newMenu) {
|
_changeMenu: function(newMenu) {
|
||||||
let oldMenu = this.activeMenu;
|
newMenu.open(this.activeMenu ? BoxPointer.PopupAnimation.FADE
|
||||||
if (oldMenu) {
|
: BoxPointer.PopupAnimation.FULL);
|
||||||
oldMenu.close(BoxPointer.PopupAnimation.FADE);
|
|
||||||
newMenu.open(BoxPointer.PopupAnimation.FADE);
|
|
||||||
} else {
|
|
||||||
newMenu.open(BoxPointer.PopupAnimation.FULL);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onMenuSourceEnter: function(menu) {
|
_onMenuSourceEnter: function(menu) {
|
||||||
|
@ -1115,6 +1115,9 @@ const ScreenShield = new Lang.Class({
|
|||||||
deactivate: function(animate) {
|
deactivate: function(animate) {
|
||||||
this._hideLockScreen(animate, 0);
|
this._hideLockScreen(animate, 0);
|
||||||
|
|
||||||
|
if (this._hasLockScreen)
|
||||||
|
this._clearLockScreen();
|
||||||
|
|
||||||
if (Main.sessionMode.currentMode == 'lock-screen')
|
if (Main.sessionMode.currentMode == 'lock-screen')
|
||||||
Main.sessionMode.popMode('lock-screen');
|
Main.sessionMode.popMode('lock-screen');
|
||||||
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
||||||
@ -1131,9 +1134,6 @@ const ScreenShield = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_completeDeactivate: function() {
|
_completeDeactivate: function() {
|
||||||
if (this._hasLockScreen)
|
|
||||||
this._clearLockScreen();
|
|
||||||
|
|
||||||
if (this._dialog && !this._isGreeter) {
|
if (this._dialog && !this._isGreeter) {
|
||||||
this._dialog.destroy();
|
this._dialog.destroy();
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
|
138
js/ui/screencast.js
Normal file
138
js/ui/screencast.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Gio = imports.gi.Gio;
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const Hash = imports.misc.hash;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
const ScreencastIface = <interface name="org.gnome.Shell.Screencast">
|
||||||
|
<method name="Screencast">
|
||||||
|
<arg type="s" direction="in" name="file_template"/>
|
||||||
|
<arg type="a{sv}" direction="in" name="options"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
<method name="ScreencastArea">
|
||||||
|
<arg type="i" direction="in" name="x"/>
|
||||||
|
<arg type="i" direction="in" name="y"/>
|
||||||
|
<arg type="i" direction="in" name="width"/>
|
||||||
|
<arg type="i" direction="in" name="height"/>
|
||||||
|
<arg type="s" direction="in" name="file_template"/>
|
||||||
|
<arg type="a{sv}" direction="in" name="options"/>
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
<arg type="s" direction="out" name="filename_used"/>
|
||||||
|
</method>
|
||||||
|
<method name="StopScreencast">
|
||||||
|
<arg type="b" direction="out" name="success"/>
|
||||||
|
</method>
|
||||||
|
</interface>;
|
||||||
|
|
||||||
|
const ScreencastService = new Lang.Class({
|
||||||
|
Name: 'ScreencastService',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreencastIface, this);
|
||||||
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Screencast');
|
||||||
|
|
||||||
|
Gio.DBus.session.own_name('org.gnome.Shell.Screencast', Gio.BusNameOwnerFlags.REPLACE, null, null);
|
||||||
|
|
||||||
|
this._recorders = new Hash.Map();
|
||||||
|
|
||||||
|
Main.sessionMode.connect('updated',
|
||||||
|
Lang.bind(this, this._sessionModeChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
_ensureRecorderForSender: function(sender) {
|
||||||
|
let recorder = this._recorders.get(sender);
|
||||||
|
if (!recorder) {
|
||||||
|
recorder = new Shell.Recorder({ stage: global.stage });
|
||||||
|
recorder._watchNameId =
|
||||||
|
Gio.bus_watch_name(Gio.BusType.SESSION, sender, 0, null,
|
||||||
|
Lang.bind(this, this._onNameVanished));
|
||||||
|
this._recorders.set(sender, recorder);
|
||||||
|
}
|
||||||
|
return recorder;
|
||||||
|
},
|
||||||
|
|
||||||
|
_sessionModeChanged: function() {
|
||||||
|
if (Main.sessionMode.allowScreencast)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (let sender in this._recorders.keys())
|
||||||
|
this._recorders.delete(sender);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNameVanished: function(connection, name) {
|
||||||
|
this._stopRecordingForSender(name);
|
||||||
|
},
|
||||||
|
|
||||||
|
_stopRecordingForSender: function(sender) {
|
||||||
|
let recorder = this._recorders.get(sender);
|
||||||
|
if (!recorder)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Gio.bus_unwatch_name(recorder._watchNameId);
|
||||||
|
recorder.close();
|
||||||
|
this._recorders.delete(sender);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_applyOptionalParameters: function(recorder, options) {
|
||||||
|
for (let option in options)
|
||||||
|
options[option] = options[option].deep_unpack();
|
||||||
|
|
||||||
|
if (options['pipeline'])
|
||||||
|
recorder.set_pipeline(options['pipeline']);
|
||||||
|
if (options['framerate'])
|
||||||
|
recorder.set_framerate(options['framerate']);
|
||||||
|
if (options['draw-cursor'])
|
||||||
|
recorder.set_draw_cursor(options['draw-cursor']);
|
||||||
|
},
|
||||||
|
|
||||||
|
ScreencastAsync: function(params, invocation) {
|
||||||
|
let returnValue = [false, ''];
|
||||||
|
if (!Main.sessionMode.allowScreencast)
|
||||||
|
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
|
||||||
|
|
||||||
|
let sender = invocation.get_sender();
|
||||||
|
let recorder = this._ensureRecorderForSender(sender);
|
||||||
|
if (!recorder.is_recording()) {
|
||||||
|
let [fileTemplate, options] = params;
|
||||||
|
|
||||||
|
recorder.set_file_template(fileTemplate);
|
||||||
|
this._applyOptionalParameters(recorder, options);
|
||||||
|
returnValue = recorder.record();
|
||||||
|
}
|
||||||
|
|
||||||
|
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
|
||||||
|
},
|
||||||
|
|
||||||
|
ScreencastAreaAsync: function(params, invocation) {
|
||||||
|
let returnValue = [false, ''];
|
||||||
|
if (!Main.sessionMode.allowScreencast)
|
||||||
|
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
|
||||||
|
|
||||||
|
let sender = invocation.get_sender();
|
||||||
|
let recorder = this._ensureRecorderForSender(sender);
|
||||||
|
|
||||||
|
if (!recorder.is_recording()) {
|
||||||
|
let [x, y, width, height, fileTemplate, options] = params;
|
||||||
|
|
||||||
|
recorder.set_file_template(fileTemplate);
|
||||||
|
recorder.set_area(x, y, width, height);
|
||||||
|
this._applyOptionalParameters(recorder, options);
|
||||||
|
returnValue = recorder.record();
|
||||||
|
}
|
||||||
|
|
||||||
|
invocation.return_value(GLib.Variant.new('(bs)', returnValue));
|
||||||
|
},
|
||||||
|
|
||||||
|
StopScreencastAsync: function(params, invocation) {
|
||||||
|
let success = this._stopRecordingForSender(invocation.get_sender());
|
||||||
|
invocation.return_value(GLib.Variant.new('(b)', [success]));
|
||||||
|
}
|
||||||
|
});
|
@ -45,7 +45,7 @@ const _modes = {
|
|||||||
unlockDialog: imports.gdm.loginDialog.LoginDialog,
|
unlockDialog: imports.gdm.loginDialog.LoginDialog,
|
||||||
components: ['polkitAgent'],
|
components: ['polkitAgent'],
|
||||||
panel: {
|
panel: {
|
||||||
left: ['logo'],
|
left: [],
|
||||||
center: ['dateMenu'],
|
center: ['dateMenu'],
|
||||||
right: ['a11yGreeter', 'display', 'keyboard',
|
right: ['a11yGreeter', 'display', 'keyboard',
|
||||||
'volume', 'battery', 'powerMenu']
|
'volume', 'battery', 'powerMenu']
|
||||||
@ -195,6 +195,10 @@ const SessionMode = new Lang.Class({
|
|||||||
return this._modeStack[this._modeStack.length - 1];
|
return this._modeStack[this._modeStack.length - 1];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get allowScreencast() {
|
||||||
|
return this.components.indexOf('recorder') != -1;
|
||||||
|
},
|
||||||
|
|
||||||
_sync: function() {
|
_sync: function() {
|
||||||
let params = this._modes[this.currentMode];
|
let params = this._modes[this.currentMode];
|
||||||
let defaults;
|
let defaults;
|
||||||
|
@ -12,6 +12,7 @@ const ExtensionDownloader = imports.ui.extensionDownloader;
|
|||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
const ExtensionUtils = imports.misc.extensionUtils;
|
||||||
const Hash = imports.misc.hash;
|
const Hash = imports.misc.hash;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
|
const Screencast = imports.ui.screencast;
|
||||||
const Screenshot = imports.ui.screenshot;
|
const Screenshot = imports.ui.screenshot;
|
||||||
|
|
||||||
const GnomeShellIface = <interface name="org.gnome.Shell">
|
const GnomeShellIface = <interface name="org.gnome.Shell">
|
||||||
@ -70,6 +71,7 @@ const GnomeShell = new Lang.Class({
|
|||||||
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
|
||||||
|
|
||||||
this._extensionsService = new GnomeShellExtensions();
|
this._extensionsService = new GnomeShellExtensions();
|
||||||
|
this._screencastService = new Screencast.ScreencastService();
|
||||||
this._screenshotService = new Screenshot.ScreenshotService();
|
this._screenshotService = new Screenshot.ScreenshotService();
|
||||||
|
|
||||||
this._grabbedAccelerators = new Hash.Map();
|
this._grabbedAccelerators = new Hash.Map();
|
||||||
@ -97,7 +99,7 @@ const GnomeShell = new Lang.Class({
|
|||||||
*/
|
*/
|
||||||
Eval: function(code) {
|
Eval: function(code) {
|
||||||
if (!global.settings.get_boolean('development-tools'))
|
if (!global.settings.get_boolean('development-tools'))
|
||||||
return [false, null];
|
return [false, ''];
|
||||||
|
|
||||||
let returnValue;
|
let returnValue;
|
||||||
let success;
|
let success;
|
||||||
|
@ -14,9 +14,7 @@ const EntryMenu = new Lang.Class({
|
|||||||
Name: 'ShellEntryMenu',
|
Name: 'ShellEntryMenu',
|
||||||
Extends: PopupMenu.PopupMenu,
|
Extends: PopupMenu.PopupMenu,
|
||||||
|
|
||||||
_init: function(entry, params) {
|
_init: function(entry) {
|
||||||
params = Params.parse (params, { isPassword: false });
|
|
||||||
|
|
||||||
this.parent(entry, 0, St.Side.TOP);
|
this.parent(entry, 0, St.Side.TOP);
|
||||||
|
|
||||||
this.actor.add_style_class_name('entry-context-menu');
|
this.actor.add_style_class_name('entry-context-menu');
|
||||||
@ -37,8 +35,6 @@ const EntryMenu = new Lang.Class({
|
|||||||
this._pasteItem = item;
|
this._pasteItem = item;
|
||||||
|
|
||||||
this._passwordItem = null;
|
this._passwordItem = null;
|
||||||
if (params.isPassword)
|
|
||||||
this._makePasswordItem();
|
|
||||||
|
|
||||||
Main.uiGroup.add_actor(this.actor);
|
Main.uiGroup.add_actor(this.actor);
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
@ -60,11 +56,13 @@ const EntryMenu = new Lang.Class({
|
|||||||
if (v == this.isPassword)
|
if (v == this.isPassword)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (v)
|
if (v) {
|
||||||
this._makePasswordItem();
|
this._makePasswordItem();
|
||||||
else {
|
this._entry.input_purpose = Gtk.InputPurpose.PASSWORD;
|
||||||
|
} else {
|
||||||
this._passwordItem.destroy();
|
this._passwordItem.destroy();
|
||||||
this._passwordItem = null;
|
this._passwordItem = null;
|
||||||
|
this._entry.input_purpose = Gtk.InputPurpose.FREE_FORM;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -155,7 +153,10 @@ function addContextMenu(entry, params) {
|
|||||||
if (entry.menu)
|
if (entry.menu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
entry.menu = new EntryMenu(entry, params);
|
params = Params.parse (params, { isPassword: false });
|
||||||
|
|
||||||
|
entry.menu = new EntryMenu(entry);
|
||||||
|
entry.menu.isPassword = params.isPassword;
|
||||||
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
|
entry._menuManager = new PopupMenu.PopupMenuManager({ actor: entry });
|
||||||
entry._menuManager.addMenu(entry.menu);
|
entry._menuManager.addMenu(entry.menu);
|
||||||
|
|
||||||
|
@ -45,26 +45,24 @@ const IBusManager = new Lang.Class({
|
|||||||
this._readyCallback = readyCallback;
|
this._readyCallback = readyCallback;
|
||||||
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
this._candidatePopup = new IBusCandidatePopup.CandidatePopup();
|
||||||
|
|
||||||
this._ibus = null;
|
|
||||||
this._panelService = null;
|
this._panelService = null;
|
||||||
this._engines = {};
|
this._engines = {};
|
||||||
this._ready = false;
|
this._ready = false;
|
||||||
this._registerPropertiesId = 0;
|
this._registerPropertiesId = 0;
|
||||||
this._currentEngineName = null;
|
this._currentEngineName = null;
|
||||||
|
|
||||||
this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
|
this._ibus = IBus.Bus.new_async();
|
||||||
Gio.BusNameWatcherFlags.NONE,
|
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
||||||
Lang.bind(this, this._onNameAppeared),
|
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
||||||
Lang.bind(this, this._clear));
|
// Need to set this to get 'global-engine-changed' emitions
|
||||||
|
this._ibus.set_watch_ibus_signal(true);
|
||||||
|
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
|
||||||
},
|
},
|
||||||
|
|
||||||
_clear: function() {
|
_clear: function() {
|
||||||
if (this._panelService)
|
if (this._panelService)
|
||||||
this._panelService.destroy();
|
this._panelService.destroy();
|
||||||
if (this._ibus)
|
|
||||||
this._ibus.destroy();
|
|
||||||
|
|
||||||
this._ibus = null;
|
|
||||||
this._panelService = null;
|
this._panelService = null;
|
||||||
this._candidatePopup.setPanelService(null);
|
this._candidatePopup.setPanelService(null);
|
||||||
this._engines = {};
|
this._engines = {};
|
||||||
@ -76,18 +74,12 @@ const IBusManager = new Lang.Class({
|
|||||||
this._readyCallback(false);
|
this._readyCallback(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onNameAppeared: function() {
|
|
||||||
this._ibus = IBus.Bus.new_async();
|
|
||||||
this._ibus.connect('connected', Lang.bind(this, this._onConnected));
|
|
||||||
},
|
|
||||||
|
|
||||||
_onConnected: function() {
|
_onConnected: function() {
|
||||||
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
|
this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
|
||||||
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
this._ibus.request_name_async(IBus.SERVICE_PANEL,
|
||||||
IBus.BusNameFlag.REPLACE_EXISTING,
|
IBus.BusNameFlag.REPLACE_EXISTING,
|
||||||
-1, null,
|
-1, null,
|
||||||
Lang.bind(this, this._initPanelService));
|
Lang.bind(this, this._initPanelService));
|
||||||
this._ibus.connect('disconnected', Lang.bind(this, this._clear));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_initEngines: function(ibus, result) {
|
_initEngines: function(ibus, result) {
|
||||||
@ -109,9 +101,6 @@ const IBusManager = new Lang.Class({
|
|||||||
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(),
|
||||||
object_path: IBus.PATH_PANEL });
|
object_path: IBus.PATH_PANEL });
|
||||||
this._candidatePopup.setPanelService(this._panelService);
|
this._candidatePopup.setPanelService(this._panelService);
|
||||||
// Need to set this to get 'global-engine-changed' emitions
|
|
||||||
this._ibus.set_watch_ibus_signal(true);
|
|
||||||
this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged));
|
|
||||||
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
|
this._panelService.connect('update-property', Lang.bind(this, this._updateProperty));
|
||||||
// If an engine is already active we need to get its properties
|
// If an engine is already active we need to get its properties
|
||||||
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
|
this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) {
|
||||||
@ -140,6 +129,9 @@ const IBusManager = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_engineChanged: function(bus, engineName) {
|
_engineChanged: function(bus, engineName) {
|
||||||
|
if (!this._ready)
|
||||||
|
return;
|
||||||
|
|
||||||
this._currentEngineName = engineName;
|
this._currentEngineName = engineName;
|
||||||
|
|
||||||
if (this._registerPropertiesId != 0)
|
if (this._registerPropertiesId != 0)
|
||||||
|
@ -2047,6 +2047,7 @@ const NMApplet = new Lang.Class({
|
|||||||
let default_ip4 = null;
|
let default_ip4 = null;
|
||||||
let default_ip6 = null;
|
let default_ip6 = null;
|
||||||
let active_vpn = null;
|
let active_vpn = null;
|
||||||
|
let active_any = null;
|
||||||
for (let i = 0; i < this._activeConnections.length; i++) {
|
for (let i = 0; i < this._activeConnections.length; i++) {
|
||||||
let a = this._activeConnections[i];
|
let a = this._activeConnections[i];
|
||||||
|
|
||||||
@ -2077,10 +2078,15 @@ const NMApplet = new Lang.Class({
|
|||||||
if (a.default6)
|
if (a.default6)
|
||||||
default_ip6 = a;
|
default_ip6 = a;
|
||||||
|
|
||||||
if (a._type == 'vpn')
|
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
||||||
active_vpn = a;
|
|
||||||
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING)
|
|
||||||
activating = a;
|
activating = a;
|
||||||
|
else if (a.state == NetworkManager.ActiveConnectionState.ACTIVE)
|
||||||
|
active_any = a;
|
||||||
|
|
||||||
|
if (a._type == 'vpn' &&
|
||||||
|
(a.state == NetworkManager.ActiveConnectionState.ACTIVATING ||
|
||||||
|
a.state == NetworkManager.ActiveConnectionState.ACTIVE))
|
||||||
|
active_vpn = a;
|
||||||
|
|
||||||
if (!a._primaryDevice) {
|
if (!a._primaryDevice) {
|
||||||
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
|
if (a._type != NetworkManager.SETTING_VPN_SETTING_NAME) {
|
||||||
@ -2108,7 +2114,7 @@ const NMApplet = new Lang.Class({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
|
this._mainConnection = activating || default_ip4 || default_ip6 || active_any || null;
|
||||||
this._vpnConnection = active_vpn;
|
this._vpnConnection = active_vpn;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -91,10 +91,6 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._promptLoginHint.hide();
|
this._promptLoginHint.hide();
|
||||||
this.contentLayout.add_actor(this._promptLoginHint);
|
this.contentLayout.add_actor(this._promptLoginHint);
|
||||||
|
|
||||||
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
|
||||||
this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, LoginDialog.WORK_SPINNER_ICON_SIZE);
|
|
||||||
this._workSpinner.actor.opacity = 0;
|
|
||||||
|
|
||||||
this.allowCancel = false;
|
this.allowCancel = false;
|
||||||
this.buttonLayout.visible = true;
|
this.buttonLayout.visible = true;
|
||||||
this.addButton({ label: _("Cancel"),
|
this.addButton({ label: _("Cancel"),
|
||||||
@ -105,8 +101,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
y_align: St.Align.MIDDLE });
|
y_align: St.Align.MIDDLE });
|
||||||
this.buttonLayout.add(this._workSpinner.actor,
|
this.placeSpinner({ expand: false,
|
||||||
{ expand: false,
|
|
||||||
x_fill: false,
|
x_fill: false,
|
||||||
y_fill: false,
|
y_fill: false,
|
||||||
x_align: St.Align.END,
|
x_align: St.Align.END,
|
||||||
@ -164,28 +159,6 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._okButton.can_focus = sensitive;
|
this._okButton.can_focus = sensitive;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setWorking: function(working) {
|
|
||||||
if (working) {
|
|
||||||
this._workSpinner.play();
|
|
||||||
Tweener.addTween(this._workSpinner.actor,
|
|
||||||
{ opacity: 255,
|
|
||||||
delay: LoginDialog.WORK_SPINNER_ANIMATION_DELAY,
|
|
||||||
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
|
|
||||||
transition: 'linear'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Tweener.addTween(this._workSpinner.actor,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: LoginDialog.WORK_SPINNER_ANIMATION_TIME,
|
|
||||||
transition: 'linear',
|
|
||||||
onCompleteScope: this,
|
|
||||||
onComplete: function() {
|
|
||||||
this._workSpinner.stop();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_showMessage: function(userVerifier, message, styleClass) {
|
_showMessage: function(userVerifier, message, styleClass) {
|
||||||
if (message) {
|
if (message) {
|
||||||
this._promptMessage.text = message;
|
this._promptMessage.text = message;
|
||||||
@ -216,7 +189,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
|
|
||||||
this._currentQuery = serviceName;
|
this._currentQuery = serviceName;
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._setWorking(false);
|
this.setWorking(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_showLoginHint: function(verifier, message) {
|
_showLoginHint: function(verifier, message) {
|
||||||
@ -235,7 +208,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
// the actual reply to GDM will be sent as soon as asked
|
// the actual reply to GDM will be sent as soon as asked
|
||||||
this._firstQuestionAnswer = this._promptEntry.text;
|
this._firstQuestionAnswer = this._promptEntry.text;
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this._setWorking(true);
|
this.setWorking(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +219,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._currentQuery = null;
|
this._currentQuery = null;
|
||||||
|
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this._setWorking(true);
|
this.setWorking(true);
|
||||||
|
|
||||||
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
||||||
},
|
},
|
||||||
@ -286,7 +259,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._promptEntry.menu.isPassword = true;
|
this._promptEntry.menu.isPassword = true;
|
||||||
|
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this._setWorking(false);
|
this.setWorking(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_escape: function() {
|
_escape: function() {
|
||||||
|
@ -172,8 +172,9 @@ const WindowManager = new Lang.Class({
|
|||||||
this.addKeybinding('open-application-menu',
|
this.addKeybinding('open-application-menu',
|
||||||
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
|
||||||
Meta.KeyBindingFlags.NONE,
|
Meta.KeyBindingFlags.NONE,
|
||||||
Shell.KeyBindingMode.NORMAL,
|
Shell.KeyBindingMode.NORMAL |
|
||||||
Lang.bind(this, this._openAppMenu));
|
Shell.KeyBindingMode.TOPBAR_POPUP,
|
||||||
|
Lang.bind(this, this._toggleAppMenu));
|
||||||
|
|
||||||
Main.overview.connect('showing', Lang.bind(this, function() {
|
Main.overview.connect('showing', Lang.bind(this, function() {
|
||||||
for (let i = 0; i < this._dimmedWindows.length; i++)
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
||||||
@ -679,8 +680,8 @@ const WindowManager = new Lang.Class({
|
|||||||
Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask());
|
Main.ctrlAltTabManager.popup(backwards, binding.get_name(), binding.get_mask());
|
||||||
},
|
},
|
||||||
|
|
||||||
_openAppMenu : function(display, screen, window, event, binding) {
|
_toggleAppMenu : function(display, screen, window, event, binding) {
|
||||||
Main.panel.openAppMenu();
|
Main.panel.toggleAppMenu();
|
||||||
},
|
},
|
||||||
|
|
||||||
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
_showWorkspaceSwitcher : function(display, screen, window, binding) {
|
||||||
|
@ -28,6 +28,7 @@ gu
|
|||||||
he
|
he
|
||||||
hi
|
hi
|
||||||
hu
|
hu
|
||||||
|
ia
|
||||||
id
|
id
|
||||||
it
|
it
|
||||||
ja
|
ja
|
||||||
|
6
po/lt.po
6
po/lt.po
@ -461,7 +461,7 @@ msgstr "Nepavyko įvykdyti „%s“:"
|
|||||||
|
|
||||||
#: ../js/ui/appDisplay.js:349
|
#: ../js/ui/appDisplay.js:349
|
||||||
msgid "Frequent"
|
msgid "Frequent"
|
||||||
msgstr "Dažniausios"
|
msgstr "Dažnai naudojamos"
|
||||||
|
|
||||||
#: ../js/ui/appDisplay.js:356
|
#: ../js/ui/appDisplay.js:356
|
||||||
msgid "All"
|
msgid "All"
|
||||||
@ -1262,7 +1262,7 @@ msgstr "Apžvalga"
|
|||||||
#. characters.
|
#. characters.
|
||||||
#: ../js/ui/overview.js:271
|
#: ../js/ui/overview.js:271
|
||||||
msgid "Type to search…"
|
msgid "Type to search…"
|
||||||
msgstr "Rašykite ko ieškote…"
|
msgstr "Rašykite, ko ieškote…"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:612
|
#: ../js/ui/panel.js:612
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
@ -1299,7 +1299,7 @@ msgstr "Užverti"
|
|||||||
#. long format
|
#. long format
|
||||||
#: ../js/ui/screenShield.js:86
|
#: ../js/ui/screenShield.js:86
|
||||||
msgid "%A, %B %d"
|
msgid "%A, %B %d"
|
||||||
msgstr "%A, %B %d"
|
msgstr "%A, %B %d d."
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:151
|
#: ../js/ui/screenShield.js:151
|
||||||
#, c-format
|
#, c-format
|
||||||
|
86
po/nb.po
86
po/nb.po
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gnome-shell 3.8.x\n"
|
"Project-Id-Version: gnome-shell 3.8.x\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2013-04-03 13:31+0200\n"
|
"POT-Creation-Date: 2013-05-13 09:47+0200\n"
|
||||||
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
|
"PO-Revision-Date: 2013-04-03 13:31+0200\n"
|
||||||
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
|
||||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||||
@ -335,43 +335,50 @@ msgstr "Utvidelse"
|
|||||||
msgid "Select an extension to configure using the combobox above."
|
msgid "Select an extension to configure using the combobox above."
|
||||||
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
msgstr "Velg en utvidelse som skal konfigureres med komboboksen over."
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:405
|
#: ../js/gdm/loginDialog.js:371
|
||||||
msgid "Session…"
|
msgid "Session…"
|
||||||
msgstr "Økt …"
|
msgstr "Økt …"
|
||||||
|
|
||||||
#. translators: this message is shown below the user list on the
|
#. translators: this message is shown below the user list on the
|
||||||
#. login screen. It can be activated to reveal an entry for
|
#. login screen. It can be activated to reveal an entry for
|
||||||
#. manually entering the username.
|
#. manually entering the username.
|
||||||
#: ../js/gdm/loginDialog.js:630
|
#: ../js/gdm/loginDialog.js:601
|
||||||
msgid "Not listed?"
|
msgid "Not listed?"
|
||||||
msgstr "Ikke listet?"
|
msgstr "Ikke listet?"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:786 ../js/ui/components/networkAgent.js:137
|
#: ../js/gdm/loginDialog.js:776 ../js/ui/components/networkAgent.js:137
|
||||||
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:375
|
#: ../js/ui/components/polkitAgent.js:162 ../js/ui/endSessionDialog.js:376
|
||||||
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
#: ../js/ui/extensionDownloader.js:195 ../js/ui/shellMountOperation.js:399
|
||||||
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:99
|
#: ../js/ui/status/bluetooth.js:415 ../js/ui/unlockDialog.js:96
|
||||||
#: ../js/ui/userMenu.js:938
|
#: ../js/ui/userMenu.js:938
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Avbryt"
|
msgstr "Avbryt"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:802
|
#: ../js/gdm/loginDialog.js:791
|
||||||
msgctxt "button"
|
msgctxt "button"
|
||||||
msgid "Sign In"
|
msgid "Sign In"
|
||||||
msgstr "Logg inn"
|
msgstr "Logg inn"
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:802
|
#: ../js/gdm/loginDialog.js:791
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Neste"
|
msgstr "Neste"
|
||||||
|
|
||||||
|
#. Translators: this message is shown below the username entry field
|
||||||
|
#. to clue the user in on how to login to the local network realm
|
||||||
|
#: ../js/gdm/loginDialog.js:888
|
||||||
|
#, c-format
|
||||||
|
msgid "(e.g., user or %s)"
|
||||||
|
msgstr "(f.eks. bruker eller %s)"
|
||||||
|
|
||||||
#. TTLS and PEAP are actually much more complicated, but this complication
|
#. TTLS and PEAP are actually much more complicated, but this complication
|
||||||
#. is not visible here since we only care about phase2 authentication
|
#. is not visible here since we only care about phase2 authentication
|
||||||
#. (and don't even care of which one)
|
#. (and don't even care of which one)
|
||||||
#: ../js/gdm/loginDialog.js:917 ../js/ui/components/networkAgent.js:260
|
#: ../js/gdm/loginDialog.js:892 ../js/ui/components/networkAgent.js:260
|
||||||
#: ../js/ui/components/networkAgent.js:278
|
#: ../js/ui/components/networkAgent.js:278
|
||||||
msgid "Username: "
|
msgid "Username: "
|
||||||
msgstr "Brukernavn: "
|
msgstr "Brukernavn: "
|
||||||
|
|
||||||
#: ../js/gdm/loginDialog.js:1173
|
#: ../js/gdm/loginDialog.js:1158
|
||||||
msgid "Login Window"
|
msgid "Login Window"
|
||||||
msgstr "Innloggingsvindu"
|
msgstr "Innloggingsvindu"
|
||||||
|
|
||||||
@ -394,21 +401,16 @@ msgstr "Start på nytt"
|
|||||||
msgid "Power Off"
|
msgid "Power Off"
|
||||||
msgstr "Slå av"
|
msgstr "Slå av"
|
||||||
|
|
||||||
#: ../js/gdm/util.js:249
|
#: ../js/gdm/util.js:247
|
||||||
msgid "Authentication error"
|
msgid "Authentication error"
|
||||||
msgstr "Autentiseringsfeil"
|
msgstr "Autentiseringsfeil"
|
||||||
|
|
||||||
#. Translators: this message is shown below the password entry field
|
#. Translators: this message is shown below the password entry field
|
||||||
#. to indicate the user can swipe their finger instead
|
#. to indicate the user can swipe their finger instead
|
||||||
#: ../js/gdm/util.js:366
|
#: ../js/gdm/util.js:364
|
||||||
msgid "(or swipe finger)"
|
msgid "(or swipe finger)"
|
||||||
msgstr "(eller dra finger)"
|
msgstr "(eller dra finger)"
|
||||||
|
|
||||||
#: ../js/gdm/util.js:391
|
|
||||||
#, c-format
|
|
||||||
msgid "(e.g., user or %s)"
|
|
||||||
msgstr "(f.eks. bruker eller %s)"
|
|
||||||
|
|
||||||
#: ../js/misc/util.js:97
|
#: ../js/misc/util.js:97
|
||||||
msgid "Command not found"
|
msgid "Command not found"
|
||||||
msgstr "Kommando ikke funnet"
|
msgstr "Kommando ikke funnet"
|
||||||
@ -632,11 +634,11 @@ msgstr "Åpne med %s"
|
|||||||
msgid "Eject"
|
msgid "Eject"
|
||||||
msgstr "Løs ut"
|
msgstr "Løs ut"
|
||||||
|
|
||||||
#: ../js/ui/components/keyring.js:82 ../js/ui/components/polkitAgent.js:268
|
#: ../js/ui/components/keyring.js:88 ../js/ui/components/polkitAgent.js:275
|
||||||
msgid "Password:"
|
msgid "Password:"
|
||||||
msgstr "Passord:"
|
msgstr "Passord:"
|
||||||
|
|
||||||
#: ../js/ui/components/keyring.js:101
|
#: ../js/ui/components/keyring.js:107
|
||||||
msgid "Type again:"
|
msgid "Type again:"
|
||||||
msgstr "Skriv på nytt:"
|
msgstr "Skriv på nytt:"
|
||||||
|
|
||||||
@ -724,7 +726,7 @@ msgstr "Autentisering kreves"
|
|||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "Administrator"
|
msgstr "Administrator"
|
||||||
|
|
||||||
#: ../js/ui/components/polkitAgent.js:165
|
#: ../js/ui/components/polkitAgent.js:171
|
||||||
msgid "Authenticate"
|
msgid "Authenticate"
|
||||||
msgstr "Autentiser"
|
msgstr "Autentiser"
|
||||||
|
|
||||||
@ -732,12 +734,12 @@ msgstr "Autentiser"
|
|||||||
#. * requested authentication was not gained; this can happen
|
#. * requested authentication was not gained; this can happen
|
||||||
#. * because of an authentication error (like invalid password),
|
#. * because of an authentication error (like invalid password),
|
||||||
#. * for instance.
|
#. * for instance.
|
||||||
#: ../js/ui/components/polkitAgent.js:256 ../js/ui/shellMountOperation.js:383
|
#: ../js/ui/components/polkitAgent.js:263 ../js/ui/shellMountOperation.js:383
|
||||||
msgid "Sorry, that didn't work. Please try again."
|
msgid "Sorry, that didn't work. Please try again."
|
||||||
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
|
msgstr "Beklager, det virket ikke. Vennligst prøv igjen."
|
||||||
|
|
||||||
#. Translators: this is a filename used for screencast recording
|
#. Translators: this is a filename used for screencast recording
|
||||||
#: ../js/ui/components/recorder.js:48
|
#: ../js/ui/components/recorder.js:47
|
||||||
#, no-c-format
|
#, no-c-format
|
||||||
msgid "Screencast from %d %t"
|
msgid "Screencast from %d %t"
|
||||||
msgstr "Skjermvideo fra %d %t"
|
msgstr "Skjermvideo fra %d %t"
|
||||||
@ -1003,14 +1005,14 @@ msgstr "Åpne kalender"
|
|||||||
msgid "Open Clocks"
|
msgid "Open Clocks"
|
||||||
msgstr "Åpne Klokker"
|
msgstr "Åpne Klokker"
|
||||||
|
|
||||||
#: ../js/ui/dateMenu.js:105
|
#: ../js/ui/dateMenu.js:104
|
||||||
msgid "Date & Time Settings"
|
msgid "Date & Time Settings"
|
||||||
msgstr "Innstillinger for dato og klokkeslett"
|
msgstr "Innstillinger for dato og klokkeslett"
|
||||||
|
|
||||||
#. Translators: This is the date format to use when the calendar popup is
|
#. Translators: This is the date format to use when the calendar popup is
|
||||||
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
#. * shown - it is shown just below the time in the shell (e.g. "Tue 9:29 AM").
|
||||||
#.
|
#.
|
||||||
#: ../js/ui/dateMenu.js:215
|
#: ../js/ui/dateMenu.js:216
|
||||||
msgid "%A %B %e, %Y"
|
msgid "%A %B %e, %Y"
|
||||||
msgstr "%a %e %B, %Y"
|
msgstr "%a %e %B, %Y"
|
||||||
|
|
||||||
@ -1188,11 +1190,11 @@ msgstr "Innstillinger for varsling"
|
|||||||
msgid "No Messages"
|
msgid "No Messages"
|
||||||
msgstr "Ingen meldinger"
|
msgstr "Ingen meldinger"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:1782
|
#: ../js/ui/messageTray.js:1785
|
||||||
msgid "Message Tray"
|
msgid "Message Tray"
|
||||||
msgstr "Meldingstrau"
|
msgstr "Meldingstrau"
|
||||||
|
|
||||||
#: ../js/ui/messageTray.js:2810
|
#: ../js/ui/messageTray.js:2813
|
||||||
msgid "System Information"
|
msgid "System Information"
|
||||||
msgstr "Systeminformasjon"
|
msgstr "Systeminformasjon"
|
||||||
|
|
||||||
@ -1224,17 +1226,17 @@ msgstr "Oversikt"
|
|||||||
msgid "Type to search…"
|
msgid "Type to search…"
|
||||||
msgstr "Skriv for å søke …"
|
msgstr "Skriv for å søke …"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:612
|
#: ../js/ui/panel.js:635
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Avslutt"
|
msgstr "Avslutt"
|
||||||
|
|
||||||
#. Translators: If there is no suitable word for "Activities"
|
#. Translators: If there is no suitable word for "Activities"
|
||||||
#. in your language, you can use the word for "Overview".
|
#. in your language, you can use the word for "Overview".
|
||||||
#: ../js/ui/panel.js:636
|
#: ../js/ui/panel.js:686
|
||||||
msgid "Activities"
|
msgid "Activities"
|
||||||
msgstr "Aktiviteter"
|
msgstr "Aktiviteter"
|
||||||
|
|
||||||
#: ../js/ui/panel.js:933
|
#: ../js/ui/panel.js:982
|
||||||
msgid "Top Bar"
|
msgid "Top Bar"
|
||||||
msgstr "Topp-panel"
|
msgstr "Topp-panel"
|
||||||
|
|
||||||
@ -1247,11 +1249,11 @@ msgstr "Topp-panel"
|
|||||||
msgid "toggle-switch-us"
|
msgid "toggle-switch-us"
|
||||||
msgstr "toggle-switch-intl"
|
msgstr "toggle-switch-intl"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:73
|
#: ../js/ui/runDialog.js:74
|
||||||
msgid "Enter a Command"
|
msgid "Enter a Command"
|
||||||
msgstr "Oppgi en kommando"
|
msgstr "Oppgi en kommando"
|
||||||
|
|
||||||
#: ../js/ui/runDialog.js:109
|
#: ../js/ui/runDialog.js:110
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr "Lukk"
|
msgstr "Lukk"
|
||||||
|
|
||||||
@ -1272,7 +1274,7 @@ msgstr[1] "%d nye varslinger"
|
|||||||
msgid "Lock"
|
msgid "Lock"
|
||||||
msgstr "Lås"
|
msgstr "Lås"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:640
|
#: ../js/ui/screenShield.js:641
|
||||||
msgid "GNOME needs to lock the screen"
|
msgid "GNOME needs to lock the screen"
|
||||||
msgstr "GNOME må låse skjermen"
|
msgstr "GNOME må låse skjermen"
|
||||||
|
|
||||||
@ -1283,11 +1285,11 @@ msgstr "GNOME må låse skjermen"
|
|||||||
#.
|
#.
|
||||||
#. XXX: another option is to kick the user into the gdm login
|
#. XXX: another option is to kick the user into the gdm login
|
||||||
#. screen, where we're not affected by grabs
|
#. screen, where we're not affected by grabs
|
||||||
#: ../js/ui/screenShield.js:761 ../js/ui/screenShield.js:1197
|
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
||||||
msgid "Unable to lock"
|
msgid "Unable to lock"
|
||||||
msgstr "Kan ikke låse"
|
msgstr "Kan ikke låse"
|
||||||
|
|
||||||
#: ../js/ui/screenShield.js:762 ../js/ui/screenShield.js:1198
|
#: ../js/ui/screenShield.js:763 ../js/ui/screenShield.js:1199
|
||||||
msgid "Lock was blocked by an application"
|
msgid "Lock was blocked by an application"
|
||||||
msgstr "Låsing ble stoppet av et program"
|
msgstr "Låsing ble stoppet av et program"
|
||||||
|
|
||||||
@ -1307,11 +1309,11 @@ msgstr "Kopier"
|
|||||||
msgid "Paste"
|
msgid "Paste"
|
||||||
msgstr "Lim inn"
|
msgstr "Lim inn"
|
||||||
|
|
||||||
#: ../js/ui/shellEntry.js:106
|
#: ../js/ui/shellEntry.js:101
|
||||||
msgid "Show Text"
|
msgid "Show Text"
|
||||||
msgstr "Vis tekst"
|
msgstr "Vis tekst"
|
||||||
|
|
||||||
#: ../js/ui/shellEntry.js:108
|
#: ../js/ui/shellEntry.js:103
|
||||||
msgid "Hide Text"
|
msgid "Hide Text"
|
||||||
msgstr "Skjul tekst"
|
msgstr "Skjul tekst"
|
||||||
|
|
||||||
@ -1323,7 +1325,7 @@ msgstr "Passord"
|
|||||||
msgid "Remember Password"
|
msgid "Remember Password"
|
||||||
msgstr "Husk passord"
|
msgstr "Husk passord"
|
||||||
|
|
||||||
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:113
|
#: ../js/ui/shellMountOperation.js:403 ../js/ui/unlockDialog.js:109
|
||||||
msgid "Unlock"
|
msgid "Unlock"
|
||||||
msgstr "Lås opp"
|
msgstr "Lås opp"
|
||||||
|
|
||||||
@ -1614,7 +1616,7 @@ msgstr "Tilkobling feilet"
|
|||||||
msgid "Activation of network connection failed"
|
msgid "Activation of network connection failed"
|
||||||
msgstr "Aktivering av nettverkstilkobling feilet"
|
msgstr "Aktivering av nettverkstilkobling feilet"
|
||||||
|
|
||||||
#: ../js/ui/status/network.js:2276
|
#: ../js/ui/status/network.js:2282
|
||||||
msgid "Networking is disabled"
|
msgid "Networking is disabled"
|
||||||
msgstr "Nettverk er slått av"
|
msgstr "Nettverk er slått av"
|
||||||
|
|
||||||
@ -1728,11 +1730,11 @@ msgstr "Volum"
|
|||||||
msgid "Microphone"
|
msgid "Microphone"
|
||||||
msgstr "Mikrofon"
|
msgstr "Mikrofon"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:124
|
#: ../js/ui/unlockDialog.js:120
|
||||||
msgid "Log in as another user"
|
msgid "Log in as another user"
|
||||||
msgstr "Logg inn som en annen bruker"
|
msgstr "Logg inn som en annen bruker"
|
||||||
|
|
||||||
#: ../js/ui/unlockDialog.js:145
|
#: ../js/ui/unlockDialog.js:141
|
||||||
msgid "Unlock Window"
|
msgid "Unlock Window"
|
||||||
msgstr "Lås opp vindu"
|
msgstr "Lås opp vindu"
|
||||||
|
|
||||||
@ -1885,11 +1887,11 @@ msgstr "Vis mulige modi"
|
|||||||
msgid "Failed to launch '%s'"
|
msgid "Failed to launch '%s'"
|
||||||
msgstr "Klarte ikke å starte «%s»"
|
msgstr "Klarte ikke å starte «%s»"
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:708
|
#: ../src/shell-keyring-prompt.c:714
|
||||||
msgid "Passwords do not match."
|
msgid "Passwords do not match."
|
||||||
msgstr "Passordene er ikke like."
|
msgstr "Passordene er ikke like."
|
||||||
|
|
||||||
#: ../src/shell-keyring-prompt.c:716
|
#: ../src/shell-keyring-prompt.c:722
|
||||||
msgid "Password cannot be blank"
|
msgid "Password cannot be blank"
|
||||||
msgstr "Passordet kan ikke være tomt"
|
msgstr "Passordet kan ikke være tomt"
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
* @SHELL_KEYBINDING_MODE_SYSTEM_MODAL: allow keybinding when a system modal
|
* @SHELL_KEYBINDING_MODE_SYSTEM_MODAL: allow keybinding when a system modal
|
||||||
* dialog (e.g. authentification or session dialogs) is open
|
* dialog (e.g. authentification or session dialogs) is open
|
||||||
* @SHELL_KEYBINDING_MODE_LOOKING_GLASS: allow keybinding in looking glass
|
* @SHELL_KEYBINDING_MODE_LOOKING_GLASS: allow keybinding in looking glass
|
||||||
|
* @SHELL_KEYBINDING_MODE_TOPBAR_POPUP: allow keybinding while a top bar menu
|
||||||
|
* is open
|
||||||
* @SHELL_KEYBINDING_MODE_ALL: always allow keybinding
|
* @SHELL_KEYBINDING_MODE_ALL: always allow keybinding
|
||||||
*
|
*
|
||||||
* Controls in which GNOME Shell states a keybinding should be handled.
|
* Controls in which GNOME Shell states a keybinding should be handled.
|
||||||
@ -29,6 +31,7 @@ typedef enum {
|
|||||||
SHELL_KEYBINDING_MODE_MESSAGE_TRAY = 1 << 5,
|
SHELL_KEYBINDING_MODE_MESSAGE_TRAY = 1 << 5,
|
||||||
SHELL_KEYBINDING_MODE_SYSTEM_MODAL = 1 << 6,
|
SHELL_KEYBINDING_MODE_SYSTEM_MODAL = 1 << 6,
|
||||||
SHELL_KEYBINDING_MODE_LOOKING_GLASS = 1 << 7,
|
SHELL_KEYBINDING_MODE_LOOKING_GLASS = 1 << 7,
|
||||||
|
SHELL_KEYBINDING_MODE_TOPBAR_POPUP = 1 << 8,
|
||||||
|
|
||||||
SHELL_KEYBINDING_MODE_ALL = ~0,
|
SHELL_KEYBINDING_MODE_ALL = ~0,
|
||||||
} ShellKeyBindingMode;
|
} ShellKeyBindingMode;
|
||||||
|
@ -100,7 +100,6 @@ G_DEFINE_TYPE_WITH_CODE (ShellKeyringPrompt, shell_keyring_prompt, G_TYPE_OBJECT
|
|||||||
enum {
|
enum {
|
||||||
SIGNAL_SHOW_PASSWORD,
|
SIGNAL_SHOW_PASSWORD,
|
||||||
SIGNAL_SHOW_CONFIRM,
|
SIGNAL_SHOW_CONFIRM,
|
||||||
SIGNAL_HIDE_PROMPT,
|
|
||||||
SIGNAL_LAST
|
SIGNAL_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -258,10 +257,8 @@ shell_keyring_prompt_dispose (GObject *obj)
|
|||||||
{
|
{
|
||||||
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (obj);
|
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (obj);
|
||||||
|
|
||||||
if (self->shown) {
|
if (self->shown)
|
||||||
self->shown = FALSE;
|
gcr_prompt_close (GCR_PROMPT (self));
|
||||||
g_signal_emit (self, signals[SIGNAL_HIDE_PROMPT], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->async_result)
|
if (self->async_result)
|
||||||
shell_keyring_prompt_cancel (self);
|
shell_keyring_prompt_cancel (self);
|
||||||
@ -384,11 +381,6 @@ shell_keyring_prompt_class_init (ShellKeyringPromptClass *klass)
|
|||||||
0, 0, NULL, NULL,
|
0, 0, NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE, 0);
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
signals[SIGNAL_HIDE_PROMPT] = g_signal_new ("hide-prompt", G_TYPE_FROM_CLASS (klass),
|
|
||||||
0, 0, NULL, NULL,
|
|
||||||
g_cclosure_marshal_VOID__VOID,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -482,6 +474,19 @@ shell_keyring_prompt_confirm_finish (GcrPrompt *prompt,
|
|||||||
return self->last_reply;
|
return self->last_reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
shell_keyring_prompt_close (GcrPrompt *prompt)
|
||||||
|
{
|
||||||
|
ShellKeyringPrompt *self = SHELL_KEYRING_PROMPT (prompt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We expect keyring.js to connect to this signal and do the
|
||||||
|
* actual work of closing the prompt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
self->shown = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_keyring_prompt_iface (GcrPromptIface *iface)
|
shell_keyring_prompt_iface (GcrPromptIface *iface)
|
||||||
{
|
{
|
||||||
@ -489,6 +494,7 @@ shell_keyring_prompt_iface (GcrPromptIface *iface)
|
|||||||
iface->prompt_password_finish = shell_keyring_prompt_password_finish;
|
iface->prompt_password_finish = shell_keyring_prompt_password_finish;
|
||||||
iface->prompt_confirm_async = shell_keyring_prompt_confirm_async;
|
iface->prompt_confirm_async = shell_keyring_prompt_confirm_async;
|
||||||
iface->prompt_confirm_finish = shell_keyring_prompt_confirm_finish;
|
iface->prompt_confirm_finish = shell_keyring_prompt_confirm_finish;
|
||||||
|
iface->prompt_close = shell_keyring_prompt_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -746,9 +752,19 @@ shell_keyring_prompt_cancel (ShellKeyringPrompt *self)
|
|||||||
GSimpleAsyncResult *res;
|
GSimpleAsyncResult *res;
|
||||||
|
|
||||||
g_return_if_fail (SHELL_IS_KEYRING_PROMPT (self));
|
g_return_if_fail (SHELL_IS_KEYRING_PROMPT (self));
|
||||||
g_return_if_fail (self->mode != PROMPTING_NONE);
|
|
||||||
g_return_if_fail (self->async_result != NULL);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If cancelled while not prompting, we should just close the prompt,
|
||||||
|
* the user wants it to go away.
|
||||||
|
*/
|
||||||
|
if (self->mode == PROMPTING_NONE)
|
||||||
|
{
|
||||||
|
if (self->shown)
|
||||||
|
gcr_prompt_close (GCR_PROMPT (self));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_return_if_fail (self->async_result != NULL);
|
||||||
self->last_reply = GCR_PROMPT_REPLY_CANCEL;
|
self->last_reply = GCR_PROMPT_REPLY_CANCEL;
|
||||||
|
|
||||||
res = self->async_result;
|
res = self->async_result;
|
||||||
|
@ -50,6 +50,8 @@ struct _ShellRecorder {
|
|||||||
RecorderState state;
|
RecorderState state;
|
||||||
|
|
||||||
ClutterStage *stage;
|
ClutterStage *stage;
|
||||||
|
gboolean custom_area;
|
||||||
|
cairo_rectangle_int_t area;
|
||||||
int stage_width;
|
int stage_width;
|
||||||
int stage_height;
|
int stage_height;
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ struct _ShellRecorder {
|
|||||||
|
|
||||||
CoglHandle recording_icon; /* icon shown while playing */
|
CoglHandle recording_icon; /* icon shown while playing */
|
||||||
|
|
||||||
|
gboolean draw_cursor;
|
||||||
cairo_surface_t *cursor_image;
|
cairo_surface_t *cursor_image;
|
||||||
int cursor_hot_x;
|
int cursor_hot_x;
|
||||||
int cursor_hot_y;
|
int cursor_hot_y;
|
||||||
@ -110,6 +113,8 @@ static void recorder_set_pipeline (ShellRecorder *recorder,
|
|||||||
const char *pipeline);
|
const char *pipeline);
|
||||||
static void recorder_set_file_template (ShellRecorder *recorder,
|
static void recorder_set_file_template (ShellRecorder *recorder,
|
||||||
const char *file_template);
|
const char *file_template);
|
||||||
|
static void recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||||
|
gboolean draw_cursor);
|
||||||
|
|
||||||
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
|
static void recorder_pipeline_set_caps (RecorderPipeline *pipeline);
|
||||||
static void recorder_pipeline_closed (RecorderPipeline *pipeline);
|
static void recorder_pipeline_closed (RecorderPipeline *pipeline);
|
||||||
@ -119,7 +124,8 @@ enum {
|
|||||||
PROP_STAGE,
|
PROP_STAGE,
|
||||||
PROP_FRAMERATE,
|
PROP_FRAMERATE,
|
||||||
PROP_PIPELINE,
|
PROP_PIPELINE,
|
||||||
PROP_FILE_TEMPLATE
|
PROP_FILE_TEMPLATE,
|
||||||
|
PROP_DRAW_CURSOR
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(ShellRecorder, shell_recorder, G_TYPE_OBJECT);
|
||||||
@ -273,6 +279,7 @@ shell_recorder_init (ShellRecorder *recorder)
|
|||||||
|
|
||||||
recorder->state = RECORDER_STATE_CLOSED;
|
recorder->state = RECORDER_STATE_CLOSED;
|
||||||
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
|
recorder->framerate = DEFAULT_FRAMES_PER_SECOND;
|
||||||
|
recorder->draw_cursor = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -429,10 +436,10 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
|||||||
/* We don't show a cursor unless the hot spot is in the frame; this
|
/* We don't show a cursor unless the hot spot is in the frame; this
|
||||||
* means that sometimes we aren't going to draw a cursor even when
|
* means that sometimes we aren't going to draw a cursor even when
|
||||||
* there is a little bit overlapping within the stage */
|
* there is a little bit overlapping within the stage */
|
||||||
if (recorder->pointer_x < 0 ||
|
if (recorder->pointer_x < recorder->area.x ||
|
||||||
recorder->pointer_y < 0 ||
|
recorder->pointer_y < recorder->area.y ||
|
||||||
recorder->pointer_x >= recorder->stage_width ||
|
recorder->pointer_x >= recorder->area.x + recorder->area.width ||
|
||||||
recorder->pointer_y >= recorder->stage_height)
|
recorder->pointer_y >= recorder->area.y + recorder->area.height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!recorder->cursor_image)
|
if (!recorder->cursor_image)
|
||||||
@ -444,15 +451,15 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
|||||||
gst_buffer_map (buffer, &info, GST_MAP_WRITE);
|
gst_buffer_map (buffer, &info, GST_MAP_WRITE);
|
||||||
surface = cairo_image_surface_create_for_data (info.data,
|
surface = cairo_image_surface_create_for_data (info.data,
|
||||||
CAIRO_FORMAT_ARGB32,
|
CAIRO_FORMAT_ARGB32,
|
||||||
recorder->stage_width,
|
recorder->area.width,
|
||||||
recorder->stage_height,
|
recorder->area.height,
|
||||||
recorder->stage_width * 4);
|
recorder->area.width * 4);
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
cairo_set_source_surface (cr,
|
cairo_set_source_surface (cr,
|
||||||
recorder->cursor_image,
|
recorder->cursor_image,
|
||||||
recorder->pointer_x - recorder->cursor_hot_x,
|
recorder->pointer_x - recorder->cursor_hot_x - recorder->area.x,
|
||||||
recorder->pointer_y - recorder->cursor_hot_y);
|
recorder->pointer_y - recorder->cursor_hot_y - recorder->area.y);
|
||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
@ -555,12 +562,13 @@ recorder_record_frame (ShellRecorder *recorder)
|
|||||||
|
|
||||||
recorder->last_frame_time = now;
|
recorder->last_frame_time = now;
|
||||||
|
|
||||||
size = recorder->stage_width * recorder->stage_height * 4;
|
size = recorder->area.width * recorder->area.height * 4;
|
||||||
|
|
||||||
data = g_malloc (recorder->stage_width * 4 * recorder->stage_height);
|
data = g_malloc (recorder->area.width * 4 * recorder->area.height);
|
||||||
cogl_read_pixels (0, 0, /* x/y */
|
cogl_read_pixels (recorder->area.x,
|
||||||
recorder->stage_width,
|
recorder->area.y,
|
||||||
recorder->stage_height,
|
recorder->area.width,
|
||||||
|
recorder->area.height,
|
||||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||||
data);
|
data);
|
||||||
@ -572,6 +580,7 @@ recorder_record_frame (ShellRecorder *recorder)
|
|||||||
|
|
||||||
GST_BUFFER_PTS(buffer) = now - recorder->start_time;
|
GST_BUFFER_PTS(buffer) = now - recorder->start_time;
|
||||||
|
|
||||||
|
if (recorder->draw_cursor)
|
||||||
recorder_draw_cursor (recorder, buffer);
|
recorder_draw_cursor (recorder, buffer);
|
||||||
|
|
||||||
shell_recorder_src_add_buffer (SHELL_RECORDER_SRC (recorder->current_pipeline->src), buffer);
|
shell_recorder_src_add_buffer (SHELL_RECORDER_SRC (recorder->current_pipeline->src), buffer);
|
||||||
@ -616,6 +625,14 @@ recorder_update_size (ShellRecorder *recorder)
|
|||||||
clutter_actor_get_allocation_box (CLUTTER_ACTOR (recorder->stage), &allocation);
|
clutter_actor_get_allocation_box (CLUTTER_ACTOR (recorder->stage), &allocation);
|
||||||
recorder->stage_width = (int)(0.5 + allocation.x2 - allocation.x1);
|
recorder->stage_width = (int)(0.5 + allocation.x2 - allocation.x1);
|
||||||
recorder->stage_height = (int)(0.5 + allocation.y2 - allocation.y1);
|
recorder->stage_height = (int)(0.5 + allocation.y2 - allocation.y1);
|
||||||
|
|
||||||
|
if (!recorder->custom_area)
|
||||||
|
{
|
||||||
|
recorder->area.x = 0;
|
||||||
|
recorder->area.y = 0;
|
||||||
|
recorder->area.width = recorder->stage_width;
|
||||||
|
recorder->area.height = recorder->stage_height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1006,6 +1023,18 @@ recorder_set_file_template (ShellRecorder *recorder,
|
|||||||
g_object_notify (G_OBJECT (recorder), "file-template");
|
g_object_notify (G_OBJECT (recorder), "file-template");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||||
|
gboolean draw_cursor)
|
||||||
|
{
|
||||||
|
if (draw_cursor == recorder->draw_cursor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
recorder->draw_cursor = draw_cursor;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (recorder), "draw-cursor");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shell_recorder_set_property (GObject *object,
|
shell_recorder_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -1028,6 +1057,9 @@ shell_recorder_set_property (GObject *object,
|
|||||||
case PROP_FILE_TEMPLATE:
|
case PROP_FILE_TEMPLATE:
|
||||||
recorder_set_file_template (recorder, g_value_get_string (value));
|
recorder_set_file_template (recorder, g_value_get_string (value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_DRAW_CURSOR:
|
||||||
|
recorder_set_draw_cursor (recorder, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -1056,6 +1088,9 @@ shell_recorder_get_property (GObject *object,
|
|||||||
case PROP_FILE_TEMPLATE:
|
case PROP_FILE_TEMPLATE:
|
||||||
g_value_set_string (value, recorder->file_template);
|
g_value_set_string (value, recorder->file_template);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DRAW_CURSOR:
|
||||||
|
g_value_set_boolean (value, recorder->draw_cursor);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -1104,6 +1139,14 @@ shell_recorder_class_init (ShellRecorderClass *klass)
|
|||||||
"The filename template to use for output files",
|
"The filename template to use for output files",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_DRAW_CURSOR,
|
||||||
|
g_param_spec_boolean ("draw-cursor",
|
||||||
|
"Draw Cursor",
|
||||||
|
"Whether to record the cursor",
|
||||||
|
TRUE,
|
||||||
|
G_PARAM_READWRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sets the GstCaps (video format, in this case) on the stream
|
/* Sets the GstCaps (video format, in this case) on the stream
|
||||||
@ -1126,8 +1169,8 @@ recorder_pipeline_set_caps (RecorderPipeline *pipeline)
|
|||||||
"bpp", G_TYPE_INT, 32,
|
"bpp", G_TYPE_INT, 32,
|
||||||
"depth", G_TYPE_INT, 24,
|
"depth", G_TYPE_INT, 24,
|
||||||
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
"framerate", GST_TYPE_FRACTION, pipeline->recorder->framerate, 1,
|
||||||
"width", G_TYPE_INT, pipeline->recorder->stage_width,
|
"width", G_TYPE_INT, pipeline->recorder->area.width,
|
||||||
"height", G_TYPE_INT, pipeline->recorder->stage_height,
|
"height", G_TYPE_INT, pipeline->recorder->area.height,
|
||||||
NULL);
|
NULL);
|
||||||
g_object_set (pipeline->src, "caps", caps, NULL);
|
g_object_set (pipeline->src, "caps", caps, NULL);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
@ -1678,6 +1721,15 @@ shell_recorder_set_file_template (ShellRecorder *recorder,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||||
|
gboolean draw_cursor)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SHELL_IS_RECORDER (recorder));
|
||||||
|
|
||||||
|
recorder_set_draw_cursor (recorder, draw_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_recorder_set_pipeline:
|
* shell_recorder_set_pipeline:
|
||||||
* @recorder: the #ShellRecorder
|
* @recorder: the #ShellRecorder
|
||||||
@ -1705,9 +1757,35 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
|
|||||||
recorder_set_pipeline (recorder, pipeline);
|
recorder_set_pipeline (recorder, pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_recorder_set_area (ShellRecorder *recorder,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
g_return_if_fail (SHELL_IS_RECORDER (recorder));
|
||||||
|
|
||||||
|
recorder->custom_area = TRUE;
|
||||||
|
recorder->area.x = CLAMP (x, 0, recorder->stage_width);
|
||||||
|
recorder->area.y = CLAMP (y, 0, recorder->stage_height);
|
||||||
|
recorder->area.width = CLAMP (width,
|
||||||
|
0, recorder->stage_width - recorder->area.x);
|
||||||
|
recorder->area.height = CLAMP (height,
|
||||||
|
0, recorder->stage_height - recorder->area.y);
|
||||||
|
|
||||||
|
/* This breaks the recording but tweaking the GStreamer pipeline a bit
|
||||||
|
* might make it work, at least if the codec can handle a stream where
|
||||||
|
* the frame size changes in the middle.
|
||||||
|
*/
|
||||||
|
if (recorder->current_pipeline)
|
||||||
|
recorder_pipeline_set_caps (recorder->current_pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_recorder_record:
|
* shell_recorder_record:
|
||||||
* @recorder: the #ShellRecorder
|
* @recorder: the #ShellRecorder
|
||||||
|
* @filename_used: (out) (allow-none): actual filename used for recording
|
||||||
*
|
*
|
||||||
* Starts recording, Starting the recording may fail if the output file
|
* Starts recording, Starting the recording may fail if the output file
|
||||||
* cannot be opened, or if the output stream cannot be created
|
* cannot be opened, or if the output stream cannot be created
|
||||||
@ -1724,7 +1802,8 @@ shell_recorder_set_pipeline (ShellRecorder *recorder,
|
|||||||
* Return value: %TRUE if recording was succesfully started
|
* Return value: %TRUE if recording was succesfully started
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
shell_recorder_record (ShellRecorder *recorder)
|
shell_recorder_record (ShellRecorder *recorder,
|
||||||
|
char **filename_used)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (SHELL_IS_RECORDER (recorder), FALSE);
|
g_return_val_if_fail (SHELL_IS_RECORDER (recorder), FALSE);
|
||||||
g_return_val_if_fail (recorder->stage != NULL, FALSE);
|
g_return_val_if_fail (recorder->stage != NULL, FALSE);
|
||||||
@ -1733,6 +1812,9 @@ shell_recorder_record (ShellRecorder *recorder)
|
|||||||
if (!recorder_open_pipeline (recorder))
|
if (!recorder_open_pipeline (recorder))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (filename_used)
|
||||||
|
*filename_used = g_strdup (recorder->current_pipeline->filename);
|
||||||
|
|
||||||
recorder_connect_stage_callbacks (recorder);
|
recorder_connect_stage_callbacks (recorder);
|
||||||
|
|
||||||
recorder->start_time = get_wall_time();
|
recorder->start_time = get_wall_time();
|
||||||
|
@ -36,7 +36,15 @@ void shell_recorder_set_file_template (ShellRecorder *recorder,
|
|||||||
const char *file_template);
|
const char *file_template);
|
||||||
void shell_recorder_set_pipeline (ShellRecorder *recorder,
|
void shell_recorder_set_pipeline (ShellRecorder *recorder,
|
||||||
const char *pipeline);
|
const char *pipeline);
|
||||||
gboolean shell_recorder_record (ShellRecorder *recorder);
|
void shell_recorder_set_draw_cursor (ShellRecorder *recorder,
|
||||||
|
gboolean draw_cursor);
|
||||||
|
void shell_recorder_set_area (ShellRecorder *recorder,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
gboolean shell_recorder_record (ShellRecorder *recorder,
|
||||||
|
char **filename_used);
|
||||||
void shell_recorder_close (ShellRecorder *recorder);
|
void shell_recorder_close (ShellRecorder *recorder);
|
||||||
void shell_recorder_pause (ShellRecorder *recorder);
|
void shell_recorder_pause (ShellRecorder *recorder);
|
||||||
gboolean shell_recorder_is_recording (ShellRecorder *recorder);
|
gboolean shell_recorder_is_recording (ShellRecorder *recorder);
|
||||||
|
@ -82,6 +82,8 @@ enum
|
|||||||
PROP_CLUTTER_TEXT,
|
PROP_CLUTTER_TEXT,
|
||||||
PROP_HINT_TEXT,
|
PROP_HINT_TEXT,
|
||||||
PROP_TEXT,
|
PROP_TEXT,
|
||||||
|
PROP_INPUT_PURPOSE,
|
||||||
|
PROP_INPUT_HINTS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
@ -136,6 +138,14 @@ st_entry_set_property (GObject *gobject,
|
|||||||
st_entry_set_text (entry, g_value_get_string (value));
|
st_entry_set_text (entry, g_value_get_string (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_PURPOSE:
|
||||||
|
st_entry_set_input_purpose (entry, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_HINTS:
|
||||||
|
st_entry_set_input_hints (entry, g_value_get_flags (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -164,6 +174,14 @@ st_entry_get_property (GObject *gobject,
|
|||||||
g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
|
g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_PURPOSE:
|
||||||
|
g_value_set_enum (value, st_im_text_get_input_purpose (ST_IM_TEXT (priv->entry)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_HINTS:
|
||||||
|
g_value_set_flags (value, st_im_text_get_input_hints (ST_IM_TEXT (priv->entry)));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -759,6 +777,26 @@ st_entry_class_init (StEntryClass *klass)
|
|||||||
NULL, G_PARAM_READWRITE);
|
NULL, G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
|
g_object_class_install_property (gobject_class, PROP_TEXT, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_enum ("input-purpose",
|
||||||
|
"Purpose",
|
||||||
|
"Purpose of the text field",
|
||||||
|
GTK_TYPE_INPUT_PURPOSE,
|
||||||
|
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_INPUT_PURPOSE,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_flags ("input-hints",
|
||||||
|
"hints",
|
||||||
|
"Hints for the text field behaviour",
|
||||||
|
GTK_TYPE_INPUT_HINTS,
|
||||||
|
GTK_INPUT_HINT_NONE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_INPUT_HINTS,
|
||||||
|
pspec);
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
/**
|
/**
|
||||||
* StEntry::primary-icon-clicked:
|
* StEntry::primary-icon-clicked:
|
||||||
@ -966,6 +1004,87 @@ st_entry_get_hint_text (StEntry *entry)
|
|||||||
return entry->priv->hint;
|
return entry->priv->hint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_entry_set_input_purpose:
|
||||||
|
* @entry: a #StEntry
|
||||||
|
* @purpose: the purpose
|
||||||
|
*
|
||||||
|
* Sets the #StEntry:input-purpose property which
|
||||||
|
* can be used by on-screen keyboards and other input
|
||||||
|
* methods to adjust their behaviour.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_entry_set_input_purpose (StEntry *entry,
|
||||||
|
GtkInputPurpose purpose)
|
||||||
|
{
|
||||||
|
StIMText *imtext;
|
||||||
|
|
||||||
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
||||||
|
|
||||||
|
imtext = ST_IM_TEXT (entry->priv->entry);
|
||||||
|
|
||||||
|
if (st_im_text_get_input_purpose (imtext) != purpose)
|
||||||
|
{
|
||||||
|
st_im_text_set_input_purpose (imtext, purpose);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (entry), "input-purpose");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_entry_get_input_purpose:
|
||||||
|
* @entry: a #StEntry
|
||||||
|
*
|
||||||
|
* Gets the value of the #StEntry:input-purpose property.
|
||||||
|
*/
|
||||||
|
GtkInputPurpose
|
||||||
|
st_entry_get_input_purpose (StEntry *entry)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_PURPOSE_FREE_FORM);
|
||||||
|
|
||||||
|
return st_im_text_get_input_purpose (ST_IM_TEXT (entry->priv->entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_entry_set_input_hints:
|
||||||
|
* @entry: a #StEntry
|
||||||
|
* @hints: the hints
|
||||||
|
*
|
||||||
|
* Sets the #StEntry:input-hints property, which
|
||||||
|
* allows input methods to fine-tune their behaviour.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_entry_set_input_hints (StEntry *entry,
|
||||||
|
GtkInputHints hints)
|
||||||
|
{
|
||||||
|
StIMText *imtext;
|
||||||
|
|
||||||
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
||||||
|
|
||||||
|
imtext = ST_IM_TEXT (entry->priv->entry);
|
||||||
|
|
||||||
|
if (st_im_text_get_input_hints (imtext) != hints)
|
||||||
|
{
|
||||||
|
st_im_text_set_input_hints (imtext, hints);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (entry), "input-hints");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_entry_get_input_hints:
|
||||||
|
* @entry: a #StEntry
|
||||||
|
*
|
||||||
|
* Gets the value of the #StEntry:input-hints property.
|
||||||
|
*/
|
||||||
|
GtkInputHints
|
||||||
|
st_entry_get_input_hints (StEntry *entry)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ST_IS_ENTRY (entry), GTK_INPUT_HINT_NONE);
|
||||||
|
|
||||||
|
return st_im_text_get_input_hints (ST_IM_TEXT (entry->priv->entry));
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_st_entry_icon_press_cb (ClutterActor *actor,
|
_st_entry_icon_press_cb (ClutterActor *actor,
|
||||||
ClutterButtonEvent *event,
|
ClutterButtonEvent *event,
|
||||||
|
@ -74,6 +74,13 @@ void st_entry_set_hint_text (StEntry *entry,
|
|||||||
const gchar *text);
|
const gchar *text);
|
||||||
const gchar *st_entry_get_hint_text (StEntry *entry);
|
const gchar *st_entry_get_hint_text (StEntry *entry);
|
||||||
|
|
||||||
|
void st_entry_set_input_purpose (StEntry *entry,
|
||||||
|
GtkInputPurpose purpose);
|
||||||
|
GtkInputPurpose st_entry_get_input_purpose (StEntry *entry);
|
||||||
|
void st_entry_set_input_hints (StEntry *entry,
|
||||||
|
GtkInputHints hints);
|
||||||
|
GtkInputHints st_entry_get_input_hints (StEntry *entry);
|
||||||
|
|
||||||
void st_entry_set_primary_icon (StEntry *entry,
|
void st_entry_set_primary_icon (StEntry *entry,
|
||||||
ClutterActor *icon);
|
ClutterActor *icon);
|
||||||
void st_entry_set_secondary_icon (StEntry *entry,
|
void st_entry_set_secondary_icon (StEntry *entry,
|
||||||
|
@ -249,11 +249,6 @@ st_icon_paint (ClutterActor *actor)
|
|||||||
clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
|
clutter_actor_get_allocation_box (priv->icon_texture, &allocation);
|
||||||
clutter_actor_box_get_size (&allocation, &width, &height);
|
clutter_actor_box_get_size (&allocation, &width, &height);
|
||||||
|
|
||||||
allocation.x1 = (width - priv->shadow_width) / 2;
|
|
||||||
allocation.y1 = (height - priv->shadow_height) / 2;
|
|
||||||
allocation.x2 = allocation.x1 + priv->shadow_width;
|
|
||||||
allocation.y2 = allocation.y1 + priv->shadow_height;
|
|
||||||
|
|
||||||
_st_paint_shadow_with_opacity (priv->shadow_spec,
|
_st_paint_shadow_with_opacity (priv->shadow_spec,
|
||||||
priv->shadow_material,
|
priv->shadow_material,
|
||||||
&allocation,
|
&allocation,
|
||||||
@ -410,8 +405,8 @@ st_icon_finish_update (StIcon *icon)
|
|||||||
st_icon_update_shadow_material (icon);
|
st_icon_update_shadow_material (icon);
|
||||||
|
|
||||||
/* "pixbuf-change" is actually a misnomer for "texture-changed" */
|
/* "pixbuf-change" is actually a misnomer for "texture-changed" */
|
||||||
g_signal_connect (priv->icon_texture, "pixbuf-change",
|
g_signal_connect_object (priv->icon_texture, "pixbuf-change",
|
||||||
G_CALLBACK (on_pixbuf_changed), icon);
|
G_CALLBACK (on_pixbuf_changed), icon, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +464,7 @@ st_icon_update (StIcon *icon)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Will be shown when fully loaded */
|
/* Will be shown when fully loaded */
|
||||||
priv->opacity_handler_id = g_signal_connect (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon);
|
priv->opacity_handler_id = g_signal_connect_object (priv->pending_texture, "notify::opacity", G_CALLBACK (opacity_changed_cb), icon, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (priv->icon_texture)
|
else if (priv->icon_texture)
|
||||||
|
@ -50,6 +50,15 @@
|
|||||||
|
|
||||||
#include "st-im-text.h"
|
#include "st-im-text.h"
|
||||||
|
|
||||||
|
/* properties */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_INPUT_PURPOSE,
|
||||||
|
PROP_INPUT_HINTS,
|
||||||
|
};
|
||||||
|
|
||||||
#define ST_IM_TEXT_GET_PRIVATE(obj) \
|
#define ST_IM_TEXT_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_IM_TEXT, StIMTextPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_IM_TEXT, StIMTextPrivate))
|
||||||
|
|
||||||
@ -404,16 +413,67 @@ st_im_text_key_focus_out (ClutterActor *actor)
|
|||||||
CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->key_focus_out (actor);
|
CLUTTER_ACTOR_CLASS (st_im_text_parent_class)->key_focus_out (actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_im_text_set_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
StIMText *imtext = ST_IM_TEXT (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_INPUT_PURPOSE:
|
||||||
|
st_im_text_set_input_purpose (imtext, g_value_get_enum (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_HINTS:
|
||||||
|
st_im_text_set_input_hints (imtext, g_value_get_flags (value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_im_text_get_property (GObject *gobject,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
StIMText *imtext = ST_IM_TEXT (gobject);
|
||||||
|
|
||||||
|
switch (prop_id)
|
||||||
|
{
|
||||||
|
case PROP_INPUT_PURPOSE:
|
||||||
|
g_value_set_enum (value, st_im_text_get_input_purpose (imtext));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_INPUT_HINTS:
|
||||||
|
g_value_set_flags (value, st_im_text_get_input_hints (imtext));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_im_text_class_init (StIMTextClass *klass)
|
st_im_text_class_init (StIMTextClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||||
ClutterTextClass *text_class = CLUTTER_TEXT_CLASS (klass);
|
ClutterTextClass *text_class = CLUTTER_TEXT_CLASS (klass);
|
||||||
|
GParamSpec *pspec;
|
||||||
|
|
||||||
g_type_class_add_private (klass, sizeof (StIMTextPrivate));
|
g_type_class_add_private (klass, sizeof (StIMTextPrivate));
|
||||||
|
|
||||||
object_class->dispose = st_im_text_dispose;
|
object_class->dispose = st_im_text_dispose;
|
||||||
|
object_class->set_property = st_im_text_set_property;
|
||||||
|
object_class->get_property = st_im_text_get_property;
|
||||||
|
|
||||||
actor_class->get_paint_volume = st_im_text_get_paint_volume;
|
actor_class->get_paint_volume = st_im_text_get_paint_volume;
|
||||||
actor_class->realize = st_im_text_realize;
|
actor_class->realize = st_im_text_realize;
|
||||||
@ -425,6 +485,26 @@ st_im_text_class_init (StIMTextClass *klass)
|
|||||||
actor_class->key_focus_out = st_im_text_key_focus_out;
|
actor_class->key_focus_out = st_im_text_key_focus_out;
|
||||||
|
|
||||||
text_class->cursor_event = st_im_text_cursor_event;
|
text_class->cursor_event = st_im_text_cursor_event;
|
||||||
|
|
||||||
|
pspec = g_param_spec_enum ("input-purpose",
|
||||||
|
"Purpose",
|
||||||
|
"Purpose of the text field",
|
||||||
|
GTK_TYPE_INPUT_PURPOSE,
|
||||||
|
GTK_INPUT_PURPOSE_FREE_FORM,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_INPUT_PURPOSE,
|
||||||
|
pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_flags ("input-hints",
|
||||||
|
"hints",
|
||||||
|
"Hints for the text field behaviour",
|
||||||
|
GTK_TYPE_INPUT_HINTS,
|
||||||
|
GTK_INPUT_HINT_NONE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_INPUT_HINTS,
|
||||||
|
pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -460,3 +540,96 @@ st_im_text_new (const gchar *text)
|
|||||||
"text", text,
|
"text", text,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_im_text_set_input_purpose:
|
||||||
|
* @imtext: a #StIMText
|
||||||
|
* @purpose: the purpose
|
||||||
|
*
|
||||||
|
* Sets the #StIMText:input-purpose property which
|
||||||
|
* can be used by on-screen keyboards and other input
|
||||||
|
* methods to adjust their behaviour.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_im_text_set_input_purpose (StIMText *imtext,
|
||||||
|
GtkInputPurpose purpose)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_IM_TEXT (imtext));
|
||||||
|
|
||||||
|
if (st_im_text_get_input_purpose (imtext) != purpose)
|
||||||
|
{
|
||||||
|
g_object_set (G_OBJECT (imtext->priv->im_context),
|
||||||
|
"input-purpose", purpose,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||||
|
"input-purpose", &purpose,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (imtext), "input-purpose");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_im_text_get_input_purpose:
|
||||||
|
* @imtext: a #StIMText
|
||||||
|
*
|
||||||
|
* Gets the value of the #StIMText:input-purpose property.
|
||||||
|
*/
|
||||||
|
GtkInputPurpose
|
||||||
|
st_im_text_get_input_purpose (StIMText *imtext)
|
||||||
|
{
|
||||||
|
GtkInputPurpose purpose;
|
||||||
|
|
||||||
|
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_PURPOSE_FREE_FORM);
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||||
|
"input-purpose", &purpose,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return purpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_im_text_set_input_hints:
|
||||||
|
* @imtext: a #StIMText
|
||||||
|
* @hints: the hints
|
||||||
|
*
|
||||||
|
* Sets the #StIMText:input-hints property, which
|
||||||
|
* allows input methods to fine-tune their behaviour.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_im_text_set_input_hints (StIMText *imtext,
|
||||||
|
GtkInputHints hints)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ST_IS_IM_TEXT (imtext));
|
||||||
|
|
||||||
|
if (st_im_text_get_input_hints (imtext) != hints)
|
||||||
|
{
|
||||||
|
g_object_set (G_OBJECT (imtext->priv->im_context),
|
||||||
|
"input-hints", hints,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (imtext), "input-hints");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* st_im_text_get_input_hints:
|
||||||
|
* @imtext: a #StIMText
|
||||||
|
*
|
||||||
|
* Gets the value of the #StIMText:input-hints property.
|
||||||
|
*/
|
||||||
|
GtkInputHints
|
||||||
|
st_im_text_get_input_hints (StIMText *imtext)
|
||||||
|
{
|
||||||
|
GtkInputHints hints;
|
||||||
|
|
||||||
|
g_return_val_if_fail (ST_IS_IM_TEXT (imtext), GTK_INPUT_HINT_NONE);
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (imtext->priv->im_context),
|
||||||
|
"input-hints", &hints,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
@ -61,8 +61,12 @@ struct _StIMTextClass
|
|||||||
GType st_im_text_get_type (void) G_GNUC_CONST;
|
GType st_im_text_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ClutterActor *st_im_text_new (const gchar *text);
|
ClutterActor *st_im_text_new (const gchar *text);
|
||||||
void st_im_text_set_autoshow_im (StIMText *self,
|
void st_im_text_set_input_purpose (StIMText *imtext,
|
||||||
gboolean autoshow);
|
GtkInputPurpose purpose);
|
||||||
|
GtkInputPurpose st_im_text_get_input_purpose (StIMText *imtext);
|
||||||
|
void st_im_text_set_input_hints (StIMText *imtext,
|
||||||
|
GtkInputHints hints);
|
||||||
|
GtkInputHints st_im_text_get_input_hints (StIMText *imtext);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -218,10 +218,6 @@ st_label_paint (ClutterActor *actor)
|
|||||||
clutter_actor_get_allocation_box (priv->label, &allocation);
|
clutter_actor_get_allocation_box (priv->label, &allocation);
|
||||||
clutter_actor_box_get_size (&allocation, &width, &height);
|
clutter_actor_box_get_size (&allocation, &width, &height);
|
||||||
|
|
||||||
allocation.x1 = allocation.y1 = 0;
|
|
||||||
allocation.x2 = width;
|
|
||||||
allocation.y2 = height;
|
|
||||||
|
|
||||||
if (priv->text_shadow_material == COGL_INVALID_HANDLE ||
|
if (priv->text_shadow_material == COGL_INVALID_HANDLE ||
|
||||||
width != priv->shadow_width ||
|
width != priv->shadow_width ||
|
||||||
height != priv->shadow_height)
|
height != priv->shadow_height)
|
||||||
|
@ -511,6 +511,7 @@ _st_create_shadow_material_from_actor (StShadow *shadow_spec,
|
|||||||
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
|
cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
|
||||||
cogl_push_framebuffer (offscreen);
|
cogl_push_framebuffer (offscreen);
|
||||||
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
|
cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
|
||||||
|
cogl_translate (-box.x1, -box.y1, 0);
|
||||||
cogl_ortho (0, width, height, 0, 0, 1.0);
|
cogl_ortho (0, width, height, 0, 0, 1.0);
|
||||||
clutter_actor_paint (actor);
|
clutter_actor_paint (actor);
|
||||||
cogl_pop_framebuffer ();
|
cogl_pop_framebuffer ();
|
||||||
|
@ -292,11 +292,6 @@ st_shadow_helper_paint (StShadowHelper *helper,
|
|||||||
|
|
||||||
clutter_actor_box_get_size (actor_box, &width, &height);
|
clutter_actor_box_get_size (actor_box, &width, &height);
|
||||||
|
|
||||||
allocation.x1 = (width - helper->width) / 2;
|
|
||||||
allocation.y1 = (height - helper->height) / 2;
|
|
||||||
allocation.x2 = allocation.x1 + helper->width;
|
|
||||||
allocation.y2 = allocation.y1 + helper->height;
|
|
||||||
|
|
||||||
_st_paint_shadow_with_opacity (helper->shadow,
|
_st_paint_shadow_with_opacity (helper->shadow,
|
||||||
helper->material,
|
helper->material,
|
||||||
&allocation,
|
&allocation,
|
||||||
|
@ -48,7 +48,7 @@ on_stage_realized (ClutterActor *stage,
|
|||||||
{
|
{
|
||||||
recorder = shell_recorder_new (CLUTTER_STAGE (stage));
|
recorder = shell_recorder_new (CLUTTER_STAGE (stage));
|
||||||
shell_recorder_set_file_template (recorder, "test-recorder.webm");
|
shell_recorder_set_file_template (recorder, "test-recorder.webm");
|
||||||
shell_recorder_record (recorder);
|
shell_recorder_record (recorder, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
|
Reference in New Issue
Block a user