Compare commits

..

2 Commits

Author SHA1 Message Date
Carlos Garnacho
f9693d3a2b TMP: theme osd changes 2016-07-20 19:24:42 +02:00
Carlos Garnacho
dc280ef2ad ui: Add PadOsd
This is an implementation of the pad OSD that's been previously
present in gnome-settings-daemon. Since things are moving closer
to the compositor, it makes sense to have this implemented as shell
UI.
2016-07-20 19:24:42 +02:00
78 changed files with 13093 additions and 12927 deletions

4
.gitignore vendored
View File

@@ -16,6 +16,7 @@ config.log
config.status
config
configure
data/50-gnome-shell-*.xml
data/org.gnome.Shell.desktop
data/org.gnome.Shell.desktop.in
data/gnome-shell-extension-prefs.desktop
@@ -25,6 +26,8 @@ data/gschemas.compiled
data/perf-background.xml
data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
data/org.gnome.shell.evolution.calendar.gschema.xml
data/org.gnome.shell.evolution.calendar.gschema.valid
data/org.gnome.Shell.PortalHelper.desktop
data/org.gnome.Shell.PortalHelper.service
data/theme/.sass-cache
@@ -71,6 +74,7 @@ src/*-marshal.[ch]
src/Makefile
src/Makefile.in
src/calendar-server/evolution-calendar.desktop
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/org.gnome.Shell.CalendarServer.service
src/gnome-shell
src/gnome-shell-calendar-server

71
NEWS
View File

@@ -1,74 +1,3 @@
3.21.92
=======
* Adjust screen capture to work with multiple stage views [Jonas; #770128]
* Improve handling of cycle shortcuts [Florian; #771063]
* Fix windows not getting undimmed in some cases [Rui; #770163, #752524]
* Disable extension version check by default [Florian; #770887]
* Misc. bug fixes [Rui, Florian, Michael; #770382, #770888, #770328]
Contributors:
Jonas Ådahl, Michael Catanzaro, Fran Dieguez, Olivier Fourdan, Rui Matos,
Florian Müllner
Translations:
Changwoo Ryu [ko], Baurzhan Muftakhidinov [kk], Aurimas Černius [lt],
Muhammet Kara [tr], Trần Ngọc Quân [vi], A S Alam [pa], Yosef Or Boczko [he],
Anders Jonsson [sv], Tiago Santos [pt], Hannie Dumoleyn [nl],
Rūdolfs Mazurs [lv], Claude Paroz [fr], Arash Mousavi [fa],
Fran Dieguez [gl], Stas Solovey [ru], Tom Tryfonidis [el]
3.21.91
=======
Translations:
Mario Blättermann [de], Jiri Grönroos [fi], Dušan Kazik [sk],
Andika Triwidada [id], Daniel Mustieles [es], Fabio Tomat [fur],
Enrico Nicoletto [pt_BR], Matej Urbančič [sl], Мирослав Николић [sr, sr@latin]
3.21.90.1
=========
Contributors:
Piotr Drąg
Translations:
Marek Černocký [cs], Balázs Úr [hu]
3.21.90
=======
* Improve on-screen keyboard on wayland [Carlos; #765009]
* Misc. bug fixes [Florian; #769156, #769216, #769074]
Contributors:
Carlos Garnacho, Florian Müllner
Translations:
Fabio Tomat [fur], Tiago Santos [pt], Daniel Mustieles [es],
Bernd Homuth [de], Aurimas Černius [lt], Balázs Úr [hu],
Yosef Or Boczko [he], Jiri Grönroos [fi], Marek Cernocky [cs],
Muhammet Kara [tr], Enrico Nicoletto [pt_BR], Andika Triwidada [id]
3.21.4
======
* overview: Fix switching workspaces when scrolling on non-primary monitors
[Florian; #766883, #768316]
* Fix crash when using screen recorder under wayland [Rui; #767001]
* Update theme on video memory purge errors [Rui; #739178]
* Free old backgrounds immediately [Hyungwon; #766353]
* Add support for system upgrades to end session dialog [Kalev; #763611]
* Fix maximized windows flickering to the wrong size on restart [Owen; #761566]
* Hide ignored events in calendar as well [Florian; #768538]
* calendar: Only hide dismissed occurrence of recurring event [Florian; #748226]
* Provide org.freedesktop.impl.portal.access implementation [Florian; #768669]
* Misc. bug fixes and cleanups [Rui, Florian, Marinus, Jonas; #767954, #768317,
#746867, #762206, #768956, #768979]
Contributors:
Jonas Ådahl, Piotr Drąg, Hyungwon Hwang, Kalev Lember, Rui Matos,
Florian Müllner, Marinus Schraal, Owen W. Taylor
Translations:
Andika Triwidada [id], Daniel Mustieles [es], Bruce Cowan [en_GB],
Dušan Kazik [sk], Piotr Drąg [pl], Chao-Hsiung Liao [zh_HK]
3.21.3
======
* Do not disable suspend action when locked [Florian; #725960]

View File

@@ -1,5 +1,5 @@
AC_PREREQ(2.63)
AC_INIT([gnome-shell],[3.21.92],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AC_INIT([gnome-shell],[3.21.3],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
AX_IS_RELEASE([git-directory])
AC_CONFIG_HEADERS([config.h])
@@ -24,14 +24,13 @@ LT_PREREQ([2.2.6])
LT_INIT([disable-static])
# i18n
IT_PROG_INTLTOOL([0.40])
GETTEXT_PACKAGE=gnome-shell
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.])
AM_GNU_GETTEXT_VERSION([0.19.6])
AM_GNU_GETTEXT([external])
PKG_PROG_PKG_CONFIG([0.22])
AC_PATH_PROG([XSLTPROC], [xsltproc])
@@ -76,9 +75,9 @@ AS_IF([test x$enable_systemd != xno], [
AC_MSG_RESULT($enable_systemd)
CLUTTER_MIN_VERSION=1.21.5
GOBJECT_INTROSPECTION_MIN_VERSION=1.49.1
GOBJECT_INTROSPECTION_MIN_VERSION=1.45.4
GJS_MIN_VERSION=1.39.0
MUTTER_MIN_VERSION=3.21.92
MUTTER_MIN_VERSION=3.21.3
GTK_MIN_VERSION=3.15.0
GIO_MIN_VERSION=2.45.3
LIBECAL_MIN_VERSION=3.5.3
@@ -255,6 +254,7 @@ AC_CONFIG_FILES([
docs/reference/st/Makefile
docs/reference/st/st-docs.sgml
js/Makefile
src/calendar-server/evolution-calendar.desktop.in
src/Makefile
src/gvc/Makefile
browser-plugin/Makefile

View File

@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.shell.keybindings"
group="system"
name="System"
_name="System"
wm_name="GNOME Shell"
package="gnome-shell">
<KeyListEntry name="toggle-message-tray"
description="Show the notification list"/>
_description="Show the notification list"/>
<KeyListEntry name="focus-active-notification"
description="Focus the active notification"/>
_description="Focus the active notification"/>
<KeyListEntry name="toggle-overview"
description="Show the overview"/>
_description="Show the overview"/>
<KeyListEntry name="toggle-application-view"
description="Show all applications"/>
_description="Show all applications"/>
<KeyListEntry name="open-application-menu"
description="Open the application menu"/>
_description="Open the application menu"/>
</KeyListEntries>

View File

@@ -14,9 +14,8 @@ servicedir = $(datadir)/dbus-1/services
service_DATA = org.gnome.Shell.PortalHelper.service
CLEANFILES += \
org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service \
org.gnome.Shell.PortalHelper.desktop \
$(NULL)
endif
@@ -32,12 +31,11 @@ endif
-e "s|@VERSION[@]|$(VERSION)|" \
$< > $@ || rm $@
%.desktop:%.desktop.in
$(AM_V_GEN) $(MSGFMT) --desktop --template $(builddir)/$< \
-d $(top_srcdir)/po -o $@
@INTLTOOL_DESKTOP_RULE@
introspectiondir = $(datadir)/dbus-1/interfaces
introspection_DATA = \
org.gnome.Shell.PadOsd.xml \
org.gnome.Shell.Screencast.xml \
org.gnome.Shell.Screenshot.xml \
org.gnome.ShellSearchProvider.xml \
@@ -86,11 +84,14 @@ perf-background.xml: perf-background.xml.in
$< > $@ || rm $@
keysdir = @GNOME_KEYBINDINGS_KEYSDIR@
keys_DATA = 50-gnome-shell-system.xml
keys_in_files = 50-gnome-shell-system.xml.in
keys_DATA = $(keys_in_files:.xml.in=.xml)
gsettings_SCHEMAS = org.gnome.shell.gschema.xml
%.gschema.xml: %.gschema.xml.in Makefile
@INTLTOOL_XML_NOMERGE_RULE@
%.gschema.xml.in: %.gschema.xml.in.in Makefile
$(AM_V_GEN) sed -e 's|@GETTEXT_PACKAGE[@]|$(GETTEXT_PACKAGE)|g' \
$< > $@ || rm $@
@@ -109,16 +110,16 @@ convert_DATA = gnome-shell-overrides.convert
EXTRA_DIST = \
org.gnome.Shell.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
$(portal_DATA) \
$(introspection_DATA) \
$(menu_DATA) \
$(convert_DATA) \
$(keys_DATA) \
$(keys_in_files) \
$(dist_theme_files) \
pad-osd.css \
perf-background.xml.in \
org.gnome.Shell.PortalHelper.desktop.in.in \
org.gnome.Shell.PortalHelper.desktop.in \
org.gnome.Shell.PortalHelper.service.in \
org.gnome.shell.gschema.xml.in \
org.gnome.shell.gschema.xml.in.in \
gnome-shell-theme.gresource.xml \
$(resource_files) \
$(NULL)
@@ -127,9 +128,11 @@ CLEANFILES += \
org.gnome.Shell.desktop.in \
gnome-shell-extension-prefs.in \
$(desktop_DATA) \
$(keys_DATA) \
$(gsettings_SCHEMAS) \
perf-background.xml \
gschemas.compiled \
org.gnome.shell.gschema.valid \
org.gnome.shell.gschema.xml.in \
gnome-shell-theme.gresource \
$(NULL)

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell Extension Preferences
Comment=Configure GNOME Shell Extensions
_Name=GNOME Shell Extension Preferences
_Comment=Configure GNOME Shell Extensions
Exec=@bindir@/gnome-shell-extension-prefs %u
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell

View File

@@ -22,6 +22,7 @@
<file>no-events.svg</file>
<file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>pad-osd.css</file>
<file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file>
<file>page-indicator-checked.svg</file>

View File

@@ -0,0 +1,28 @@
<!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.PadOSD:
@short_description: Pad OSD interface
The interface used to show button map OSD on pad devices.
-->
<interface name='org.gnome.Shell.Wacom.PadOsd'>
<!--
Show:
@device_node: device node file, usually in /dev/input/...
@edition_mode: whether toggling edition mode on when showing
Shows the pad button map OSD for the requested device, the OSD
will be shown according the current device settings (output
mapping, left handed mode, ...)
-->
<method name='Show'>
<arg name='device_node' direction='in' type='o'/>
<arg name='edition_mode' direction='in' type='b'/>
</method>
</interface>
</node>

View File

@@ -1,10 +1,9 @@
[Desktop Entry]
Name=Network Login
_Name=Network Login
Type=Application
Exec=gapplication launch org.gnome.Shell.PortalHelper
DBusActivatable=true
NoDisplay=true
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=network-workgroup
StartupNotify=true
OnlyShowIn=GNOME;

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=GNOME Shell
Comment=Window management and application launching
_Name=GNOME Shell
_Comment=Window management and application launching
Exec=@bindir@/gnome-shell
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-shell

View File

@@ -3,84 +3,84 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="development-tools" type="b">
<default>true</default>
<summary>
<_summary>
Enable internal tools useful for developers and testers from Alt-F2
</summary>
<description>
</_summary>
<_description>
Allows access to internal debugging and monitoring tools
using the Alt-F2 dialog.
</description>
</_description>
</key>
<key name="enabled-extensions" type="as">
<default>[]</default>
<summary>UUIDs of extensions to enable</summary>
<description>
<_summary>UUIDs of extensions to enable</_summary>
<_description>
GNOME Shell extensions have a UUID property; this key lists extensions
which should be loaded. Any extension that wants to be loaded needs
to be in this list. You can also manipulate this list with the
EnableExtension and DisableExtension D-Bus methods on org.gnome.Shell.
</description>
</_description>
</key>
<key name="disable-extension-version-validation" type="b">
<default>true</default>
<summary>Disables the validation of extension version compatibility</summary>
<description>
<default>false</default>
<_summary>Disables the validation of extension version compatibility</_summary>
<_description>
GNOME Shell will only load extensions that claim to support the current
running version. Enabling this option will disable this check and try to
load all extensions regardless of the versions they claim to support.
</description>
</_description>
</key>
<key name="favorite-apps" type="as">
<default>[ 'epiphany.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]</default>
<summary>List of desktop file IDs for favorite applications</summary>
<description>
<_summary>List of desktop file IDs for favorite applications</_summary>
<_description>
The applications corresponding to these identifiers
will be displayed in the favorites area.
</description>
</_description>
</key>
<key name="app-picker-view" type="u">
<default>0</default>
<summary>App Picker View</summary>
<description>
<_summary>App Picker View</_summary>
<_description>
Index of the currently selected view in the application picker.
</description>
</_description>
</key>
<key name="command-history" type="as">
<default>[]</default>
<summary>History for command (Alt-F2) dialog</summary>
<_summary>History for command (Alt-F2) dialog</_summary>
</key>
<key name="looking-glass-history" type="as">
<default>[]</default>
<!-- Translators: looking glass is a debugger and inspector tool, see https://wiki.gnome.org/Projects/GnomeShell/LookingGlass -->
<summary>History for the looking glass dialog</summary>
<_summary>History for the looking glass dialog</_summary>
</key>
<key name="always-show-log-out" type="b">
<default>false</default>
<summary>Always show the 'Log out' menu item in the user menu.</summary>
<description>
<_summary>Always show the 'Log out' menu item in the user menu.</_summary>
<_description>
This key overrides the automatic hiding of the 'Log out'
menu item in single-user, single-session situations.
</description>
</_description>
</key>
<key name="remember-mount-password" type="b">
<default>false</default>
<summary>Whether to remember password for mounting encrypted or remote filesystems</summary>
<description>
<_summary>Whether to remember password for mounting encrypted or remote filesystems</_summary>
<_description>
The shell will request a password when an encrypted device or a
remote filesystem is mounted. If the password can be saved for
future use a 'Remember Password' checkbox will be present.
This key sets the default state of the checkbox.
</description>
</_description>
</key>
<key name="had-bluetooth-devices-setup" type="b">
<default>false</default>
<summary>Whether the default Bluetooth adapter had set up devices associated to it</summary>
<description>
<_summary>Whether the default Bluetooth adapter had set up devices associated to it</_summary>
<_description>
The shell will only show a Bluetooth menu item if a Bluetooth
adapter is powered, or if there were devices set up associated
with the default adapter. This will be reset if the default
adapter is ever seen not to have devices associated to it.
</description>
</_description>
</key>
<child name="keybindings" schema="org.gnome.shell.keybindings"/>
<child name="keyboard" schema="org.gnome.shell.keyboard"/>
@@ -90,44 +90,44 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="open-application-menu" type="as">
<default>["&lt;Super&gt;F10"]</default>
<summary>Keybinding to open the application menu</summary>
<description>
<_summary>Keybinding to open the application menu</_summary>
<_description>
Keybinding to open the application menu.
</description>
</_description>
</key>
<key name="toggle-application-view" type="as">
<default>["&lt;Super&gt;a"]</default>
<summary>Keybinding to open the "Show Applications" view</summary>
<description>
<_summary>Keybinding to open the "Show Applications" view</_summary>
<_description>
Keybinding to open the "Show Applications" view of the Activities
Overview.
</description>
</_description>
</key>
<key name="toggle-overview" type="as">
<default>["&lt;Super&gt;s"]</default>
<summary>Keybinding to open the overview</summary>
<description>
<_summary>Keybinding to open the overview</_summary>
<_description>
Keybinding to open the Activities Overview.
</description>
</_description>
</key>
<key name="toggle-message-tray" type="as">
<default>["&lt;Super&gt;v","&lt;Super&gt;m"]</default>
<summary>Keybinding to toggle the visibility of the notification list</summary>
<description>
<_summary>Keybinding to toggle the visibility of the notification list</_summary>
<_description>
Keybinding to toggle the visibility of the notification list.
</description>
</_description>
</key>
<key name="focus-active-notification" type="as">
<default>["&lt;Super&gt;n"]</default>
<summary>Keybinding to focus the active notification</summary>
<description>
<_summary>Keybinding to focus the active notification</_summary>
<_description>
Keybinding to focus the active notification.
</description>
</_description>
</key>
<key name="pause-resume-tweens" type="as">
<default>[]</default>
<summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</summary>
<description></description>
<_summary>Keybinding that pauses and resumes all running tweens, for debugging purposes</_summary>
<_description></_description>
</key>
</schema>
@@ -135,10 +135,10 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="keyboard-type" type="s">
<default>'touch'</default>
<summary>Which keyboard to use</summary>
<description>
<_summary>Which keyboard to use</_summary>
<_description>
The type of keyboard to use.
</description>
</_description>
</key>
</schema>
@@ -147,11 +147,11 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key type="b" name="current-workspace-only">
<default>false</default>
<summary>Limit switcher to current workspace.</summary>
<description>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
If true, only applications that have windows on the current workspace are shown in the switcher.
Otherwise, all applications are included.
</description>
</_description>
</key>
</schema>
@@ -165,20 +165,20 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="app-icon-mode" enum="org.gnome.shell.window-switcher.AppIconMode">
<default>'both'</default>
<summary>The application icon mode.</summary>
<description>
<_summary>The application icon mode.</_summary>
<_description>
Configures how the windows are shown in the switcher. Valid possibilities
are 'thumbnail-only' (shows a thumbnail of the window), 'app-icon-only'
(shows only the application icon) or 'both'.
</description>
</_description>
</key>
<key type="b" name="current-workspace-only">
<default>true</default>
<summary>Limit switcher to current workspace.</summary>
<description>
<_summary>Limit switcher to current workspace.</_summary>
<_description>
If true, only windows from the current workspace are shown in the switcher.
Otherwise, all windows are included.
</description>
</_description>
</key>
</schema>
@@ -186,43 +186,43 @@
gettext-domain="@GETTEXT_PACKAGE@">
<key name="attach-modal-dialogs" type="b">
<default>true</default>
<summary>Attach modal dialog to the parent window</summary>
<description>
<_summary>Attach modal dialog to the parent window</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running
GNOME Shell.
</description>
</_description>
</key>
<key name="edge-tiling" type="b">
<default>true</default>
<summary>Enable edge tiling when dropping windows on screen edges</summary>
<description>
<_summary>Enable edge tiling when dropping windows on screen edges</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="dynamic-workspaces" type="b">
<default>true</default>
<summary>Workspaces are managed dynamically</summary>
<description>
<_summary>Workspaces are managed dynamically</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="workspaces-only-on-primary" type="b">
<default>true</default>
<summary>Workspaces only on primary monitor</summary>
<description>
<_summary>Workspaces only on primary monitor</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
<key name="focus-change-on-pointer-rest" type="b">
<default>true</default>
<summary>Delay focus changes in mouse mode until the pointer stops moving</summary>
<description>
<_summary>Delay focus changes in mouse mode until the pointer stops moving</_summary>
<_description>
This key overrides the key in org.gnome.mutter when running GNOME Shell.
</description>
</_description>
</key>
</schema>
</schemalist>

View File

@@ -604,10 +604,6 @@ StScrollBar {
width: 96px;
height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */
.workspace-switcher-group {
padding: 12px; }

View File

@@ -562,6 +562,10 @@ StScrollBar {
background-color: #eeeeec;
border-radius: 0.3em; }
.pad-osd-window {
background-color: rgba(0, 0, 0, 0.8);
}
/* App Switcher */
.switcher-popup {
padding: 8px;
@@ -604,10 +608,6 @@ StScrollBar {
width: 96px;
height: 96px; }
/* Window Cycler */
.cycler-highlight {
border: 5px solid #215d9c; }
/* Workspace Switcher */
.workspace-switcher-group {
padding: 12px; }

30
data/theme/pad-osd.css Normal file
View File

@@ -0,0 +1,30 @@
.Leader {
stroke-width: .5 !important;
stroke: #535353;
fill: none !important;
}
.Button {
stroke-width: .25;
stroke: #ededed;
fill: #ededed;
}
.Ring {
stroke-width: .5 !important;
stroke: #535353 !important;
fill: none !important;
}
.Label {
stroke: none !important;
stroke-width: .1 !important;
font-size: .1 !important;
fill: transparent !important;
}
.TouchStrip, .TouchRing {
stroke-width: .1 !important;
stroke: #ededed !important;
fill: #535353 !important;
}

View File

@@ -804,11 +804,6 @@ const LoginDialog = new Lang.Class({
this._user = null;
if (this._nextSignalId) {
this._authPrompt.disconnect(this._nextSignalId);
this._nextSignalId = 0;
}
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
if (!this._disableUserList)
this._showUserList();

View File

@@ -72,6 +72,7 @@
<file>ui/osdMonitorLabeler.js</file>
<file>ui/overview.js</file>
<file>ui/overviewControls.js</file>
<file>ui/padOsd.js</file>
<file>ui/panel.js</file>
<file>ui/panelMenu.js</file>
<file>ui/pointerWatcher.js</file>

View File

@@ -354,67 +354,6 @@ const AppSwitcherPopup = new Lang.Class({
}
});
const CyclerHighlight = new Lang.Class({
Name: 'CyclerHighlight',
_init: function() {
this._window = null;
this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout() });
this._clone = new Clutter.Clone();
this.actor.add_actor(this._clone);
this._highlight = new St.Widget({ style_class: 'cycler-highlight' });
this.actor.add_actor(this._highlight);
let coordinate = Clutter.BindCoordinate.ALL;
let constraint = new Clutter.BindConstraint({ coordinate: coordinate });
this._clone.bind_property('source', constraint, 'source', 0);
this.actor.add_constraint(constraint);
this.actor.connect('notify::allocation',
Lang.bind(this, this._onAllocationChanged));
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
},
set window(w) {
if (this._window == w)
return;
this._window = w;
if (this._clone.source)
this._clone.source.show();
let windowActor = this._window ? this._window.get_compositor_private()
: null;
if (windowActor)
windowActor.hide();
this._clone.source = windowActor;
},
_onAllocationChanged: function() {
if (!this._window) {
this._highlight.set_size(0, 0);
this._highlight.hide();
} else {
let [x, y] = this.actor.allocation.get_origin();
let rect = this._window.get_frame_rect();
this._highlight.set_size(rect.width, rect.height);
this._highlight.set_position(rect.x - x, rect.y - y);
this._highlight.show();
}
},
_onDestroy: function() {
this.window = null;
}
});
const CyclerPopup = new Lang.Class({
Name: 'CyclerPopup',
Extends: SwitcherPopup.SwitcherPopup,
@@ -428,9 +367,6 @@ const CyclerPopup = new Lang.Class({
if (this._items.length == 0)
return;
this._highlight = new CyclerHighlight();
global.window_group.add_actor(this._highlight.actor);
// We don't show an actual popup, so just provide what SwitcherPopup
// expects instead of inheriting from SwitcherList
this._switcherList = { actor: new St.Widget(),
@@ -439,18 +375,11 @@ const CyclerPopup = new Lang.Class({
},
_highlightItem: function(index, justOutline) {
this._highlight.window = this._items[index];
global.window_group.set_child_above_sibling(this._highlight.actor, null);
Main.activateWindow(this._items[index]);
},
_finish: function() {
Main.activateWindow(this._items[this._selectedIndex]);
this.parent();
},
_onDestroy: function() {
this._highlight.actor.destroy();
this._highlightItem(this._selectedIndex);
this.parent();
}

View File

@@ -475,11 +475,6 @@ const ChatSource = new Lang.Class({
this._channel.close_async(function(channel, result) {
channel.close_finish(result);
});
} else {
// Don't indicate any unread messages when the notification
// that represents them has been destroyed.
this._pendingMessages = [];
this.countUpdated();
}
// Keep source alive while the channel is open

View File

@@ -10,7 +10,6 @@ const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const InputSourceManager = imports.ui.status.keyboard;
const BoxPointer = imports.ui.boxpointer;
const Layout = imports.ui.layout;
@@ -758,48 +757,19 @@ const ShellWaylandAdapter = new Lang.Class({
Name: 'ShellWaylandAdapter',
Extends: Caribou.XAdapter,
_init: function () {
this.parent();
let deviceManager = Clutter.DeviceManager.get_default();
this._virtualDevice = deviceManager.create_virtual_device(Clutter.InputDeviceType.KEYBOARD_DEVICE);
this._inputSourceManager = InputSourceManager.getInputSourceManager();
this._sourceChangedId = this._inputSourceManager.connect('current-source-changed',
Lang.bind(this, this._onSourceChanged));
this._sourcesModifiedId = this._inputSourceManager.connect ('sources-changed',
Lang.bind(this, this._onSourcesModified));
},
_onSourcesModified: function () {
this.emit('config-changed');
},
_onSourceChanged: function (inputSourceManager, oldSource) {
let source = inputSourceManager.currentSource;
this.emit('group-changed', source.index, source.id, '');
},
vfunc_get_groups: function () {
let inputSources = this._inputSourceManager.inputSources;
let groups = []
let variants = [];
for (let i in inputSources) {
let is = inputSources[i];
groups[is.index] = is.id;
variants[is.index] = '';
}
return [groups, groups.length, variants, variants.length];
},
vfunc_keyval_press: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.PRESSED);
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
Shell.util_text_insert_keyval(focus, keyval);
else
this.parent(keyval);
},
vfunc_keyval_release: function(keyval) {
this._virtualDevice.notify_keyval(Clutter.get_current_event_time(),
keyval, Clutter.KeyState.RELEASED);
let focus = global.stage.get_key_focus();
if (focus instanceof Clutter.Text)
return; // do nothing
else
this.parent(keyval);
},
});

View File

@@ -26,6 +26,7 @@ const ModalDialog = imports.ui.modalDialog;
const OsdWindow = imports.ui.osdWindow;
const OsdMonitorLabeler = imports.ui.osdMonitorLabeler;
const Overview = imports.ui.overview;
const PadOsd = imports.ui.padOsd;
const Panel = imports.ui.panel;
const Params = imports.misc.params;
const RunDialog = imports.ui.runDialog;
@@ -61,6 +62,7 @@ let screenShield = null;
let notificationDaemon = null;
let windowAttentionHandler = null;
let ctrlAltTabManager = null;
let padOsdService = null;
let osdWindowManager = null;
let osdMonitorLabeler = null;
let sessionMode = null;
@@ -155,6 +157,7 @@ function _initializeUI() {
// working until it's updated.
uiGroup = layoutManager.uiGroup;
padOsdService = new PadOsd.PadOsdService();
screencastService = new Screencast.ScreencastService();
xdndHandler = new XdndHandler.XdndHandler();
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();

733
js/ui/padOsd.js Normal file
View File

@@ -0,0 +1,733 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Rsvg = imports.gi.Rsvg;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;
const GDesktopEnums = imports.gi.GDesktopEnums;
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Signals = imports.signals;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Layout = imports.ui.layout;
const ACTIVE_COLOR = "#729fcf";
const LTR = 0;
const RTL = 1;
const CW = 0;
const CCW = 1;
const UP = 0;
const DOWN = 1;
const KeybindingEntry = new Lang.Class({
Name: 'KeybindingEntry',
_init: function () {
this.actor = new St.Entry({ hint_text: _('New shortcut...'),
width: 120 });
this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
this.actor.connect('destroy', Lang.bind(this, this.destroy));
},
_onCapturedEvent: function (actor, event) {
if (event.type() == Clutter.EventType.KEY_PRESS) {
if (GLib.unichar_isprint(event.get_key_unicode())) {
let str = Gtk.accelerator_name_with_keycode(null,
event.get_key_symbol(),
event.get_key_code(),
event.get_state());
this.actor.set_text(str);
this.emit('keybinding', str);
}
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
},
destroy: function () {
this.actor.destroy();
}
});
Signals.addSignalMethods(KeybindingEntry.prototype);
const ActionComboBox = new Lang.Class({
Name: 'ActionComboBox',
_init: function () {
this.actor = new St.Button({ style_class: 'button' });
this.actor.connect('clicked', Lang.bind(this, this._onButtonClicked));
this.actor.set_toggle_mode(true);
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 6 });
let box = new St.Widget({ layout_manager: boxLayout });
this.actor.set_child(box);
this._label = new St.Label({ width: 150 });
box.add_child(this._label)
let arrow = new St.Icon({ style_class: 'popup-menu-arrow',
icon_name: 'pan-down-symbolic',
accessible_role: Atk.Role.ARROW,
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
box.add_child(arrow);
/* Order matches GDesktopPadButtonAction enum */
this._actions = [_('Application defined'),
_('Show on-screen help'),
_('Switch monitor'),
_('Assign keystroke')];
this._editMenu = new PopupMenu.PopupMenu(this.actor, 0, St.Side.TOP);
this._editMenu.connect('menu-closed', Lang.bind(this, function() { this.actor.set_checked(false); }));
this._editMenu.actor.hide();
Main.uiGroup.add_actor(this._editMenu.actor);
for (let i = 0; i < this._actions.length; i++) {
let str = this._actions[i];
let action = i;
this._editMenu.addAction(str, Lang.bind(this, function() { this._onActionSelected(action) }));
}
this.setAction(GDesktopEnums.PadButtonAction.NONE);
},
_onActionSelected: function (action) {
this.setAction(action);
this.popdown();
this.emit('action', action);
},
setAction: function (action) {
this._label.set_text(this._actions[action]);
},
popup: function () {
this._editMenu.open(true);
},
popdown: function () {
this._editMenu.close(true);
},
_onButtonClicked: function () {
if (this.actor.get_checked())
this.popup();
else
this.popdown();
}
});
Signals.addSignalMethods(ActionComboBox.prototype);
const ActionEditor = new Lang.Class({
Name: 'ActionEditor',
_init: function () {
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.HORIZONTAL,
spacing: 12 });
this.actor = new St.Widget({ layout_manager: boxLayout });
this._actionComboBox = new ActionComboBox();
this._actionComboBox.connect('action', Lang.bind(this, this._onActionSelected));
this.actor.add_actor(this._actionComboBox.actor);
this._keybindingEdit = new KeybindingEntry();
this._keybindingEdit.connect('keybinding', Lang.bind(this, this._onKeybindingEdited));
this._keybindingEdit.actor.hide();
this.actor.add_actor(this._keybindingEdit.actor);
this._doneButton = new St.Button ({ label: _('Done'),
width: 100,
style_class: 'button'});
this._doneButton.connect('clicked', Lang.bind(this, this._onEditingDone));
this.actor.add_actor(this._doneButton);
},
setSettings: function (settings) {
this._buttonSettings = settings;
this._currentAction = this._buttonSettings.get_enum('action');
this._currentKeybinding = this._buttonSettings.get_string('keybinding');
this._actionComboBox.setAction (this._currentAction);
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING) {
this._keybindingEdit.actor.set_text(this._currentKeybinding);
this._keybindingEdit.actor.show();
} else {
this._keybindingEdit.actor.hide();
}
},
close: function() {
this._actionComboBox.popdown();
this.actor.hide();
},
_onKeybindingEdited: function (entry, keybinding) {
this._currentKeybinding = keybinding;
},
_onActionSelected: function (menu, action) {
this._currentAction = action;
if (action == GDesktopEnums.PadButtonAction.KEYBINDING) {
this._keybindingEdit.actor.show();
this._keybindingEdit.actor.grab_key_focus();
} else {
this._keybindingEdit.actor.hide();
}
},
_storeSettings: function () {
if (!this._buttonSettings)
return;
let keybinding = null;
if (this._currentAction == GDesktopEnums.PadButtonAction.KEYBINDING)
keybinding = this._currentKeybinding;
this._buttonSettings.set_enum('action', this._currentAction);
if (keybinding)
this._buttonSettings.set_string('keybinding', keybinding);
else
this._buttonSettings.reset('keybinding');
},
_onEditingDone: function () {
this._storeSettings();
this.close();
this.emit ('done');
}
});
Signals.addSignalMethods(ActionEditor.prototype);
const PadDiagram = new Lang.Class({
Name: 'PadDiagram',
Extends: St.DrawingArea,
_init: function (imagePath, leftHanded) {
this.parent();
let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/pad-osd.css');
let [success, css, etag] = file.load_contents(null);
this._css = css;
let originalHandle = Rsvg.Handle.new_from_file(imagePath);
let dimensions = originalHandle.get_dimensions();
this._imageWidth = dimensions.width;
this._imageHeight = dimensions.height;
this._activeButtons = [];
this._imagePath = imagePath;
this._handle = this._composeStyledDiagram();
this.connect('repaint', Lang.bind(this, this._repaint));
this.connect('notify::size', Lang.bind(this, this._updateScale));
this._leftHanded = leftHanded;
},
_wrappingSvgHeader: function () {
return ('<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ' +
'xmlns:xi="http://www.w3.org/2001/XInclude" ' +
'width="' + this._imageWidth + '" height="' + this._imageHeight + '"> ' +
'<style type="text/css">');
},
_wrappingSvgFooter: function () {
return ('</style>' +
'<xi:include href="' + this._imagePath + '" />' +
'</svg>');
},
_cssString: function () {
let css = this._css;
for (let i = 0; i < this._activeButtons.length; i++) {
let ch = String.fromCharCode('A'.charCodeAt() + this._activeButtons[i]);
css += ('.' + ch + ' { ' +
' stroke: ' + ACTIVE_COLOR + ' !important; ' +
' fill: ' + ACTIVE_COLOR + ' !important; ' +
'} ');
}
return css;
},
_composeStyledDiagram: function () {
let svgData = '';
if (!GLib.file_test(this._imagePath, GLib.FileTest.EXISTS))
return null;
svgData += this._wrappingSvgHeader();
svgData += this._cssString();
svgData += this._wrappingSvgFooter();
let handle = new Rsvg.Handle();
handle.set_base_uri (GLib.path_get_dirname (this._imagePath));
handle.write(svgData);
handle.close();
return handle;
},
_updateScale: function () {
let [width, height] = this.get_size();
let dimensions = this._handle.get_dimensions ();
let scaleX = width / dimensions.width;
let scaleY = height / dimensions.height;
this._scale = Math.min(scaleX, scaleY);
},
_repaint: function (area) {
if (this._handle == null)
return;
let [width, height] = area.get_surface_size();
let dimensions = this._handle.get_dimensions ();
let cr = this.get_context();
if (this._scale == null)
this._updateScale();
cr.save();
cr.translate (width/2, height/2);
cr.scale (this._scale, this._scale);
if (this._leftHanded)
cr.rotate(Math.PI);
cr.translate (-dimensions.width/2, -dimensions.height/2);
this._handle.render_cairo(cr);
cr.restore();
cr.$dispose();
},
_transformPoint: function (x, y) {
if (this._handle == null || this._scale == null)
return [x, y];
// I miss Cairo.Matrix
let [width, height] = this.get_size();
let dimensions = this._handle.get_dimensions ();
x = x * this._scale + width / 2 - dimensions.width / 2 * this._scale;
y = y * this._scale + height / 2 - dimensions.height / 2 * this._scale;;
return [Math.round(x), Math.round(y)];
},
_getItemLabelCoords: function (labelName, leaderName) {
if (this._handle == null)
return [false];
let leaderPos, leaderSize, pos;
let found, direction;
[found, pos] = this._handle.get_position_sub('#' + labelName);
if (!found)
return [false];
[found, leaderPos] = this._handle.get_position_sub('#' + leaderName);
[found, leaderSize] = this._handle.get_dimensions_sub('#' + leaderName);
if (!found)
return [false];
if (pos.x > leaderPos.x + leaderSize.width)
direction = LTR;
else
direction = RTL;
if (this._leftHanded) {
direction = 1 - direction;
pos.x = this._imageWidth - pos.x;
pos.y = this._imageHeight - pos.y;
}
let [x, y] = this._transformPoint(pos.x, pos.y)
return [true, x, y, direction];
},
getButtonLabelCoords: function (button) {
let ch = String.fromCharCode('A'.charCodeAt() + button);
let labelName = 'Label' + ch;
let leaderName = 'Leader' + ch;
return this._getItemLabelCoords(labelName, leaderName);
},
getRingLabelCoords: function (number, dir) {
let numStr = number > 0 ? number.toString() : '';
let dirStr = dir == CW ? 'CW' : 'CCW';
let labelName = 'LabelRing' + numStr + dirStr;
let leaderName = 'LeaderRing' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
},
getStripLabelCoords: function (number, dir) {
let numStr = number > 0 ? (number + 1).toString() : '';
let dirStr = dir == UP ? 'Up' : 'Down';
let labelName = 'LabelStrip' + numStr + dirStr;
let leaderName = 'LeaderStrip' + numStr + dirStr;
return this._getItemLabelCoords(labelName, leaderName);
},
_invalidateSvg: function () {
if (this._handle == null)
return;
this._handle = this._composeStyledDiagram();
this.queue_repaint();
},
activateButton: function (button) {
this._activeButtons.push(button);
this._invalidateSvg ();
},
deactivateButton: function (button) {
for (let i = 0; i < this._activeButtons.length; i++) {
if (this._activeButtons[i] == button)
this._activeButtons.splice(i, 1);
}
this._invalidateSvg ();
}
});
const PadOsd = new Lang.Class({
Name: 'PadOsd',
_init: function (padDevice, settings, imagePath, editionMode, monitorIndex) {
this.padDevice = padDevice;
this._settings = settings;
this._imagePath = imagePath;
this._editionMode = editionMode;
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
this.actor = new Shell.GenericContainer({ style_class: 'pad-osd-window',
reactive: true,
x: 0,
y: 0,
width: global.screen_width,
height: global.screen_height });
this.actor.connect('allocate', Lang.bind(this, this._allocate));
this.actor.connect('destroy', Lang.bind(this, this.destroy));
Main.uiGroup.add_actor(this.actor);
this._monitorIndex = monitorIndex;
let constraint = new Layout.MonitorConstraint({ index: monitorIndex });
this.actor.add_constraint(constraint);
this._padDiagram = new PadDiagram(this._imagePath, settings.get_boolean('left-handed'));
this.actor.add_actor(this._padDiagram);
this._buttonBox = new St.Widget({ layout_manager: new Clutter.BinLayout(),
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this._editButton = new St.Button({ label: _('Edit...'),
style_class: 'button',
can_focus: true,
x_expand: true });
this._editButton.connect('clicked', Lang.bind(this, function () { this.setEditionMode(true) }));
this._buttonBox.add_actor(this._editButton);
this.actor.add_actor(this._buttonBox);
let boxLayout = new Clutter.BoxLayout({ orientation: Clutter.Orientation.VERTICAL });
this._labelBox = new St.Widget({ layout_manager: boxLayout,
x_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER });
this._titleLabel = new St.Label();
this._titleLabel.clutter_text.set_markup('<span size="larger"><b>' + padDevice.get_device_name() + '</b></span>');
this._labelBox.add_actor(this._titleLabel);
this._tipLabel = new St.Label();
this._labelBox.add_actor(this._tipLabel);
this.actor.add_actor(this._labelBox);
this._actionEditor = new ActionEditor();
this._actionEditor.connect ('done', Lang.bind(this, this._endButtonActionEdition));
this.actor.add_actor(this._actionEditor.actor);
this._labels = [];
this._ringLabels = [];
this._stripLabels = [];
// FIXME: Fix num buttons.
let i = 0;
for (i = 0; i < 50; i++) {
let [found, x, y, direction] = this._padDiagram.getButtonLabelCoords(i);
if (!found)
break;
let label = this._createLabel(i, Meta.PadActionType.BUTTON);
this._labels.push(label);
}
for (i = 0; i < padDevice.get_n_rings(); i++) {
let [found, x, y, direction] = this._padDiagram.getRingLabelCoords(i, CW);
let [found2, x2, y2, direction2] = this._padDiagram.getRingLabelCoords(i, CCW);
if (!found || !found2)
break;
let label1 = this._createLabel(i, Meta.PadActionType.RING);
let label2 = this._createLabel(i, Meta.PadActionType.RING);
this._ringLabels.push([label1, label2]);
}
for (i = 0; i < padDevice.get_n_strips(); i++) {
let [found, x, y, direction] = this._padDiagram.getStripLabelCoords(i, UP);
let [found2, x2, y2, direction2] = this._padDiagram.getStripLabelCoords(i, DOWN);
if (!found || !found2)
break;
let label1 = this._createLabel(i, Meta.PadActionType.STRIP);
let label2 = this._createLabel(i, Meta.PadActionType.STRIP);
this._stripLabels.push([label1, label2]);
}
this._syncEditionMode();
},
_createLabel: function (number, type) {
let str = global.display.get_pad_action_label(this.padDevice, type, number);
let label = new St.Label({ text: str ? str : _('None') });
this.actor.add_actor(label);
return label;
},
_allocateChild: function (child, x, y, direction, box) {
let [prefHeight, natHeight] = child.get_preferred_height (-1);
let [prefWidth, natWidth] = child.get_preferred_width (natHeight);
let childBox = new Clutter.ActorBox();
natWidth = Math.min(natWidth, 250);
if (direction == LTR) {
childBox.x1 = x + box.x1;
childBox.x2 = x + box.x1 + natWidth;
} else {
childBox.x1 = x + box.x1 - natWidth;
childBox.x2 = x + box.x1;
}
childBox.y1 = y + box.y1 - natHeight / 2;
childBox.y2 = y + box.y1 + natHeight / 2;
child.allocate(childBox, 0);
},
_allocate: function (actor, box, flags) {
let [prefLabelHeight, natLabelHeight] = this._labelBox.get_preferred_height(box.x2 - box.x1);
let buttonY = Math.max((box.y2 - box.y1) * 3 / 4 + box.y1, (box.y2 - box.y1) - 100);
let childBox = new Clutter.ActorBox();
let diagramBox = new Clutter.ActorBox();
diagramBox.x1 = box.x1;
diagramBox.x2 = box.x2;
diagramBox.y1 = prefLabelHeight;
diagramBox.y2 = buttonY;
this._padDiagram.allocate(diagramBox, flags);
childBox.x1 = box.x1;
childBox.x2 = box.x2;
childBox.y1 = buttonY;
childBox.y2 = box.y2;
this._buttonBox.allocate(childBox, flags);
childBox.y1 = 0;
childBox.y2 = prefLabelHeight;
this._labelBox.allocate(childBox, flags);
for (let i = 0; i < this._labels.length; i++) {
let label = this._labels[i];
let [found, x, y, direction] = this._padDiagram.getButtonLabelCoords(i);
this._allocateChild(label, x, y, direction, diagramBox);
}
for (let i = 0; i < this._ringLabels.length; i++) {
let [label1, label2] = this._ringLabels[i];
let [found, x, y, direction] = this._padDiagram.getRingLabelCoords(i, CW);
this._allocateChild(label1, x, y, direction, diagramBox);
[found, x, y, direction] = this._padDiagram.getRingLabelCoords(i, CCW);
this._allocateChild(label2, x, y, direction, diagramBox);
}
for (let i = 0; i < this._stripLabels.length; i++) {
let [label1, label2] = this._stripLabels[i];
let [found, x, y, direction] = this._padDiagram.getStripLabelCoords(i, UP);
this._allocateChild(label1, x, y, direction, diagramBox);
[found, x, y, direction] = this._padDiagram.getStripLabelCoords(i, DOWN);
this._allocateChild(label2, x, y, direction, diagramBox);
}
if (this._editingButtonAction != null) {
let [found, x, y, direction] = this._padDiagram.getButtonLabelCoords(this._editingButtonAction);
this._allocateChild(this._actionEditor.actor, x, y, direction, diagramBox);
}
},
_onCapturedEvent : function (actor, event) {
if (event.type() == Clutter.EventType.PAD_BUTTON_PRESS &&
event.get_source_device() == this.padDevice) {
this._padDiagram.activateButton(event.get_button());
if (this._editionMode)
this._startButtonActionEdition(event.get_button());
return Clutter.EVENT_STOP;
} else if (event.type() == Clutter.EventType.PAD_BUTTON_RELEASE &&
event.get_source_device() == this.padDevice) {
this._padDiagram.deactivateButton(event.get_button());
return Clutter.EVENT_STOP;
} else if (event.type() == Clutter.EventType.KEY_PRESS &&
(!this._editionMode || event.get_key_symbol() == Clutter.Escape)) {
if (this._editingButtonAction != null)
this._endButtonActionEdition();
else
this.destroy();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
},
_syncEditionMode: function () {
this._editButton.set_reactive(!this._editionMode);
this._editButton.save_easing_state();
this._editButton.set_easing_duration(200);
this._editButton.set_opacity(this._editionMode ? 128 : 255);
this._editButton.restore_easing_state();
let title;
if (this._editionMode) {
title = _('Press a button to configure');
this._tipLabel.set_text (_("Press Esc to exit"));
} else {
title = this.padDevice.get_device_name();
this._tipLabel.set_text (_("Press any key to exit"));
}
this._titleLabel.clutter_text.set_markup('<span size="larger"><b>' + title + '</b></span>');
},
_endButtonActionEdition: function () {
this._actionEditor.close();
if (this._editingButtonAction != null) {
// Update and show the label
let str = global.display.get_pad_action_label(this.padDevice,
Meta.PadActionType.BUTTON,
this._editingButtonAction);
this._labels[this._editingButtonAction].set_text(str ? str : _('None'));
this._labels[this._editingButtonAction].show();
this._editingButtonAction = null;
}
this._editedButtonSettings = null;
},
_startButtonActionEdition: function (button) {
if (this._editingButtonAction == button)
return;
this._endButtonActionEdition();
this._editingButtonAction = button;
this._labels[this._editingButtonAction].hide();
this._actionEditor.actor.show();
this.actor.queue_relayout();
let ch = String.fromCharCode('A'.charCodeAt() + button);
let settingsPath = this._settings.path + "button" + ch + '/';
this._editedButtonSettings = Gio.Settings.new_with_path('org.gnome.desktop.peripherals.tablet.pad-button',
settingsPath);
this._actionEditor.setSettings (this._editedButtonSettings);
},
setEditionMode: function (editionMode) {
if (this._editionMode == editionMode)
return;
this._editionMode = editionMode;
this._syncEditionMode();
},
destroy: function () {
this._actionEditor.close();
if (this._capturedEventId != 0) {
global.stage.disconnect(this._capturedEventId);
this._capturedEventId = 0;
}
if (this.actor) {
let actor = this.actor;
this.actor = null;
actor.destroy();
this.emit('closed');
}
}
});
Signals.addSignalMethods(PadOsd.prototype);
const PadOsdIface = '<node> \
<interface name="org.gnome.Shell.Wacom.PadOsd"> \
<method name="Show"> \
<arg name="device_node" direction="in" type="o"/> \
<arg name="edition_mode" direction="in" type="b"/> \
</method> \
</interface> \
</node>';
const PadOsdService = new Lang.Class({
Name: 'PadOsdService',
_init: function() {
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(PadOsdIface, this);
this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell/Wacom');
Gio.DBus.session.own_name('org.gnome.Shell.Wacom.PadOsd', Gio.BusNameOwnerFlags.REPLACE, null, null);
},
ShowAsync: function(params, invocation) {
let [deviceNode, editionMode] = params;
let deviceManager = Clutter.DeviceManager.get_default();
let devices = deviceManager.list_devices();
let padDevice = null;
devices.forEach(Lang.bind(this, function(device) {
if (deviceNode == device.get_device_node())
padDevice = device;
}));
if (padDevice == null ||
padDevice.get_device_type() != Clutter.InputDeviceType.PAD_DEVICE) {
invocation.return_error_literal(Gio.IOErrorEnum,
Gio.IOErrorEnum.CANCELLED,
"Invalid params");
return;
}
global.display.request_pad_osd(padDevice, editionMode);
invocation.return_value(null);
}
});
Signals.addSignalMethods(PadOsdService.prototype);

View File

@@ -17,6 +17,7 @@ const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const WindowMenu = imports.ui.windowMenu;
const PadOsd = imports.ui.padOsd;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const MINIMIZE_WINDOW_ANIMATION_TIME = 0.2;
@@ -915,6 +916,7 @@ const WindowManager = new Lang.Class({
Lang.bind(this, this._toggleCalendar));
global.display.connect('show-resize-popup', Lang.bind(this, this._showResizePopup));
global.display.connect('show-pad-osd', Lang.bind(this, this._showPadOsd));
Main.overview.connect('showing', Lang.bind(this, function() {
for (let i = 0; i < this._dimmedWindows.length; i++)
@@ -944,7 +946,19 @@ const WindowManager = new Lang.Class({
gesture = new AppSwitchAction();
gesture.connect('activated', Lang.bind(this, this._switchApp));
global.stage.add_action(gesture);
},
_showPadOsd: function (display, device, settings, imagePath, editionMode, monitorIndex) {
if (this._currentPadOsd != null) {
if (this._currentPadOsd.padDevice == device)
this._currentPadOsd.destroy();
return null;
}
this._currentPadOsd = new PadOsd.PadOsd(device, settings, imagePath, editionMode, monitorIndex);
this._currentPadOsd.connect('closed', Lang.bind(this, function() { this._currentPadOsd = null }));
return this._currentPadOsd.actor;
},
_actionSwitchWorkspace: function(action, direction) {
@@ -1349,13 +1363,9 @@ const WindowManager = new Lang.Class({
_hasAttachedDialogs: function(window, ignoreWindow) {
var count = 0;
window.foreach_transient(function(win) {
if (win != ignoreWindow &&
win.is_attached_dialog() &&
win.get_transient_for() == window) {
if (win != ignoreWindow && win.is_attached_dialog())
count++;
return false;
}
return true;
return false;
});
return count != 0;
},
@@ -1424,11 +1434,6 @@ const WindowManager = new Lang.Class({
actor._windowType = type;
}));
actor.meta_window.connect('unmanaged', Lang.bind(this, function(window) {
let parent = window.get_transient_for();
if (parent)
this._checkDimming(parent);
}));
if (actor.meta_window.is_attached_dialog())
this._checkDimming(actor.get_meta_window().get_transient_for());

View File

@@ -19,7 +19,8 @@ const WorkspaceSwitcherPopup = new Lang.Class({
Name: 'WorkspaceSwitcherPopup',
_init : function() {
this.actor = new St.Widget({ x: 0,
this.actor = new St.Widget({ reactive: true,
x: 0,
y: 0,
width: global.screen_width,
height: global.screen_height,

View File

@@ -1,68 +0,0 @@
# Makefile variables for PO directory in any package using GNU gettext.
# Usually the message domain is the same as the package name.
DOMAIN = $(PACKAGE)
# These two variables depend on the location of this directory.
subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ \
--keyword=C_:1c,2 --keyword=NC_:1c,2 \
--keyword=g_dngettext:2,3 --add-comments \
--flag=g_dngettext:2:pass-c-format \
--flag=g_strdup_printf:1:c-format \
--flag=g_string_printf:2:c-format \
--flag=g_string_append_printf:2:c-format \
--flag=g_error_new:3:c-format \
--flag=g_set_error:4:c-format \
--flag=g_markup_printf_escaped:1:c-format \
--flag=g_log:3:c-format \
--flag=g_print:1:c-format \
--flag=g_printerr:1:c-format \
--flag=g_printf:1:c-format \
--flag=g_fprintf:2:c-format \
--flag=g_sprintf:2:c-format \
--flag=g_snprintf:3:c-format
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
# package. (Note that the msgstr strings, extracted from the package's
# sources, belong to the copyright holder of the package.) Translators are
# expected to transfer the copyright for their translations to this person
# or entity, or to disclaim their copyright. The empty string stands for
# the public domain; in this case the translators are expected to disclaim
# their copyright.
COPYRIGHT_HOLDER = Translation copyright holder
# This is the email address or URL to which the translators shall report
# bugs in the untranslated strings:
# - Strings which are not entire sentences, see the maintainer guidelines
# in the GNU gettext documentation, section 'Preparing Strings'.
# - Strings which use unclear terms or require additional context to be
# understood.
# - Strings which make invalid assumptions about notation of date, time or
# money.
# - Pluralisation problems.
# - Incorrect English spelling.
# - Incorrect formatting.
# It can be your email address, or a mailing list address where translators
# can write to without being subscribed, or the URL of a web page through
# which the translators can contact you.
MSGID_BUGS_ADDRESS = http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=general
# This is the list of locale categories, beyond LC_MESSAGES, for which the
# message catalogs shall be used. It is usually empty.
EXTRA_LOCALE_CATEGORIES =
# Ignore the timestamp of the .pot file, as git clones do not have
# deterministic timestamps, and .po files are updated by translators
# (only) in GNOME projects.
PO_DEPENDS_ON_POT = no
# This tells whether or not to forcibly update $(DOMAIN).pot and
# regenerate PO files on "make dist". Possible values are "yes" and
# "no". Set this to no if the POT file and PO files are maintained
# externally.
DIST_DEPENDS_ON_UPDATE_PO = no

View File

@@ -1,17 +1,17 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
data/50-gnome-shell-system.xml
[encoding: UTF-8]
data/50-gnome-shell-system.xml.in
data/gnome-shell-extension-prefs.desktop.in.in
data/org.gnome.Shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in
data/org.gnome.Shell.PortalHelper.desktop.in.in
data/org.gnome.shell.gschema.xml.in.in
data/org.gnome.Shell.PortalHelper.desktop.in
js/extensionPrefs/main.js
js/gdm/authPrompt.js
js/gdm/loginDialog.js
js/gdm/util.js
js/misc/util.js
js/portalHelper/main.js
js/ui/accessDialog.js
js/ui/appDisplay.js
js/ui/appFavorites.js
js/ui/audioDeviceSelection.js
@@ -61,7 +61,7 @@ js/ui/viewSelector.js
js/ui/windowAttentionHandler.js
js/ui/windowManager.js
js/ui/windowMenu.js
src/calendar-server/evolution-calendar.desktop.in
src/calendar-server/evolution-calendar.desktop.in.in
# Please do not remove this file from POTFILES.in. Run "git submodule init && git submodule update" to get it.
src/gvc/gvc-mixer-control.c
src/main.c

4
po/POTFILES.skip Normal file
View File

@@ -0,0 +1,4 @@
data/org.gnome.shell.evolution.calendar.gschema.xml.in
src/calendar-server/evolution-calendar.desktop.in
# Meh, autofools :-(
sub/src/calendar-server/evolution-calendar.desktop.in

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2014-09-15 14:59+0530\n"
"Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n"
"Language-Team: Assamese <kde-i18n-doc@kde.org>\n"
"Language: as\n"
"Language: as_IN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -7,7 +7,6 @@ msgstr ""
"PO-Revision-Date: 2011-04-04 11:04+0600\n"
"Last-Translator: Israt Jahan <israt@ankur.org.bd>\n"
"Language-Team: Bengali <ankur-bd-l10n@googlegroups.com>\n"
"Language: bn\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -11,7 +11,7 @@ msgstr ""
"PO-Revision-Date: 2014-12-30 16:45+0000\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: bn_IN\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -14,7 +14,7 @@ msgstr ""
"PO-Revision-Date: 2014-09-14 23:32+0200\n"
"Last-Translator: Gil Forcada <gilforcada@guifi.net>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
"Language: ca@valencia\n"
"Language: ca-XV\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bits\n"

825
po/cs.po

File diff suppressed because it is too large Load Diff

838
po/de.po

File diff suppressed because it is too large Load Diff

836
po/el.po

File diff suppressed because it is too large Load Diff

806
po/es.po

File diff suppressed because it is too large Load Diff

1022
po/fa.po

File diff suppressed because it is too large Load Diff

844
po/fi.po

File diff suppressed because it is too large Load Diff

836
po/fr.po

File diff suppressed because it is too large Load Diff

911
po/fur.po

File diff suppressed because it is too large Load Diff

813
po/gl.po

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2014-10-01 15:51+0530\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: gu\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

854
po/he.po

File diff suppressed because it is too large Load Diff

836
po/hu.po

File diff suppressed because it is too large Load Diff

808
po/id.po

File diff suppressed because it is too large Load Diff

831
po/kk.po

File diff suppressed because it is too large Load Diff

816
po/ko.po

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ msgstr ""
"PO-Revision-Date: 2012-09-24 14:29+0600\n"
"Last-Translator: Timur Zhamakeev <ztimur@gmail.com>\n"
"Language-Team: Kirghiz <gnome-i18n@gnome.org>\n"
"Language: ky\n"
"Language: ky_KG\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

829
po/lt.po

File diff suppressed because it is too large Load Diff

805
po/lv.po

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@ msgstr ""
"PO-Revision-Date: 2011-12-08 22:37+0100\n"
"Last-Translator: Jovan N\n"
"Language-Team: mk_MK <jovan@lugola.net>\n"
"Language: mk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -11,7 +11,7 @@ msgstr ""
"PO-Revision-Date: 2014-09-15 19:21+0730\n"
"Last-Translator: Umarzuki Mochlis Moktar <umar@umarzuki.org>\n"
"Language-Team: GNOME Malay Team <gnome-ms@googlegroups.com>\n"
"Language: ms\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2016-05-01 14:21+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: nb\n"
"Language: Norwegian bokmål\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

808
po/nl.po

File diff suppressed because it is too large Load Diff

904
po/pa.po

File diff suppressed because it is too large Load Diff

903
po/pl.po

File diff suppressed because it is too large Load Diff

811
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

799
po/ru.po

File diff suppressed because it is too large Load Diff

804
po/sk.po

File diff suppressed because it is too large Load Diff

827
po/sl.po

File diff suppressed because it is too large Load Diff

836
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

827
po/sv.po

File diff suppressed because it is too large Load Diff

808
po/tr.po

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ msgstr ""
"PO-Revision-Date: 2013-03-07 21:01+0900\n"
"Last-Translator: Gheyret Kenji <gheyret@gmail.com>\n"
"Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n"
"Language: ug\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

831
po/vi.po

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@ msgstr ""
"PO-Revision-Date: 2014-08-19 19:17+0800\n"
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
"Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\n"
"Language: zh_HK\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -12,9 +12,7 @@ desktopdir=$(datadir)/applications
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
desktop_in_files = calendar-server/evolution-calendar.desktop.in
%.desktop:%.desktop.in
@$(MKDIR_P) $(builddir)/calendar-server
$(AM_V_GEN) $(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@
@INTLTOOL_DESKTOP_RULE@
gnome_shell_calendar_server_CFLAGS = \
-I$(top_srcdir)/src \
@@ -32,7 +30,6 @@ gnome_shell_calendar_server_LDADD = \
EXTRA_DIST += \
calendar-server/README \
calendar-server/org.gnome.Shell.CalendarServer.service.in \
$(desktop_in_files) \
$(NULL)
CLEANFILES += \

View File

@@ -1,8 +0,0 @@
[Desktop Entry]
Name=Evolution Calendar
Exec=evolution -c calendar
# Translators: Do NOT translate or transliterate this text (this is an icon file name)!
Icon=evolution
NoDisplay=true
Type=Application
StartupNotify=true

View File

@@ -0,0 +1,7 @@
[Desktop Entry]
_Name=Evolution Calendar
Exec=evolution -c calendar
Icon=evolution
NoDisplay=true
Type=Application
StartupNotify=true

View File

@@ -443,8 +443,6 @@ generate_instances_cb (ECalComponent *comp,
occurrence->rid = e_cal_component_get_recurid_as_string (comp);
appointment->occurrences = g_slist_append (appointment->occurrences, occurrence);
return TRUE;
}

View File

@@ -1583,7 +1583,7 @@ shell_global_get_current_time (ShellGlobal *global)
*/
GAppLaunchContext *
shell_global_create_app_launch_context (ShellGlobal *global,
guint32 timestamp,
int timestamp,
int workspace)
{
GdkAppLaunchContext *context;

View File

@@ -71,7 +71,7 @@ void shell_global_sync_pointer (ShellGlobal *global);
GAppLaunchContext *
shell_global_create_app_launch_context (ShellGlobal *global,
guint32 timestamp,
int timestamp,
int workspace);
void shell_global_play_theme_sound (ShellGlobal *global,

View File

@@ -22,7 +22,6 @@
#include "shell-global.h"
#include "shell-recorder-src.h"
#include "shell-recorder.h"
#include "shell-util.h"
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
@@ -438,21 +437,17 @@ recorder_record_frame (ShellRecorder *recorder,
if (n_captures == 0)
return;
if (n_captures == 1)
image = cairo_surface_reference (captures[0].image);
else
image = shell_util_composite_capture_images (captures,
n_captures,
recorder->area.x,
recorder->area.y,
recorder->area.width,
recorder->area.height);
/*
* TODO: Deal with each capture region separately, instead of dropping
* anything except the first one.
*/
image = captures[0].image;
data = cairo_image_surface_get_data (image);
size = (cairo_image_surface_get_height (image) *
cairo_image_surface_get_stride (image));
size = captures[0].rect.width * captures[0].rect.height * 4;
for (i = 0; i < n_captures; i++)
/* TODO: Capture more than the first framebuffer. */
for (i = 1; i < n_captures; i++)
cairo_surface_destroy (captures[i].image);
g_free (captures);
@@ -1080,7 +1075,7 @@ recorder_open_outfile (ShellRecorder *recorder,
if (outfile == -1 && errno != EEXIST)
{
g_warning ("Cannot open output file '%s': %s", path, g_strerror (errno));
g_warning ("Cannot open output file '%s': %s", filename->str, g_strerror (errno));
g_string_free (filename, TRUE);
g_free (path);
goto out;

View File

@@ -10,7 +10,6 @@
#include "shell-global.h"
#include "shell-screenshot.h"
#include "shell-util.h"
#define A11Y_APPS_SCHEMA "org.gnome.desktop.a11y.applications"
#define MAGNIFIER_ACTIVE_KEY "screen-magnifier-enabled"
@@ -234,15 +233,14 @@ do_grab_screenshot (ShellScreenshot *screenshot,
if (n_captures == 0)
return;
else if (n_captures == 1)
priv->image = cairo_surface_reference (captures[0].image);
else
priv->image = shell_util_composite_capture_images (captures,
n_captures,
x, y,
width, height);
for (i = 0; i < n_captures; i++)
/*
* TODO: Deal with each capture region separately, instead of dropping
* anything except the first one.
*/
priv->image = captures[0].image;
for (i = 1; i < n_captures; i++)
cairo_surface_destroy (captures[i].image);
g_free (captures);

View File

@@ -204,12 +204,6 @@ shell_tray_icon_click (ShellTrayIcon *icon,
gdk_error_trap_push ();
remote_window = gtk_socket_get_plug_window (GTK_SOCKET (icon->priv->socket));
if (remote_window == NULL)
{
g_warning ("shell tray: plug window is gone");
gdk_error_trap_pop_ignored ();
return;
}
xwindow = GDK_WINDOW_XID (remote_window);
xdisplay = GDK_WINDOW_XDISPLAY (remote_window);
screen = gdk_window_get_screen (remote_window);

View File

@@ -393,6 +393,18 @@ shell_util_need_background_refresh (void)
return FALSE;
}
void
shell_util_text_insert_keyval (ClutterActor *actor,
guint keyval)
{
ClutterEvent event = { 0 };
event.type = CLUTTER_KEY_PRESS;
event.key.keyval = keyval;
clutter_actor_event (actor, &event, FALSE);
}
static gboolean
canvas_draw_cb (ClutterContent *content,
cairo_t *cr,
@@ -446,49 +458,3 @@ shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
return content;
}
cairo_surface_t *
shell_util_composite_capture_images (ClutterCapture *captures,
int n_captures,
int x,
int y,
int width,
int height)
{
int i;
cairo_format_t format;
cairo_surface_t *image;
cairo_t *cr;
format = cairo_image_surface_get_format (captures[0].image);
image = cairo_image_surface_create (format, width, height);
cr = cairo_create (image);
for (i = 0; i < n_captures; i++)
{
ClutterCapture *capture = &captures[i];
double capture_scale = 1.0;
/*
* Ignore capture regions with scale other than 1 for now; mutter can't
* produce them yet, so there is no way to test them.
*/
cairo_surface_get_device_scale (capture->image, &capture_scale, NULL);
if ((int) capture_scale != 1)
continue;
cairo_save (cr);
cairo_translate (cr,
capture->rect.x - x,
capture->rect.y - y);
cairo_set_source_surface (cr, capture->image, 0, 0);
cairo_paint (cr);
cairo_restore (cr);
}
cairo_destroy (cr);
return image;
}

View File

@@ -48,16 +48,12 @@ void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker,
gboolean shell_util_need_background_refresh (void);
void shell_util_text_insert_keyval (ClutterActor *actor,
guint keyval);
ClutterContent * shell_util_get_content_for_window_actor (MetaWindowActor *window_actor,
MetaRectangle *window_rect);
cairo_surface_t * shell_util_composite_capture_images (ClutterCapture *captures,
int n_captures,
int x,
int y,
int width,
int height);
G_END_DECLS
#endif /* __SHELL_UTIL_H__ */