Compare commits
228 Commits
Author | SHA1 | Date | |
---|---|---|---|
ea3b2a5707 | |||
25eaf2a294 | |||
7bf748c579 | |||
04f33e8dc7 | |||
01c493565f | |||
f1e3104128 | |||
2ace472100 | |||
fff04d51b7 | |||
a1bfaac5a2 | |||
d80c1af1a3 | |||
cbde065a01 | |||
0b1c7320ab | |||
ce3f003e46 | |||
9fca747ef4 | |||
9455554453 | |||
4859eb63c4 | |||
e7220591ba | |||
20d579e7d8 | |||
52a68eb24a | |||
bc57574094 | |||
e4e92a2b38 | |||
023a274e41 | |||
5d0536d732 | |||
08b8b39a5d | |||
c972ff3ab4 | |||
98c2247c1b | |||
a97b8c1947 | |||
1dd2f2c6bc | |||
a9a513c621 | |||
2ce746e7dd | |||
11cde53108 | |||
fe542f8732 | |||
91319d5da2 | |||
5bd7b0dc31 | |||
c8f4adde7f | |||
b6a47cdf76 | |||
8b242dd4bd | |||
9b3e16595b | |||
2179f5836e | |||
320adb316d | |||
db36a90c48 | |||
5cfd72ff8b | |||
1d721c9080 | |||
5de1a15d98 | |||
b02089c435 | |||
ccdc6264da | |||
b736f52037 | |||
1af392b5f0 | |||
84716bccd4 | |||
f438ccfc53 | |||
fdd819e9f6 | |||
a3a09e6b2e | |||
7160e8a137 | |||
016ad69550 | |||
42e9b21b24 | |||
b6e3bf198d | |||
5e3eb5e8c3 | |||
ed1dc4649b | |||
5b586fdf3e | |||
703b21cef0 | |||
c7ec84eb33 | |||
4ce2620b68 | |||
ec6bc8f216 | |||
47a92e7fc0 | |||
e835cd2c2d | |||
6098dca0f8 | |||
21ff050a40 | |||
508001bfde | |||
410dfb2da3 | |||
74ccdbf3a9 | |||
80fc55b8ea | |||
dc424280a1 | |||
7b7c34a399 | |||
865976cfe7 | |||
81a497b476 | |||
dc1a6c746d | |||
27bcce0888 | |||
fdcb73d93e | |||
47dae0832b | |||
78e3126f97 | |||
12e45f275b | |||
7b32888322 | |||
44c2027b40 | |||
a90c81b2c7 | |||
8a25d49319 | |||
014ac2d388 | |||
1e3bf0ea7e | |||
54d11b65a1 | |||
6318c8e95b | |||
8c5bb8655d | |||
75b52d36f2 | |||
5111edb80b | |||
c4406d4ace | |||
3bd2f75866 | |||
6360d8bba6 | |||
f104a329b0 | |||
0e9c47bd56 | |||
2ca1fe3254 | |||
88211ed4bb | |||
266a0fb7d6 | |||
e6b91414de | |||
62afd2ffa3 | |||
37692513cf | |||
35bf6b0d36 | |||
0d1ac8cb5b | |||
b09b30616d | |||
daf133dca8 | |||
ae7f30483d | |||
d6fc2cc36f | |||
082a15bbc5 | |||
2bd64b6cab | |||
b1486f54c8 | |||
39a24b9a6d | |||
6e2ec7291e | |||
b0ba40f812 | |||
50c453c54d | |||
b71afe55d8 | |||
dd0882aa8b | |||
31914ab23b | |||
1816a6339d | |||
e9e2786fa3 | |||
024ab39c6d | |||
1210a78193 | |||
c55dbd5fbd | |||
263261cc86 | |||
077f0c56f1 | |||
e83656969e | |||
7d7ed7ce7a | |||
929073882f | |||
0513297029 | |||
704354be2c | |||
3715109ebe | |||
9d21b2cb25 | |||
7f56d06546 | |||
cf0664fcc6 | |||
26c8227df5 | |||
df43352441 | |||
7d705d4de3 | |||
4a0fbf03a8 | |||
54168fcd31 | |||
5012d64580 | |||
10ac42d6ad | |||
a277dfa9ce | |||
3d6c12121f | |||
98a093a279 | |||
7467e9e3a5 | |||
a7cd294403 | |||
29d89467b9 | |||
dc5dcc6139 | |||
6aaf4b87d5 | |||
4392516713 | |||
a9aa89e858 | |||
58c0abe600 | |||
d42263c1bc | |||
1d2f0e0e15 | |||
752c25bb7d | |||
df09e199b0 | |||
ab75c8cacc | |||
e94d54bffb | |||
5bce103a40 | |||
5ab852bfa3 | |||
439203349d | |||
2320c393c9 | |||
887f0f554b | |||
46c210c314 | |||
b4c3ab6726 | |||
95a6353dee | |||
cfea0649d8 | |||
045faf3f12 | |||
44ede8c942 | |||
1ddb775d59 | |||
cbcbd11ba0 | |||
bae07700a1 | |||
ca13cec01c | |||
f2af295867 | |||
0dffec661a | |||
bab5a006d8 | |||
f89b95c2aa | |||
f262473a3f | |||
b571ad0760 | |||
750672061a | |||
2ca5cfd6f5 | |||
8dd572d1cc | |||
b8647cc00e | |||
a9bdffc9e6 | |||
68723f191c | |||
5eafb29332 | |||
c92ce5983d | |||
fe52a9e1a1 | |||
1a25cd98ea | |||
611ca3c161 | |||
1dd4c7140e | |||
b9e58947cc | |||
73ab59f1d6 | |||
df8b03398f | |||
feaaefd8ba | |||
04200a4281 | |||
c6f84cfa59 | |||
103d0cba20 | |||
095e15fc11 | |||
ca2a11c57d | |||
9423d2c9ac | |||
6461db9df6 | |||
5ff609ed49 | |||
4aa2473d18 | |||
3f5bb8f98d | |||
0487630e03 | |||
d173f9e19d | |||
f53bf17331 | |||
ac54fed8d4 | |||
6deee27d14 | |||
d9f43e27a0 | |||
d1a178301f | |||
8b3d4857aa | |||
8d3abea6ef | |||
5060081db5 | |||
a8fa8a498a | |||
5635797cb9 | |||
468f30e4ab | |||
68b943d8ea | |||
994b4c0007 | |||
f9e4385e02 | |||
909b5ec43c | |||
7c37e94eda | |||
874dd14ddc | |||
d39d7b45e0 | |||
23e11175f8 | |||
aefa8af60e |
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,6 +18,8 @@ config
|
||||
configure
|
||||
data/gnome-shell.desktop
|
||||
data/gnome-shell.desktop.in
|
||||
data/gnome-shell-clock-preferences.desktop
|
||||
data/gnome-shell-clock-preferences.desktop.in
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
@ -38,6 +40,7 @@ src/Makefile
|
||||
src/Makefile.in
|
||||
src/gnomeshell-taskpanel
|
||||
src/gnome-shell
|
||||
src/gnome-shell-clock-preferences
|
||||
src/test-recorder
|
||||
src/test-recorder.ogg
|
||||
src/test-theme
|
||||
|
30
configure.ac
30
configure.ac
@ -1,5 +1,5 @@
|
||||
AC_PREREQ(2.63)
|
||||
AC_INIT([gnome-shell],[2.29.1],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
AC_INIT([gnome-shell],[2.31.2],[https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell],[gnome-shell])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([src/shell-global.c])
|
||||
@ -55,13 +55,15 @@ fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
|
||||
CLUTTER_MIN_VERSION=1.2.0
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.6.9
|
||||
GJS_MIN_VERSION=0.6
|
||||
MUTTER_MIN_VERSION=2.29.1
|
||||
CLUTTER_MIN_VERSION=1.2.8
|
||||
GOBJECT_INTROSPECTION_MIN_VERSION=0.6.11
|
||||
GJS_MIN_VERSION=0.7
|
||||
MUTTER_MIN_VERSION=2.31.2
|
||||
GTK_MIN_VERSION=2.18.0
|
||||
|
||||
# Collect more than 20 libraries for a prize!
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 dbus-glib-1
|
||||
gtk+-2.0 >= $GTK_MIN_VERSION
|
||||
mutter-plugins >= $MUTTER_MIN_VERSION
|
||||
gjs-gi-1.0 >= $GJS_MIN_VERSION
|
||||
libgnome-menu $recorder_modules gconf-2.0
|
||||
@ -70,9 +72,19 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1
|
||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||
libstartup-notification-1.0
|
||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
|
||||
|
||||
# This is for the newly added application id bits, we can replace this with
|
||||
# a version check later
|
||||
saved_CFLAGS=$CFLAGS
|
||||
saved_LIBS=$LIBS
|
||||
CFLAGS=$MUTTER_PLUGIN_CFLAGS
|
||||
LIBS=$MUTTER_PLUGIN_LIBS
|
||||
AC_CHECK_FUNCS(sn_startup_sequence_get_application_id)
|
||||
CFLAGS=$saved_CFLAGS
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6 gnome-desktop-2.0 >= 2.26)
|
||||
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
|
||||
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-2.0)
|
||||
PKG_CHECK_MODULES(TRAY, gtk+-2.0)
|
||||
|
||||
@ -86,8 +98,10 @@ AC_SUBST(MUTTER_PLUGIN_DIR)
|
||||
|
||||
GJS_JS_DIR=`$PKG_CONFIG --variable=jsdir gjs-1.0`
|
||||
GJS_JS_NATIVE_DIR=`$PKG_CONFIG --variable=jsnativedir gjs-1.0`
|
||||
GJS_CONSOLE=`$PKG_CONFIG --variable=gjs_console gjs-1.0`
|
||||
AC_SUBST(GJS_JS_DIR)
|
||||
AC_SUBST(GJS_JS_NATIVE_DIR)
|
||||
AC_SUBST(GJS_CONSOLE)
|
||||
|
||||
AC_CHECK_FUNCS(fdwalk)
|
||||
AC_CHECK_HEADERS([sys/resource.h])
|
||||
@ -141,6 +155,8 @@ AC_CONFIG_FILES([
|
||||
js/Makefile
|
||||
js/misc/Makefile
|
||||
js/ui/Makefile
|
||||
js/perf/Makefile
|
||||
js/prefs/Makefile
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
po/Makefile.in
|
||||
|
@ -1,17 +1,19 @@
|
||||
desktopdir=$(datadir)/applications
|
||||
desktop_DATA = gnome-shell.desktop
|
||||
desktop_DATA = gnome-shell.desktop gnome-shell-clock-preferences.desktop
|
||||
|
||||
# We substitute in bindir so it works as an autostart
|
||||
# file when built in a non-system prefix
|
||||
gnome-shell.desktop.in: gnome-shell.desktop.in.in
|
||||
%.desktop.in:%.desktop.in.in
|
||||
$(AM_V_GEN) sed -e "s|@bindir[@]|$(bindir)|" \
|
||||
-e "s|@VERSION[@]|$(VERSION)|" \
|
||||
$< > $@ || rm $@
|
||||
|
||||
# Placeholder until we add intltool
|
||||
gnome-shell.desktop: gnome-shell.desktop.in
|
||||
%.desktop:%.desktop.in
|
||||
$(AM_V_GEN) sed s/^_// < $< > $@ || rm $@
|
||||
|
||||
dist_pkgdata_DATA = clock-preferences.ui
|
||||
|
||||
imagesdir = $(pkgdatadir)/images
|
||||
dist_images_DATA = \
|
||||
close-black.svg \
|
||||
@ -50,11 +52,13 @@ schema_DATA = gnome-shell.schemas
|
||||
install-data-local:
|
||||
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$(schema_DATA)
|
||||
|
||||
EXTRA_DIST = \
|
||||
gnome-shell.desktop.in.in \
|
||||
EXTRA_DIST = \
|
||||
gnome-shell.desktop.in.in \
|
||||
gnome-shell-clock-preferences.desktop.in.in \
|
||||
$(schema_DATA)
|
||||
|
||||
CLEANFILES = \
|
||||
gnome-shell.desktop.in \
|
||||
CLEANFILES = \
|
||||
gnome-shell.desktop.in \
|
||||
gnome-shell-clock-preferences.desktop.in \
|
||||
$(desktop_DATA)
|
||||
|
||||
|
188
data/clock-preferences.ui
Normal file
188
data/clock-preferences.ui
Normal file
@ -0,0 +1,188 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="2.16"/>
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="GtkDialog" id="prefs-dialog">
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Clock Preferences</property>
|
||||
<property name="window_position">center</property>
|
||||
<property name="type_hint">normal</property>
|
||||
<property name="has_separator">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">18</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="top_padding">6</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">6</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="12hr_radio">
|
||||
<property name="label" translatable="yes">_12 hour format</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="24hr_radio">
|
||||
<property name="label" translatable="yes">_24 hour format</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">12hr_radio</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label_format">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Clock Format</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment2">
|
||||
<property name="visible">True</property>
|
||||
<property name="top_padding">6</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="date_check">
|
||||
<property name="label" translatable="yes">Show the _date</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="seconds_check">
|
||||
<property name="label" translatable="yes">Show seco_nds</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label_display">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Panel Display</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="padding">6</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="prefs_close_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="0">prefs_close_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
15
data/gnome-shell-clock-preferences.desktop.in.in
Normal file
15
data/gnome-shell-clock-preferences.desktop.in.in
Normal file
@ -0,0 +1,15 @@
|
||||
[Desktop Entry]
|
||||
_Name=Clock
|
||||
_Comment=Customize the panel clock
|
||||
Exec=@bindir@/gnome-shell-clock-preferences
|
||||
Icon=gnome-panel-clock
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=GNOME;GTK;Settings;DesktopSettings;
|
||||
OnlyShowIn=GNOME;
|
||||
X-GNOME-ShellOnly=true
|
||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||
X-GNOME-Bugzilla-Product=gnome-shell
|
||||
X-GNOME-Bugzilla-Component=general
|
||||
X-GNOME-Bugzilla-Version=@VERSION@
|
@ -58,59 +58,86 @@
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/visible</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/visible</applyto>
|
||||
<key>/schemas/desktop/gnome/shell/clock/format</key>
|
||||
<applyto>/desktop/gnome/shell/clock/format</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default>
|
||||
<!-- Translators:
|
||||
This controls whether the GNOME panel clock should display time
|
||||
in 24 hour mode or 12 hour mode by default. The only valid values
|
||||
for this are "24-hour" and "12-hour".
|
||||
If your locale uses 24 hour time notation, translate this to
|
||||
"24-hour".
|
||||
If your locale uses 12 hour time notation with am/pm, translate
|
||||
this to "12-hour".
|
||||
|
||||
Do NOT translate this into anything else than "24-hour" or
|
||||
"12-hour". For example, if you translate this to "24 sata" or
|
||||
anything else that isn't "24-hour" or "12-hour", things will
|
||||
not work.
|
||||
-->
|
||||
24-hour
|
||||
</default>
|
||||
<locale name="C">
|
||||
<short>Hour format</short>
|
||||
<long>
|
||||
This key specifies the hour format used by the panel clock.
|
||||
Possible values are "12-hour", "24-hour", "unix" and "custom".
|
||||
If set to "unix", the clock will display time in seconds since Epoch,
|
||||
i.e. 1970-01-01.
|
||||
If set to "custom", the clock will display time according to the format
|
||||
specified in the custom_format key.
|
||||
Note that if set to either "unix" or "custom", the show_date and
|
||||
show_seconds keys are ignored.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/clock/custom_format</key>
|
||||
<applyto>/desktop/gnome/shell/clock/custom_format</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default></default>
|
||||
<locale name="C">
|
||||
<short>Custom format of the clock</short>
|
||||
<long>
|
||||
This key specifies the format used by the panel clock when the
|
||||
format key is set to "custom". You can use conversion specifiers
|
||||
understood by strftime() to obtain a specific format. See the
|
||||
strftime() manual for more information.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/clock/show_seconds</key>
|
||||
<applyto>/desktop/gnome/shell/clock/show_seconds</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Whether or not to display the sidebar</short>
|
||||
<short>Show time with seconds</short>
|
||||
<long>
|
||||
Determines whether or not the sidebar is visible.
|
||||
</long>
|
||||
If true and format is either "12-hour" or "24-hour",
|
||||
display seconds in time.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/expanded</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/expanded</applyto>
|
||||
<key>/schemas/desktop/gnome/shell/clock/show_date</key>
|
||||
<applyto>/desktop/gnome/shell/clock/show_date</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Whether the sidebar should be in the expanded (wide) mode</short>
|
||||
<short>Show date in clock</short>
|
||||
<long>
|
||||
Controls the expanded/collapsed state of the sidebar.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/autohide</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/autohide</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<locale name="C">
|
||||
<short>Whether the sidebar should automatically hide itself in compact mode</short>
|
||||
<long>
|
||||
Controls the autohide state of the sidebar.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/widgets</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/widgets</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>list</type>
|
||||
<list_type>string</list_type>
|
||||
<default>[imports.ui.widget.ClockWidget,imports.ui.widget.AppsWidget,imports.ui.widget.RecentDocsWidget]</default>
|
||||
<locale name="C">
|
||||
<short>The widgets to display in the sidebar</short>
|
||||
<long>
|
||||
The widgets to display in the sidebar, in order from top to bottom. Each widget "name" is actually a JavaScript expression referring to a widget constructor object.
|
||||
</long>
|
||||
If true and format is either "12-hour" or "24-hour",
|
||||
display date in the clock, in addition to time.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
@ -191,6 +218,226 @@
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/windows/button_layout</key>
|
||||
<applyto>/desktop/gnome/shell/windows/button_layout</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default>:minimize,maximize,close</default>
|
||||
<locale name="C">
|
||||
<short>Arrangement of buttons on the titlebar</short>
|
||||
<long>
|
||||
Arrangement of buttons on the titlebar. The
|
||||
value should be a string, such as
|
||||
"menu:minimize,maximize,spacer,close"; the colon separates the
|
||||
left corner of the window from the right corner, and
|
||||
the button names are comma-separated. Duplicate buttons
|
||||
are not allowed. Unknown button names are silently ignored
|
||||
so that buttons can be added in future gnome-shell versions
|
||||
without breaking older versions.
|
||||
A special spacer tag can be used to insert some space between
|
||||
two adjacent buttons.
|
||||
|
||||
This key overrides /apps/metacity/general/button_layout when
|
||||
running GNOME Shell.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<!-- Magnifier -->
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/show_magnifier</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/show_magnifier</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Show or hide the magnifier</short>
|
||||
<long>
|
||||
Show or hide the magnifier and all of its zoom regions.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/mouse_tracking</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/mouse_tracking</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>1</default>
|
||||
<locale name="C">
|
||||
<short>Mouse Tracking Mode</short>
|
||||
<long>
|
||||
Determines the position of the magnified mouse image within
|
||||
the magnified view and how it reacts to system mouse movement.
|
||||
The values are 0 - none: no mouse tracking; 1 - centered: the
|
||||
mouse image is displayed at the center of the zoom region
|
||||
(which also represents the point under the system mouse) and the
|
||||
magnified contents are scrolled as the system mouse moves; 2 -
|
||||
proportional: the position of the magnified mouse in the zoom
|
||||
region is proportionally the same as the position of the system
|
||||
mouse on screen; or 3 - push: when the magnified mouse
|
||||
intersects a boundary of the zoom region, the contents are
|
||||
scrolled into view.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/screen_position</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/screen_position</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>3</default>
|
||||
<locale name="C">
|
||||
<short>Screen position</short>
|
||||
<long>
|
||||
The magnified view either fills the entire screen (1), or
|
||||
occupies the top-half (2), bottom-half (3), left-half (4), or
|
||||
right-half (5) of the screen.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/mag_factor</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/mag_factor</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>float</type>
|
||||
<default>2.0</default>
|
||||
<locale name="C">
|
||||
<short>Magnification factor</short>
|
||||
<long>
|
||||
The power of the magnification. A value of 1.0 means no
|
||||
magnification. A value of 2.0 doubles the size.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/lens_mode</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/lens_mode</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Enable lens mode</short>
|
||||
<long>
|
||||
Whether the magnified view should be centered over the location
|
||||
of the system mouse and move with it.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/scroll_at_edges</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/scroll_at_edges</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Scroll magnified contents beyond the edges of the desktop</short>
|
||||
<long>
|
||||
For centered mouse tracking, when the system pointer is at
|
||||
or near the edge of the screen, the magnified contents continue
|
||||
to scroll such that the screen edge moves into the magnified
|
||||
view.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<!-- Magnifier: Crosshairs -->
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/show_cross_hairs</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/show_cross_hairs</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Show or hide crosshairs</short>
|
||||
<long>
|
||||
Enables/disables display of crosshairs centered on the magnified mouse
|
||||
sprite.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_thickness</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_thickness</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>8</default>
|
||||
<locale name="C">
|
||||
<short>Thickness of the crosshairs</short>
|
||||
<long>
|
||||
Width of the vertical and horizontal lines that make up the
|
||||
crosshairs.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_color</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_color</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>string</type>
|
||||
<default>#ff0000</default>
|
||||
<locale name="C">
|
||||
<short>Color of the crosshairs</short>
|
||||
<long>
|
||||
The color of the the vertical and horizontal lines that make up
|
||||
the crosshairs.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_opacity</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_opacity</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>169</default>
|
||||
<locale name="C">
|
||||
<short>Opacity of the crosshairs</short>
|
||||
<long>
|
||||
Determines the transparency of the crosshairs, from fully opaque
|
||||
to fully transparent.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_length</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_length</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>int</type>
|
||||
<default>4096</default>
|
||||
<locale name="C">
|
||||
<short>Length of the crosshairs</short>
|
||||
<long>
|
||||
Determines the length of the vertical and horizontal lines that
|
||||
make up the crosshairs.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/accessibility/magnifier/cross_hairs_clip</key>
|
||||
<applyto>/desktop/gnome/accessibility/magnifier/cross_hairs_clip</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Clip the crosshairs at the center</short>
|
||||
<long>
|
||||
Determines whether the crosshairs intersect the magnified mouse
|
||||
sprite, or are clipped such that the ends of the horizontal
|
||||
and vertical lines surround the mouse image.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
|
||||
</gconfschemafile>
|
||||
|
@ -99,7 +99,6 @@ StTooltip {
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
background-color: black;
|
||||
border-bottom: 1px solid #1f1f1f;
|
||||
}
|
||||
|
||||
#panelLeft, #panelCenter, #panelRight {
|
||||
@ -115,11 +114,61 @@ StTooltip {
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.panel-button:pressed {
|
||||
background-color: rgba(50,76,111,0.98);
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
}
|
||||
|
||||
.panel-menu-boxpointer {
|
||||
-arrow-border-radius: 9px;
|
||||
-arrow-background-color: rgba(0,0,0,0.9);
|
||||
-arrow-border-width: 2px;
|
||||
-arrow-border-color: #5f5f5f;
|
||||
-arrow-base: 30px;
|
||||
-arrow-rise: 15px;
|
||||
}
|
||||
|
||||
.panel-menu {
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.panel-menu-content {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
|
||||
.panel-menu-item {
|
||||
padding: 6px 20px;
|
||||
}
|
||||
|
||||
.panel-menu-item:active {
|
||||
background-color: #4c4c4c;
|
||||
}
|
||||
|
||||
.panel-image-menu-item {
|
||||
spacing: 12px;
|
||||
}
|
||||
|
||||
.panel-separator-menu-item {
|
||||
-gradient-height: 2px;
|
||||
-gradient-start: rgba(8,8,8,0);
|
||||
-gradient-end: #333333;
|
||||
-margin-horizontal: 30px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
#appMenu {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.app-menu-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.panel-button {
|
||||
padding: 4px 12px 3px;
|
||||
padding: 0px 12px;
|
||||
border-radius: 5px;
|
||||
border-radius-bottomleft: 0px;
|
||||
border-radius-bottomright: 0px;
|
||||
@ -141,10 +190,18 @@ StTooltip {
|
||||
border-radius-topright: 0px;
|
||||
}
|
||||
|
||||
#statusMenu {
|
||||
#panelStatusMenu {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#statusTray {
|
||||
spacing: 14px;
|
||||
}
|
||||
|
||||
#statusTray:compact {
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
/* Overview */
|
||||
|
||||
.overview {
|
||||
@ -317,6 +374,7 @@ StTooltip {
|
||||
border: 1px solid #3a3a3a;
|
||||
background-color: #e8e8e8;
|
||||
caret-color: #545454;
|
||||
-st-shadow: 0px 0px 6px 2px rgba(255,255,255,0.9);
|
||||
}
|
||||
|
||||
#searchEntry:hover {
|
||||
@ -404,6 +462,10 @@ StTooltip {
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
.dash-results-container {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
/* GenericDisplay */
|
||||
|
||||
.generic-display-container {
|
||||
@ -489,6 +551,9 @@ StTooltip {
|
||||
|
||||
.app-well-app:hover {
|
||||
border: 1px solid #666666;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(61,61,61,0.8);
|
||||
background-gradient-end: rgba(24,24,24,0.2);
|
||||
}
|
||||
|
||||
.app-well-app:active {
|
||||
@ -502,8 +567,13 @@ StTooltip {
|
||||
padding: 4px;
|
||||
background-color: rgba(0,0,0,0.9);
|
||||
color: #ffffff;
|
||||
-shell-arrow-width: 12px;
|
||||
-shell-menu-spacing: 4px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.app-well-menu-arrow {
|
||||
border-color: #5f5f5f;
|
||||
color: rgba(0,0,0,0.9);
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.app-well-menu-item:hover {
|
||||
@ -518,20 +588,49 @@ StTooltip {
|
||||
|
||||
/* Places */
|
||||
|
||||
.places-section {
|
||||
spacing-columns: 4px;
|
||||
spacing-rows: 4px;
|
||||
}
|
||||
|
||||
.places-item-box {
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.places-item {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.places-actions {
|
||||
spacing: 2px;
|
||||
}
|
||||
|
||||
#placesDevices {
|
||||
padding-top: 4px;
|
||||
.places-item {
|
||||
border-radius: 4px;
|
||||
padding: 2px;
|
||||
border: 1px solid #181818;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.places-item:hover {
|
||||
border: 1px solid #666666;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(61,61,61,0.8);
|
||||
background-gradient-end: rgba(24,24,24,0.2);
|
||||
}
|
||||
|
||||
/* Recent items */
|
||||
|
||||
.recent-docs-item-box {
|
||||
spacing: 2px;
|
||||
}
|
||||
|
||||
.recent-docs-item {
|
||||
border-radius: 4px;
|
||||
padding: 2px;
|
||||
border: 1px solid #181818;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.recent-docs-item:hover {
|
||||
border: 1px solid #666666;
|
||||
background-gradient-direction: vertical;
|
||||
background-gradient-start: rgba(61,61,61,0.8);
|
||||
background-gradient-end: rgba(24,24,24,0.2);
|
||||
}
|
||||
|
||||
/* LookingGlass */
|
||||
@ -541,7 +640,7 @@ StTooltip {
|
||||
background-color: rgba(0,0,0,0.85);
|
||||
spacing: 4px;
|
||||
padding: 4px;
|
||||
border: 1px solid rgba(0,0,172,0.85);
|
||||
border: 2px solid grey;
|
||||
border-radius: 4px;
|
||||
|
||||
color: #88ff66;
|
||||
@ -561,27 +660,69 @@ StTooltip {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog .notebook-tab:hover {
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
#LookingGlassDialog .notebook-tab:selected {
|
||||
border: 1px solid #88ff66;
|
||||
padding: 1px;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StLabel
|
||||
#LookingGlassDialog .lg-inspector-title {
|
||||
font-weight: bold;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.lg-dialog StLabel
|
||||
{
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StEntry
|
||||
.lg-dialog StEntry
|
||||
{
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
.lg-obj-inspector-title
|
||||
{
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
.lg-obj-inspector-button
|
||||
{
|
||||
border: 1px solid #88ff66;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.lg-obj-inspector-button:hover
|
||||
{
|
||||
border: 1px solid #00ff00;
|
||||
}
|
||||
|
||||
.lg-dialog .shell-link
|
||||
{
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
.lg-dialog .shell-link:hover
|
||||
{
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StBoxLayout#EvalBox
|
||||
{
|
||||
padding: 4px;
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#LookingGlassDialog StBoxLayout#ResultsArea
|
||||
{
|
||||
spacing: 4px;
|
||||
}
|
||||
|
||||
#lookingGlassExtensions {
|
||||
padding: 4px;
|
||||
}
|
||||
@ -605,6 +746,14 @@ StTooltip {
|
||||
spacing: 6px;
|
||||
}
|
||||
|
||||
#LookingGlassPropertyInspector {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
border: 2px solid grey;
|
||||
border-radius: 4px;
|
||||
padding: 6px;
|
||||
color: #88ff66;
|
||||
}
|
||||
|
||||
/* Calendar popup */
|
||||
|
||||
#calendarPopup {
|
||||
@ -662,7 +811,7 @@ StTooltip {
|
||||
|
||||
#notification {
|
||||
font-size: 16px;
|
||||
border-radius: 5px;
|
||||
border-radius: 5px 5px 0px 0px;
|
||||
background: rgba(0,0,0,0.9);
|
||||
color: white;
|
||||
padding: 2px 10px 10px 10px;
|
||||
@ -671,6 +820,23 @@ StTooltip {
|
||||
max-width: 40em;
|
||||
}
|
||||
|
||||
#summary-notification-bin #notification {
|
||||
/* message-tray.height + notification.padding-bottom */
|
||||
padding-bottom: 38px;
|
||||
}
|
||||
|
||||
#notification-scrollview {
|
||||
max-height: 10em;
|
||||
}
|
||||
|
||||
#notification-scrollview > .top-shadow, #notification-scrollview > .bottom-shadow {
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
#notification-body {
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
#notification-actions {
|
||||
spacing: 5px;
|
||||
}
|
||||
@ -693,12 +859,52 @@ StTooltip {
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
.chat-received {
|
||||
background-gradient-direction: horizontal;
|
||||
background-gradient-start: #606060;
|
||||
background-gradient-end: #000000;
|
||||
|
||||
min-width: 20em;
|
||||
}
|
||||
|
||||
.chat-sent {
|
||||
background-gradient-direction: horizontal;
|
||||
background-gradient-start: #000000;
|
||||
background-gradient-end: #606060;
|
||||
}
|
||||
|
||||
.chat-response {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
/* The spacing and padding on the summary is tricky; we want to keep
|
||||
* the icons from touching each other or the edges of the screen, but
|
||||
* we also want them to be "Fitts"-y with respect to the edges, so the
|
||||
* summary area's bottom and right padding must actually be part of
|
||||
* the icons. However, we can't put *all* of the padding into the
|
||||
* icons, because then the summary would be 0x0 when there were no
|
||||
* icons in it, and so you wouldn't be able to hover over it to
|
||||
* activate it.
|
||||
*
|
||||
* The padding-right on the non-rightmost icons is noticeable and
|
||||
* slightly annoying. If StBoxLayout implemented the ":last-child"
|
||||
* pseudo-class we could fix that...
|
||||
*/
|
||||
#summary-mode {
|
||||
spacing: 10px;
|
||||
padding: 2px 4px;
|
||||
spacing: 6px;
|
||||
padding: 2px 0px 0px 4px;
|
||||
}
|
||||
|
||||
.summary-icon {
|
||||
padding: 0px 4px 2px 0px;
|
||||
}
|
||||
|
||||
/* App Switcher */
|
||||
#altTabPopup {
|
||||
padding: 8px;
|
||||
spacing: 16px;
|
||||
}
|
||||
|
||||
.switcher-list {
|
||||
background: rgba(0,0,0,0.8);
|
||||
border: 1px solid rgba(128,128,128,0.40);
|
||||
@ -709,6 +915,10 @@ StTooltip {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.switcher-list-item-container {
|
||||
spacing: 8px;
|
||||
}
|
||||
|
||||
.thumbnail-scroll-gradient-left {
|
||||
background-gradient-direction: horizontal;
|
||||
background-gradient-start: rgba(51, 51, 51, 1.0);
|
||||
@ -762,6 +972,16 @@ StTooltip {
|
||||
background-image: url("corner-ripple.png");
|
||||
}
|
||||
|
||||
.switcher-arrow {
|
||||
border-color: rgba(0,0,0,0);
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.switcher-arrow:highlighted {
|
||||
border-color: rgba(0,0,0,0);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Workspace Switcher */
|
||||
.workspace-switcher-container {
|
||||
background: rgba(0,0,0,0.8);
|
||||
@ -835,3 +1055,13 @@ StTooltip {
|
||||
.lightbox {
|
||||
background-color: rgba(0, 0, 0, 0.27);
|
||||
}
|
||||
|
||||
/* Magnifier */
|
||||
|
||||
.magnifier-zoom-region {
|
||||
border: 2px solid rgba(128, 0, 0, 255);
|
||||
}
|
||||
|
||||
.magnifier-zoom-region.full-screen {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
SUBDIRS = misc ui
|
||||
SUBDIRS = misc ui perf prefs
|
||||
|
@ -3,4 +3,6 @@ jsmiscdir = $(pkgdatadir)/js/misc
|
||||
dist_jsmisc_DATA = \
|
||||
docInfo.js \
|
||||
format.js \
|
||||
params.js
|
||||
gnomeSession.js \
|
||||
params.js \
|
||||
telepathy.js
|
||||
|
@ -148,6 +148,6 @@ DocManager.prototype = {
|
||||
}
|
||||
return multipleMatches.concat(prefixMatches.concat(substringMatches));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(DocManager.prototype);
|
||||
|
45
js/misc/gnomeSession.js
Normal file
45
js/misc/gnomeSession.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Lang = imports.lang;
|
||||
|
||||
const PresenceIface = {
|
||||
name: 'org.gnome.SessionManager.Presence',
|
||||
methods: [{ name: 'SetStatus',
|
||||
inSignature: 'u' }],
|
||||
properties: [{ name: 'status',
|
||||
signature: 'u',
|
||||
access: 'readwrite' }],
|
||||
signals: [{ name: 'StatusChanged',
|
||||
inSignature: 'u' }]
|
||||
};
|
||||
|
||||
const PresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
INVISIBLE: 1,
|
||||
BUSY: 2,
|
||||
IDLE: 3
|
||||
};
|
||||
|
||||
function Presence() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Presence.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
||||
},
|
||||
|
||||
getStatus: function(callback) {
|
||||
this.GetRemote('status', Lang.bind(this,
|
||||
function(status, ex) {
|
||||
if (!ex)
|
||||
callback(this, status);
|
||||
}));
|
||||
},
|
||||
|
||||
setStatus: function(status) {
|
||||
this.SetStatusRemote(status);
|
||||
}
|
||||
};
|
||||
DBus.proxifyPrototype(Presence.prototype, PresenceIface);
|
@ -2,7 +2,7 @@
|
||||
|
||||
// parse:
|
||||
// @params: caller-provided parameter object, or %null
|
||||
// @default: function-provided defaults object
|
||||
// @defaults: function-provided defaults object
|
||||
// @allowExtras: whether or not to allow properties not in @default
|
||||
//
|
||||
// Examines @params and fills in default values from @defaults for
|
||||
@ -10,24 +10,26 @@
|
||||
// @allowExtras is not %true, it will throw an error if @params
|
||||
// contains any properties that aren't in @defaults.
|
||||
//
|
||||
// If @params is %null, this returns @defaults.
|
||||
// If @params is %null, this returns the values from @defaults.
|
||||
//
|
||||
// Return value: the updated params
|
||||
// Return value: a new object, containing the merged parameters from
|
||||
// @params and @defaults
|
||||
function parse(params, defaults, allowExtras) {
|
||||
let ret = {}, prop;
|
||||
|
||||
if (!params)
|
||||
return defaults;
|
||||
params = {};
|
||||
|
||||
if (!allowExtras) {
|
||||
for (let prop in params) {
|
||||
if (!(prop in defaults))
|
||||
throw new Error('Unrecognized parameter "' + prop + '"');
|
||||
}
|
||||
for (prop in params) {
|
||||
if (!(prop in defaults) && !allowExtras)
|
||||
throw new Error('Unrecognized parameter "' + prop + '"');
|
||||
ret[prop] = params[prop];
|
||||
}
|
||||
|
||||
for (let prop in defaults) {
|
||||
for (prop in defaults) {
|
||||
if (!(prop in params))
|
||||
params[prop] = defaults[prop];
|
||||
ret[prop] = defaults[prop];
|
||||
}
|
||||
|
||||
return params;
|
||||
return ret;
|
||||
}
|
372
js/misc/telepathy.js
Normal file
372
js/misc/telepathy.js
Normal file
@ -0,0 +1,372 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
|
||||
// D-Bus utils; should eventually move to gjs.
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=610859
|
||||
|
||||
function makeProxyClass(iface) {
|
||||
let constructor = function() { this._init.apply(this, arguments); };
|
||||
|
||||
constructor.prototype._init = function(bus, name, path) {
|
||||
bus.proxifyObject(this, name, path);
|
||||
};
|
||||
|
||||
DBus.proxifyPrototype(constructor.prototype, iface);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
function nameToPath(name) {
|
||||
return '/' + name.replace('.', '/', 'g');
|
||||
};
|
||||
|
||||
function pathToName(path) {
|
||||
if (path[0] != '/')
|
||||
throw new Error('not a D-Bus path: ' + path);
|
||||
return path.substr(1).replace('/', '.', 'g');
|
||||
};
|
||||
|
||||
// This is tp_escape_as_identifier() from telepathy-glib
|
||||
function escapeAsIdentifier(name) {
|
||||
if (!name)
|
||||
return '_';
|
||||
|
||||
// first char is replaced with _XX if it's non-alpha,
|
||||
// later chars are replaced with _XX if they're non-alphanumeric
|
||||
if (name.length == 1) {
|
||||
return name.replace(/[^a-zA-Z]/, _hexEscape);
|
||||
} else {
|
||||
return (name[0].replace(/[^a-zA-Z]/, _hexEscape) +
|
||||
name.substring(1).replace(/[^a-zA-Z0-9]/g, _hexEscape));
|
||||
}
|
||||
}
|
||||
|
||||
function _hexEscape(ch) {
|
||||
return '_' + ch.charCodeAt(0).toString(16);
|
||||
}
|
||||
|
||||
// Telepathy D-Bus interface definitions. Note that most of these are
|
||||
// incomplete, and only cover the methods/properties/signals that
|
||||
// we're currently using.
|
||||
|
||||
const TELEPATHY = 'org.freedesktop.Telepathy';
|
||||
|
||||
const CLIENT_NAME = TELEPATHY + '.Client';
|
||||
const ClientIface = {
|
||||
name: CLIENT_NAME,
|
||||
properties: [
|
||||
{ name: 'Interfaces',
|
||||
signature: 'as',
|
||||
access: 'read' }
|
||||
]
|
||||
};
|
||||
|
||||
const CLIENT_APPROVER_NAME = TELEPATHY + '.Client.Approver';
|
||||
const ClientApproverIface = {
|
||||
name: CLIENT_APPROVER_NAME,
|
||||
methods: [
|
||||
{ name: 'AddDispatchOperation',
|
||||
inSignature: 'a(oa{sv})oa{sv}',
|
||||
outSignature: '' }
|
||||
],
|
||||
properties: [
|
||||
{ name: 'ApproverChannelFilter',
|
||||
signature: 'aa{sv}',
|
||||
access: 'read' }
|
||||
]
|
||||
};
|
||||
|
||||
const CLIENT_HANDLER_NAME = TELEPATHY + '.Client.Handler';
|
||||
const ClientHandlerIface = {
|
||||
name: CLIENT_HANDLER_NAME,
|
||||
methods: [
|
||||
{ name: 'HandleChannels',
|
||||
inSignature: 'ooa(oa{sv})aota{sv}',
|
||||
outSignature: '' }
|
||||
],
|
||||
properties: [
|
||||
{ name: 'HandlerChannelFilter',
|
||||
signature: 'aa{sv}',
|
||||
access: 'read' }
|
||||
]
|
||||
};
|
||||
|
||||
const CLIENT_OBSERVER_NAME = TELEPATHY + '.Client.Observer';
|
||||
const ClientObserverIface = {
|
||||
name: CLIENT_OBSERVER_NAME,
|
||||
methods: [
|
||||
{ name: 'ObserveChannels',
|
||||
inSignature: 'ooa(oa{sv})oaoa{sv}',
|
||||
outSignature: '' }
|
||||
],
|
||||
properties: [
|
||||
{ name: 'ObserverChannelFilter',
|
||||
signature: 'aa{sv}',
|
||||
access: 'read' }
|
||||
]
|
||||
};
|
||||
|
||||
const CHANNEL_DISPATCH_OPERATION_NAME = TELEPATHY + '.ChannelDispatchOperation';
|
||||
const ChannelDispatchOperationIface = {
|
||||
name: CHANNEL_DISPATCH_OPERATION_NAME,
|
||||
methods: [
|
||||
{ name: 'HandleWith',
|
||||
inSignature: 's',
|
||||
outSignature: '' },
|
||||
{ name: 'Claim',
|
||||
inSignature: '',
|
||||
outSignature: '' }
|
||||
]
|
||||
};
|
||||
let ChannelDispatchOperation = makeProxyClass(ChannelDispatchOperationIface);
|
||||
|
||||
const CONNECTION_NAME = TELEPATHY + '.Connection';
|
||||
const ConnectionIface = {
|
||||
name: CONNECTION_NAME,
|
||||
signals: [
|
||||
{ name: 'StatusChanged',
|
||||
inSignature: 'uu' }
|
||||
]
|
||||
};
|
||||
let Connection = makeProxyClass(ConnectionIface);
|
||||
|
||||
const ConnectionStatus = {
|
||||
CONNECTED: 0,
|
||||
CONNECTING: 1,
|
||||
DISCONNECTED: 2
|
||||
};
|
||||
|
||||
const CONNECTION_ALIASING_NAME = CONNECTION_NAME + '.Interface.Aliasing';
|
||||
const ConnectionAliasingIface = {
|
||||
name: CONNECTION_ALIASING_NAME,
|
||||
methods: [
|
||||
{ name: 'RequestAliases',
|
||||
inSignature: 'au',
|
||||
outSignature: 'as'
|
||||
}
|
||||
],
|
||||
signals: [
|
||||
{ name: 'AliasesChanged',
|
||||
inSignature: 'a(us)' }
|
||||
]
|
||||
};
|
||||
let ConnectionAliasing = makeProxyClass(ConnectionAliasingIface);
|
||||
|
||||
const CONNECTION_AVATARS_NAME = CONNECTION_NAME + '.Interface.Avatars';
|
||||
const ConnectionAvatarsIface = {
|
||||
name: CONNECTION_AVATARS_NAME,
|
||||
methods: [
|
||||
{ name: 'GetKnownAvatarTokens',
|
||||
inSignature: 'au',
|
||||
outSignature: 'a{us}'
|
||||
},
|
||||
{ name: 'RequestAvatars',
|
||||
inSignature: 'au',
|
||||
outSignature: ''
|
||||
}
|
||||
],
|
||||
signals: [
|
||||
{ name: 'AvatarRetrieved',
|
||||
inSignature: 'usays'
|
||||
},
|
||||
{ name: 'AvatarUpdated',
|
||||
inSignature: 'us'
|
||||
}
|
||||
]
|
||||
};
|
||||
let ConnectionAvatars = makeProxyClass(ConnectionAvatarsIface);
|
||||
|
||||
const CONNECTION_CONTACTS_NAME = CONNECTION_NAME + '.Interface.Contacts';
|
||||
const ConnectionContactsIface = {
|
||||
name: CONNECTION_CONTACTS_NAME,
|
||||
methods: [
|
||||
{ name: 'GetContactAttributes',
|
||||
inSignature: 'auasb',
|
||||
outSignature: 'a{ua{sv}}'
|
||||
}
|
||||
]
|
||||
};
|
||||
let ConnectionContacts = makeProxyClass(ConnectionContactsIface);
|
||||
|
||||
const CONNECTION_REQUESTS_NAME = CONNECTION_NAME + '.Interface.Requests';
|
||||
const ConnectionRequestsIface = {
|
||||
name: CONNECTION_REQUESTS_NAME,
|
||||
methods: [
|
||||
{ name: 'CreateChannel',
|
||||
inSignature: 'a{sv}',
|
||||
outSignature: 'oa{sv}'
|
||||
},
|
||||
{ name: 'EnsureChannel',
|
||||
inSignature: 'a{sv}',
|
||||
outSignature: 'boa{sv}'
|
||||
}
|
||||
],
|
||||
properties: [
|
||||
{ name: 'Channels',
|
||||
signature: 'a(oa{sv})',
|
||||
access: 'read' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'NewChannels',
|
||||
inSignature: 'a(oa{sv})'
|
||||
},
|
||||
{ name: 'ChannelClosed',
|
||||
inSignature: 'o'
|
||||
}
|
||||
]
|
||||
};
|
||||
let ConnectionRequests = makeProxyClass(ConnectionRequestsIface);
|
||||
|
||||
const CONNECTION_SIMPLE_PRESENCE_NAME = CONNECTION_NAME + '.Interface.SimplePresence';
|
||||
const ConnectionSimplePresenceIface = {
|
||||
name: CONNECTION_SIMPLE_PRESENCE_NAME,
|
||||
methods: [
|
||||
{ name: 'SetPresence',
|
||||
inSignature: 'ss'
|
||||
},
|
||||
{ name: 'GetPresences',
|
||||
inSignature: 'au',
|
||||
outSignature: 'a{u(uss)}'
|
||||
}
|
||||
],
|
||||
signals: [
|
||||
{ name: 'PresencesChanged',
|
||||
inSignature: 'a{u(uss)}' }
|
||||
]
|
||||
};
|
||||
let ConnectionSimplePresence = makeProxyClass(ConnectionSimplePresenceIface);
|
||||
|
||||
const ConnectionPresenceType = {
|
||||
UNSET: 0,
|
||||
OFFLINE: 1,
|
||||
AVAILABLE: 2,
|
||||
AWAY: 3,
|
||||
EXTENDED_AWAY: 4,
|
||||
HIDDEN: 5,
|
||||
BUSY: 6,
|
||||
UNKNOWN: 7,
|
||||
ERROR: 8
|
||||
};
|
||||
|
||||
const HandleType = {
|
||||
NONE: 0,
|
||||
CONTACT: 1,
|
||||
ROOM: 2,
|
||||
LIST: 3,
|
||||
GROUP: 4
|
||||
};
|
||||
|
||||
const CHANNEL_NAME = TELEPATHY + '.Channel';
|
||||
const ChannelIface = {
|
||||
name: CHANNEL_NAME,
|
||||
signals: [
|
||||
{ name: 'Closed',
|
||||
inSignature: '' }
|
||||
]
|
||||
};
|
||||
let Channel = makeProxyClass(ChannelIface);
|
||||
|
||||
const CHANNEL_TEXT_NAME = CHANNEL_NAME + '.Type.Text';
|
||||
const ChannelTextIface = {
|
||||
name: CHANNEL_TEXT_NAME,
|
||||
methods: [
|
||||
{ name: 'ListPendingMessages',
|
||||
inSignature: 'b',
|
||||
outSignature: 'a(uuuuus)'
|
||||
},
|
||||
{ name: 'AcknowledgePendingMessages',
|
||||
inSignature: 'au',
|
||||
outSignature: ''
|
||||
},
|
||||
{ name: 'Send',
|
||||
inSignature: 'us',
|
||||
outSignature: ''
|
||||
}
|
||||
],
|
||||
signals: [
|
||||
{ name: 'Received',
|
||||
inSignature: 'uuuuus' }
|
||||
]
|
||||
};
|
||||
let ChannelText = makeProxyClass(ChannelTextIface);
|
||||
|
||||
const ChannelTextMessageType = {
|
||||
NORMAL: 0,
|
||||
ACTION: 1,
|
||||
NOTICE: 2,
|
||||
AUTO_REPLY: 3,
|
||||
DELIVERY_REPORT: 4
|
||||
};
|
||||
|
||||
const CHANNEL_CONTACT_LIST_NAME = CHANNEL_NAME + '.Type.ContactList';
|
||||
// There is no interface associated with ContactList; it's just a
|
||||
// special kind of Channel.Interface.Group
|
||||
|
||||
const CHANNEL_GROUP_NAME = CHANNEL_NAME + '.Interface.Group';
|
||||
const ChannelGroupIface = {
|
||||
name: CHANNEL_GROUP_NAME,
|
||||
properties: [
|
||||
{ name: 'Members',
|
||||
signature: 'au',
|
||||
access: 'read' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'MembersChanged',
|
||||
inSignature: 'sauauauauuu' }
|
||||
]
|
||||
};
|
||||
let ChannelGroup = makeProxyClass(ChannelGroupIface);
|
||||
|
||||
const ACCOUNT_MANAGER_NAME = TELEPATHY + '.AccountManager';
|
||||
const AccountManagerIface = {
|
||||
name: ACCOUNT_MANAGER_NAME,
|
||||
properties: [
|
||||
{ name: 'ValidAccounts',
|
||||
signature: 'ao',
|
||||
access: 'read' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'AccountValidityChanged',
|
||||
inSignature: 'ob' }
|
||||
]
|
||||
};
|
||||
let AccountManager = makeProxyClass(AccountManagerIface);
|
||||
|
||||
const ACCOUNT_NAME = TELEPATHY + '.Account';
|
||||
const AccountIface = {
|
||||
name: ACCOUNT_NAME,
|
||||
properties: [
|
||||
{ name: 'Connection',
|
||||
signature: 'o',
|
||||
access: 'read' }
|
||||
]
|
||||
};
|
||||
let Account = makeProxyClass(AccountIface);
|
||||
|
||||
const CHANNEL_DISPATCHER_NAME = TELEPATHY + '.ChannelDispatcher';
|
||||
const ChannelDispatcherIface = {
|
||||
name: CHANNEL_DISPATCHER_NAME,
|
||||
methods: [
|
||||
{ name: 'EnsureChannel',
|
||||
inSignature: 'oa{sv}xs',
|
||||
outSignature: 'o' }
|
||||
]
|
||||
};
|
||||
let ChannelDispatcher = makeProxyClass(ChannelDispatcherIface);
|
||||
|
||||
const CHANNEL_REQUEST_NAME = TELEPATHY + '.ChannelRequest';
|
||||
const ChannelRequestIface = {
|
||||
name: CHANNEL_REQUEST_NAME,
|
||||
methods: [
|
||||
{ name: 'Proceed',
|
||||
inSignature: '',
|
||||
outSignature: '' }
|
||||
],
|
||||
signals: [
|
||||
{ name: 'Failed',
|
||||
signature: 'ss' },
|
||||
{ name: 'Succeeded',
|
||||
signature: '' }
|
||||
]
|
||||
};
|
||||
let ChannelRequest = makeProxyClass(ChannelRequestIface);
|
4
js/perf/Makefile.am
Normal file
4
js/perf/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
jsperfdir = $(pkgdatadir)/js/perf
|
||||
|
||||
dist_jsperf_DATA = \
|
||||
core.js
|
102
js/perf/core.js
Normal file
102
js/perf/core.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Scripting = imports.ui.scripting;
|
||||
|
||||
// This performance script measure the most important (core) performance
|
||||
// metrics for the shell. By looking at the output metrics of this script
|
||||
// someone should be able to get an idea of how well the shell is performing
|
||||
// on a particular system.
|
||||
|
||||
let METRICS = {
|
||||
overviewLatencyFirst:
|
||||
{ description: "Time to first frame after triggering overview, first time",
|
||||
units: "us" },
|
||||
overviewFramesFirst:
|
||||
{ description: "Frames displayed when going to overview, first time",
|
||||
units: "frames" },
|
||||
overviewLatencySubsequent:
|
||||
{ description: "Time to first frame after triggering overview, second time",
|
||||
units: "us"},
|
||||
overviewFramesSubsequent:
|
||||
{ description: "Frames displayed when going to overview, second time",
|
||||
units: "us" },
|
||||
usedAfterOverview:
|
||||
{ description: "Malloc'ed bytes after the overview is shown once",
|
||||
units: "B" },
|
||||
leakedAfterOverview:
|
||||
{ description: "Additional malloc'ed bytes the second time the overview is shown",
|
||||
units: "B" }
|
||||
};
|
||||
|
||||
function run() {
|
||||
Scripting.defineScriptEvent("overviewShowStart", "Starting to show the overview");
|
||||
Scripting.defineScriptEvent("overviewShowDone", "Overview finished showing");
|
||||
Scripting.defineScriptEvent("afterShowHide", "After a show/hide cycle for the overview");
|
||||
|
||||
yield Scripting.sleep(1000);
|
||||
yield Scripting.waitLeisure();
|
||||
for (let i = 0; i < 2; i++) {
|
||||
Scripting.scriptEvent('overviewShowStart');
|
||||
Main.overview.show();
|
||||
yield Scripting.waitLeisure();
|
||||
Scripting.scriptEvent('overviewShowDone');
|
||||
|
||||
Main.overview.hide();
|
||||
yield Scripting.waitLeisure();
|
||||
|
||||
global.gc();
|
||||
yield Scripting.sleep(1000);
|
||||
Scripting.collectStatistics();
|
||||
Scripting.scriptEvent('afterShowHide');
|
||||
}
|
||||
}
|
||||
|
||||
let showingOverview = false;
|
||||
let overviewShowStart;
|
||||
let overviewFrames;
|
||||
let overviewLatency;
|
||||
let mallocUsedSize = 0;
|
||||
let overviewShowCount = 0;
|
||||
let firstOverviewUsedSize;
|
||||
|
||||
function script_overviewShowStart(time) {
|
||||
showingOverview = true;
|
||||
overviewShowStart = time;
|
||||
overviewFrames = 0;
|
||||
}
|
||||
|
||||
function script_overviewShowDone(time) {
|
||||
showingOverview = false;
|
||||
|
||||
overviewShowCount++;
|
||||
|
||||
if (overviewShowCount == 1) {
|
||||
METRICS.overviewLatencyFirst.value = overviewLatency;
|
||||
METRICS.overviewFramesFirst.value = overviewFrames;
|
||||
} else {
|
||||
METRICS.overviewLatencySubsequent.value = overviewLatency;
|
||||
METRICS.overviewFramesSubsequent.value = overviewFrames;
|
||||
}
|
||||
}
|
||||
|
||||
function script_afterShowHide(time) {
|
||||
if (overviewShowCount == 1) {
|
||||
METRICS.usedAfterOverview.value = mallocUsedSize;
|
||||
} else {
|
||||
METRICS.leakedAfterOverview.value = mallocUsedSize - METRICS.usedAfterOverview.value;
|
||||
}
|
||||
}
|
||||
|
||||
function malloc_usedSize(time, bytes) {
|
||||
mallocUsedSize = bytes;
|
||||
}
|
||||
|
||||
function clutter_stagePaintDone(time) {
|
||||
if (showingOverview) {
|
||||
if (overviewFrames == 0)
|
||||
overviewLatency = time - overviewShowStart;
|
||||
|
||||
overviewFrames++;
|
||||
}
|
||||
}
|
4
js/prefs/Makefile.am
Normal file
4
js/prefs/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
jsprefsdir = $(pkgdatadir)/js/prefs
|
||||
|
||||
dist_jsprefs_DATA = \
|
||||
clockPreferences.js
|
93
js/prefs/clockPreferences.js
Normal file
93
js/prefs/clockPreferences.js
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const GConf = imports.gi.GConf;
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const GCONF_DIR = '/desktop/gnome/shell/clock';
|
||||
const FORMAT_KEY = GCONF_DIR + '/format';
|
||||
const SHOW_DATE_KEY = GCONF_DIR + '/show_date';
|
||||
const SHOW_SECONDS_KEY = GCONF_DIR + '/show_seconds';
|
||||
|
||||
|
||||
function ClockPreferences(uiFile) {
|
||||
this._init(uiFile);
|
||||
};
|
||||
|
||||
ClockPreferences.prototype = {
|
||||
_init: function(uiFile) {
|
||||
let builder = new Gtk.Builder();
|
||||
builder.add_from_file(uiFile);
|
||||
|
||||
this._dialog = builder.get_object('prefs-dialog');
|
||||
this._dialog.connect('response', Lang.bind(this, this._onResponse));
|
||||
|
||||
this._12hrRadio = builder.get_object('12hr_radio');
|
||||
this._24hrRadio = builder.get_object('24hr_radio');
|
||||
this._dateCheck = builder.get_object('date_check');
|
||||
this._secondsCheck = builder.get_object('seconds_check');
|
||||
|
||||
delete builder;
|
||||
|
||||
this._gconf = GConf.Client.get_default();
|
||||
this._gconf.add_dir(GCONF_DIR, GConf.ClientPreloadType.PRELOAD_NONE);
|
||||
this._notifyId = this._gconf.notify_add(GCONF_DIR,
|
||||
Lang.bind(this,
|
||||
this._updateDialog));
|
||||
|
||||
this._12hrRadio.connect('toggled', Lang.bind(this,
|
||||
function() {
|
||||
let format = this._12hrRadio.active ? '12-hour' : '24-hour';
|
||||
this._gconf.set_string(FORMAT_KEY, format);
|
||||
}));
|
||||
this._dateCheck.connect('toggled', Lang.bind(this,
|
||||
function() {
|
||||
this._gconf.set_bool(SHOW_DATE_KEY, this._dateCheck.active);
|
||||
}));
|
||||
this._secondsCheck.connect('toggled', Lang.bind(this,
|
||||
function() {
|
||||
this._gconf.set_bool(SHOW_SECONDS_KEY,
|
||||
this._secondsCheck.active);
|
||||
}));
|
||||
|
||||
this._updateDialog();
|
||||
},
|
||||
|
||||
show: function() {
|
||||
this._dialog.show_all();
|
||||
},
|
||||
|
||||
_updateDialog: function() {
|
||||
let format = this._gconf.get_string(FORMAT_KEY);
|
||||
this._12hrRadio.active = (format == "12-hour");
|
||||
this._24hrRadio.active = (format == "24-hour");
|
||||
|
||||
this._dateCheck.active = this._gconf.get_bool(SHOW_DATE_KEY);
|
||||
this._secondsCheck.active = this._gconf.get_bool(SHOW_SECONDS_KEY);
|
||||
},
|
||||
|
||||
_onResponse: function() {
|
||||
this._dialog.destroy();
|
||||
this._gconf.notify_remove(this._notifyId);
|
||||
this.emit('destroy');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ClockPreferences.prototype);
|
||||
|
||||
function main(params) {
|
||||
if ('progName' in params)
|
||||
GLib.set_prgname(params['progName']);
|
||||
Gtk.init(null, null);
|
||||
|
||||
let clockPrefs = new ClockPreferences(params['uiFile']);
|
||||
clockPrefs.connect('destroy',
|
||||
function() {
|
||||
Gtk.main_quit();
|
||||
});
|
||||
clockPrefs.show();
|
||||
|
||||
Gtk.main();
|
||||
}
|
@ -4,17 +4,20 @@ dist_jsui_DATA = \
|
||||
altTab.js \
|
||||
appDisplay.js \
|
||||
appFavorites.js \
|
||||
boxpointer.js \
|
||||
calendar.js \
|
||||
chrome.js \
|
||||
dash.js \
|
||||
dnd.js \
|
||||
docDisplay.js \
|
||||
environment.js \
|
||||
extensionSystem.js \
|
||||
extensionSystem.js \
|
||||
genericDisplay.js \
|
||||
lightbox.js \
|
||||
link.js \
|
||||
lookingGlass.js \
|
||||
magnifier.js \
|
||||
magnifierDBus.js \
|
||||
main.js \
|
||||
messageTray.js \
|
||||
notificationDaemon.js \
|
||||
@ -22,15 +25,14 @@ dist_jsui_DATA = \
|
||||
panel.js \
|
||||
placeDisplay.js \
|
||||
runDialog.js \
|
||||
search.js \
|
||||
scripting.js \
|
||||
search.js \
|
||||
shellDBus.js \
|
||||
sidebar.js \
|
||||
statusMenu.js \
|
||||
telepathyClient.js \
|
||||
tweener.js \
|
||||
widget.js \
|
||||
widgetBox.js \
|
||||
windowAttentionHandler.js \
|
||||
windowAttentionHandler.js \
|
||||
windowManager.js \
|
||||
workspacesView.js \
|
||||
workspaceSwitcherPopup.js \
|
||||
workspaceSwitcherPopup.js \
|
||||
workspace.js
|
||||
|
290
js/ui/altTab.js
290
js/ui/altTab.js
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
const Lang = imports.lang;
|
||||
@ -14,15 +13,7 @@ const St = imports.gi.St;
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const POPUP_ARROW_COLOR = new Clutter.Color();
|
||||
POPUP_ARROW_COLOR.from_pixel(0xffffffff);
|
||||
const POPUP_UNFOCUSED_ARROW_COLOR = new Clutter.Color();
|
||||
POPUP_UNFOCUSED_ARROW_COLOR.from_pixel(0x808080ff);
|
||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
||||
|
||||
const POPUP_APPICON_SIZE = 96;
|
||||
const POPUP_LIST_SPACING = 8;
|
||||
const POPUP_SCROLL_TIME = 0.10; // seconds
|
||||
|
||||
const DISABLE_HOVER_TIMEOUT = 500; // milliseconds
|
||||
@ -43,7 +34,8 @@ function AltTabPopup() {
|
||||
|
||||
AltTabPopup.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new Shell.GenericContainer({ reactive: true });
|
||||
this.actor = new Shell.GenericContainer({ name: 'altTabPopup',
|
||||
reactive: true });
|
||||
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
@ -54,7 +46,7 @@ AltTabPopup.prototype = {
|
||||
this._haveModal = false;
|
||||
|
||||
this._currentApp = 0;
|
||||
this._currentWindow = 0;
|
||||
this._currentWindow = -1;
|
||||
this._thumbnailTimeoutId = 0;
|
||||
this._motionTimeoutId = 0;
|
||||
|
||||
@ -62,7 +54,7 @@ AltTabPopup.prototype = {
|
||||
// the switcher appears underneath the current pointer location
|
||||
this._disableHover();
|
||||
|
||||
global.stage.add_actor(this.actor);
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
},
|
||||
|
||||
_getPreferredWidth: function (actor, forHeight, alloc) {
|
||||
@ -79,12 +71,18 @@ AltTabPopup.prototype = {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let focus = global.get_focus_monitor();
|
||||
|
||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
let vPadding = this.actor.get_theme_node().get_vertical_padding();
|
||||
let hPadding = leftPadding + rightPadding;
|
||||
|
||||
// Allocate the appSwitcher
|
||||
// We select a size based on an icon size that does not overflow the screen
|
||||
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(focus.width - POPUP_LIST_SPACING * 2);
|
||||
let [childMinHeight, childNaturalHeight] = this._appSwitcher.actor.get_preferred_height(focus.width - hPadding);
|
||||
let [childMinWidth, childNaturalWidth] = this._appSwitcher.actor.get_preferred_width(childNaturalHeight);
|
||||
childBox.x1 = Math.max(POPUP_LIST_SPACING, focus.x + Math.floor((focus.width - childNaturalWidth) / 2));
|
||||
childBox.x2 = Math.min(childBox.x1 + focus.width - POPUP_LIST_SPACING * 2, childBox.x1 + childNaturalWidth);
|
||||
childBox.x1 = Math.max(focus.x + leftPadding, focus.x + Math.floor((focus.width - childNaturalWidth) / 2));
|
||||
childBox.x2 = Math.min(childBox.x1 + focus.width - hPadding, childBox.x1 + childNaturalWidth);
|
||||
childBox.y1 = focus.y + Math.floor((focus.height - childNaturalHeight) / 2);
|
||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||
this._appSwitcher.actor.allocate(childBox, flags);
|
||||
@ -94,20 +92,26 @@ AltTabPopup.prototype = {
|
||||
// those calculations
|
||||
if (this._thumbnails) {
|
||||
let icon = this._appIcons[this._currentApp].actor;
|
||||
// Force a stage relayout to make sure we get the correct position
|
||||
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
|
||||
let [posX, posY] = icon.get_transformed_position();
|
||||
let thumbnailCenter = posX + icon.width / 2;
|
||||
let [childMinWidth, childNaturalWidth] = this._thumbnails.actor.get_preferred_width(-1);
|
||||
childBox.x1 = Math.max(POPUP_LIST_SPACING, Math.floor(thumbnailCenter - childNaturalWidth / 2));
|
||||
if (childBox.x1 + childNaturalWidth > focus.width - POPUP_LIST_SPACING * 2) {
|
||||
let offset = childBox.x1 + childNaturalWidth - focus.width + POPUP_LIST_SPACING * 2;
|
||||
childBox.x1 = Math.max(POPUP_LIST_SPACING, childBox.x1 - offset - POPUP_LIST_SPACING * 2);
|
||||
childBox.x1 = Math.max(focus.x + leftPadding, Math.floor(thumbnailCenter - childNaturalWidth / 2));
|
||||
if (childBox.x1 + childNaturalWidth > focus.x + focus.width - hPadding) {
|
||||
let offset = childBox.x1 + childNaturalWidth - focus.width + hPadding;
|
||||
childBox.x1 = Math.max(focus.x + leftPadding, childBox.x1 - offset - hPadding);
|
||||
}
|
||||
|
||||
let [found, spacing] = this.actor.get_theme_node().get_length('spacing', false);
|
||||
if (!found)
|
||||
spacing = 0;
|
||||
|
||||
childBox.x2 = childBox.x1 + childNaturalWidth;
|
||||
if (childBox.x2 > focus.width - POPUP_LIST_SPACING)
|
||||
childBox.x2 = focus.width - POPUP_LIST_SPACING;
|
||||
childBox.y1 = this._appSwitcher.actor.allocation.y2 + POPUP_LIST_SPACING * 2;
|
||||
this._thumbnails.addClones(focus.height - POPUP_LIST_SPACING - childBox.y1);
|
||||
if (childBox.x2 > focus.x + focus.width - rightPadding)
|
||||
childBox.x2 = focus.x + focus.width - rightPadding;
|
||||
childBox.y1 = this._appSwitcher.actor.allocation.y2 + spacing;
|
||||
this._thumbnails.addClones(focus.height - bottomPadding - childBox.y1);
|
||||
let [childMinHeight, childNaturalHeight] = this._thumbnails.actor.get_preferred_height(-1);
|
||||
childBox.y2 = childBox.y1 + childNaturalHeight;
|
||||
this._thumbnails.actor.allocate(childBox, flags);
|
||||
@ -116,7 +120,7 @@ AltTabPopup.prototype = {
|
||||
|
||||
show : function(backward) {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
let apps = tracker.get_running_apps ("");
|
||||
let apps = tracker.get_running_apps ('');
|
||||
|
||||
if (!apps.length)
|
||||
return false;
|
||||
@ -160,8 +164,9 @@ AltTabPopup.prototype = {
|
||||
this._select(0, 1, true);
|
||||
else
|
||||
this._select(1);
|
||||
} else
|
||||
} else {
|
||||
this._select(1);
|
||||
}
|
||||
}
|
||||
|
||||
// There's a race condition; if the user released Alt before
|
||||
@ -169,7 +174,7 @@ AltTabPopup.prototype = {
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=596695 for
|
||||
// details.) So we check now. (Have to do this after updating
|
||||
// selection.)
|
||||
let mods = global.get_modifier_keys();
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
if (!(mods & Gdk.ModifierType.MOD1_MASK)) {
|
||||
this._finish();
|
||||
return false;
|
||||
@ -186,10 +191,16 @@ AltTabPopup.prototype = {
|
||||
},
|
||||
|
||||
_nextWindow : function() {
|
||||
// We actually want the second window if we're in the unset state
|
||||
if (this._currentWindow == -1)
|
||||
this._currentWindow = 0;
|
||||
return mod(this._currentWindow + 1,
|
||||
this._appIcons[this._currentApp].cachedWindows.length);
|
||||
},
|
||||
_previousWindow : function() {
|
||||
// Also assume second window here
|
||||
if (this._currentWindow == -1)
|
||||
this._currentWindow = 1;
|
||||
return mod(this._currentWindow - 1,
|
||||
this._appIcons[this._currentApp].cachedWindows.length);
|
||||
},
|
||||
@ -209,7 +220,7 @@ AltTabPopup.prototype = {
|
||||
this.destroy();
|
||||
else if (this._thumbnailsFocused) {
|
||||
if (keysym == Clutter.Tab) {
|
||||
if (shift && this._currentWindow == 0)
|
||||
if (shift && (this._currentWindow == 0 || this._currentWindow == -1))
|
||||
this._select(this._previousApp());
|
||||
else if (!shift && this._currentWindow == this._appIcons[this._currentApp].cachedWindows.length - 1)
|
||||
this._select(this._nextApp());
|
||||
@ -229,7 +240,7 @@ AltTabPopup.prototype = {
|
||||
else if (keysym == Clutter.Right || keysym == Clutter.d)
|
||||
this._select(this._nextApp());
|
||||
else if (keysym == Clutter.Down || keysym == Clutter.s)
|
||||
this._select(this._currentApp, this._currentWindow);
|
||||
this._select(this._currentApp, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -248,7 +259,7 @@ AltTabPopup.prototype = {
|
||||
let direction = event.get_scroll_direction();
|
||||
if (direction == Clutter.ScrollDirection.UP) {
|
||||
if (this._thumbnailsFocused) {
|
||||
if (this._currentWindow == 0)
|
||||
if (this._currentWindow == 0 || this._currentWindow == -1)
|
||||
this._select(this._previousApp());
|
||||
else
|
||||
this._select(this._currentApp, this._previousWindow());
|
||||
@ -282,10 +293,17 @@ AltTabPopup.prototype = {
|
||||
_appActivated : function(appSwitcher, n) {
|
||||
// If the user clicks on the selected app, activate the
|
||||
// selected window; otherwise (eg, they click on an app while
|
||||
// !mouseActive) activate the first window of the clicked-on
|
||||
// app.
|
||||
let window = (n == this._currentApp) ? this._currentWindow : 0;
|
||||
Main.activateWindow(this._appIcons[n].cachedWindows[window]);
|
||||
// !mouseActive) activate the the clicked-on app.
|
||||
if (n == this._currentApp) {
|
||||
let window;
|
||||
if (this._currentWindow >= 0)
|
||||
window = this._appIcons[this._currentApp].cachedWindows[this._currentWindow];
|
||||
else
|
||||
window = null;
|
||||
this._appIcons[this._currentApp].app.activate_window(window, global.get_current_time());
|
||||
} else {
|
||||
this._appIcons[n].app.activate_window(null, global.get_current_time());
|
||||
}
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
@ -297,7 +315,8 @@ AltTabPopup.prototype = {
|
||||
},
|
||||
|
||||
_windowActivated : function(thumbnailList, n) {
|
||||
Main.activateWindow(this._appIcons[this._currentApp].cachedWindows[n]);
|
||||
let appIcon = this._appIcons[this._currentApp];
|
||||
Main.activateWindow(appIcon.cachedWindows[n]);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
@ -324,8 +343,11 @@ AltTabPopup.prototype = {
|
||||
|
||||
_finish : function() {
|
||||
let app = this._appIcons[this._currentApp];
|
||||
let window = app.cachedWindows[this._currentWindow];
|
||||
Main.activateWindow(window);
|
||||
if (this._currentWindow >= 0) {
|
||||
Main.activateWindow(app.cachedWindows[this._currentWindow]);
|
||||
} else {
|
||||
app.app.activate_window(null, global.get_current_time());
|
||||
}
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
@ -390,7 +412,7 @@ AltTabPopup.prototype = {
|
||||
this._thumbnailsFocused = (window != null) && !forceAppFocus;
|
||||
|
||||
this._currentApp = app;
|
||||
this._currentWindow = window ? window : 0;
|
||||
this._currentWindow = window ? window : -1;
|
||||
this._appSwitcher.highlight(app, this._thumbnailsFocused);
|
||||
|
||||
if (window != null) {
|
||||
@ -402,18 +424,23 @@ AltTabPopup.prototype = {
|
||||
!forceAppFocus) {
|
||||
this._thumbnailTimeoutId = Mainloop.timeout_add (
|
||||
THUMBNAIL_POPUP_TIME,
|
||||
Lang.bind(this, function () {
|
||||
this._select(this._currentApp, 0, true);
|
||||
return false;
|
||||
}));
|
||||
Lang.bind(this, this._timeoutPopupThumbnails));
|
||||
}
|
||||
},
|
||||
|
||||
_timeoutPopupThumbnails: function() {
|
||||
if (!this._thumbnails)
|
||||
this._createThumbnails();
|
||||
this._thumbnailTimeoutId = 0;
|
||||
this._thumbnailsFocused = false;
|
||||
return false;
|
||||
},
|
||||
|
||||
_destroyThumbnails : function() {
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
{ opacity: 0,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() { this.destroy(); }
|
||||
});
|
||||
this._thumbnails = null;
|
||||
@ -430,7 +457,7 @@ AltTabPopup.prototype = {
|
||||
Tweener.addTween(this._thumbnails.actor,
|
||||
{ opacity: 255,
|
||||
time: THUMBNAIL_FADE_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -441,12 +468,19 @@ function SwitcherList(squareItems) {
|
||||
|
||||
SwitcherList.prototype = {
|
||||
_init : function(squareItems) {
|
||||
this.actor = new St.BoxLayout({ style_class: 'switcher-list' });
|
||||
this.actor = new Shell.GenericContainer({ style_class: 'switcher-list' });
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocateTop));
|
||||
|
||||
// Here we use a GenericContainer so that we can force all the
|
||||
// children except the separator to have the same width.
|
||||
this._list = new Shell.GenericContainer();
|
||||
this._list.spacing = POPUP_LIST_SPACING;
|
||||
this._list = new Shell.GenericContainer({ style_class: 'switcher-list-item-container' });
|
||||
this._list.spacing = 0;
|
||||
this._list.connect('style-changed', Lang.bind(this, function() {
|
||||
let [found, spacing] = this._list.get_theme_node().get_length('spacing', false);
|
||||
this._list.spacing = (found) ? spacing : 0;
|
||||
}));
|
||||
|
||||
this._list.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this._list.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
@ -462,26 +496,72 @@ SwitcherList.prototype = {
|
||||
this.actor.add_actor(this._rightGradient);
|
||||
|
||||
// Those arrows indicate whether scrolling in one direction is possible
|
||||
this._leftArrow = new St.DrawingArea();
|
||||
this._leftArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||
pseudo_class: 'highlighted' });
|
||||
this._leftArrow.connect('repaint', Lang.bind(this,
|
||||
function (area) {
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT, TRANSPARENT_COLOR, POPUP_ARROW_COLOR);
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT);
|
||||
}));
|
||||
|
||||
this._rightArrow = new St.DrawingArea();
|
||||
this._rightArrow = new St.DrawingArea({ style_class: 'switcher-arrow',
|
||||
pseudo_class: 'highlighted' });
|
||||
this._rightArrow.connect('repaint', Lang.bind(this,
|
||||
function (area) {
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.RIGHT, TRANSPARENT_COLOR, POPUP_ARROW_COLOR);
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.RIGHT);
|
||||
}));
|
||||
|
||||
this._leftGradient.add_actor(this._leftArrow);
|
||||
this._rightGradient.add_actor(this._rightArrow);
|
||||
this.actor.add_actor(this._leftArrow);
|
||||
this.actor.add_actor(this._rightArrow);
|
||||
|
||||
this._items = [];
|
||||
this._highlighted = -1;
|
||||
this._separator = null;
|
||||
this._squareItems = squareItems;
|
||||
this._scrollable = false;
|
||||
this._minSize = 0;
|
||||
this._scrollableRight = true;
|
||||
this._scrollableLeft = false;
|
||||
},
|
||||
|
||||
_allocateTop: function(actor, box, flags) {
|
||||
let leftPadding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
|
||||
let rightPadding = this.actor.get_theme_node().get_padding(St.Side.RIGHT);
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let scrollable = this._minSize > box.x2 - box.x1;
|
||||
|
||||
this._clipBin.allocate(box, flags);
|
||||
|
||||
childBox.x1 = 0;
|
||||
childBox.y1 = 0;
|
||||
childBox.x2 = this._leftGradient.width;
|
||||
childBox.y2 = this.actor.height;
|
||||
this._leftGradient.allocate(childBox, flags);
|
||||
this._leftGradient.opacity = (this._scrollableLeft && scrollable) ? 255 : 0;
|
||||
|
||||
childBox.x1 = (this.actor.allocation.x2 - this.actor.allocation.x1) - this._rightGradient.width;
|
||||
childBox.y1 = 0;
|
||||
childBox.x2 = childBox.x1 + this._rightGradient.width;
|
||||
childBox.y2 = this.actor.height;
|
||||
this._rightGradient.allocate(childBox, flags);
|
||||
this._rightGradient.opacity = (this._scrollableRight && scrollable) ? 255 : 0;
|
||||
|
||||
let arrowWidth = Math.floor(leftPadding / 3);
|
||||
let arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = leftPadding / 2;
|
||||
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._leftArrow.allocate(childBox, flags);
|
||||
this._leftArrow.opacity = this._leftGradient.opacity;
|
||||
|
||||
arrowWidth = Math.floor(rightPadding / 3);
|
||||
arrowHeight = arrowWidth * 2;
|
||||
childBox.x1 = this.actor.width - arrowWidth - rightPadding / 2;
|
||||
childBox.y1 = this.actor.height / 2 - arrowWidth;
|
||||
childBox.x2 = childBox.x1 + arrowWidth;
|
||||
childBox.y2 = childBox.y1 + arrowHeight;
|
||||
this._rightArrow.allocate(childBox, flags);
|
||||
this._rightArrow.opacity = this._rightGradient.opacity;
|
||||
},
|
||||
|
||||
addItem : function(item) {
|
||||
@ -525,8 +605,7 @@ SwitcherList.prototype = {
|
||||
let itemSize = this._items[index].allocation.x2 - this._items[index].allocation.x1;
|
||||
let [posX, posY] = this._items[index].get_transformed_position();
|
||||
posX += this.actor.x;
|
||||
|
||||
if (posX + itemSize > monitor.width)
|
||||
if (posX + itemSize > monitor.width + monitor.x)
|
||||
this._scrollToRight();
|
||||
else if (posX < 0)
|
||||
this._scrollToLeft();
|
||||
@ -535,28 +614,33 @@ SwitcherList.prototype = {
|
||||
|
||||
_scrollToLeft : function() {
|
||||
let x = this._items[this._highlighted].allocation.x1;
|
||||
this._rightGradient.show();
|
||||
this._scrollableRight = true;
|
||||
Tweener.addTween(this._list, { anchor_x: x,
|
||||
time: POPUP_SCROLL_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function () {
|
||||
if (this._highlighted == 0)
|
||||
this._leftGradient.hide();
|
||||
if (this._highlighted == 0) {
|
||||
this._scrollableLeft = false;
|
||||
this.actor.queue_relayout();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
_scrollToRight : function() {
|
||||
this._scrollableLeft = true;
|
||||
let monitor = global.get_focus_monitor();
|
||||
let padding = this.actor.get_theme_node().get_horizontal_padding();
|
||||
let x = this._items[this._highlighted].allocation.x2 - monitor.width + padding + POPUP_LIST_SPACING * 2;
|
||||
this._leftGradient.show();
|
||||
let parentPadding = this.actor.get_parent().get_theme_node().get_horizontal_padding();
|
||||
let x = this._items[this._highlighted].allocation.x2 - monitor.width + padding + parentPadding;
|
||||
Tweener.addTween(this._list, { anchor_x: x,
|
||||
time: POPUP_SCROLL_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function () {
|
||||
if (this._highlighted == this._items.length - 1)
|
||||
this._rightGradient.hide();
|
||||
if (this._highlighted == this._items.length - 1) {
|
||||
this._scrollableRight = false;
|
||||
this.actor.queue_relayout();
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
@ -600,6 +684,7 @@ SwitcherList.prototype = {
|
||||
let totalSpacing = this._list.spacing * (this._items.length - 1);
|
||||
alloc.min_size = this._items.length * maxChildMin + separatorWidth + totalSpacing;
|
||||
alloc.natural_size = alloc.min_size;
|
||||
this._minSize = alloc.min_size;
|
||||
},
|
||||
|
||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||
@ -642,11 +727,14 @@ SwitcherList.prototype = {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
|
||||
let focus = global.get_focus_monitor();
|
||||
if (this.actor.allocation.x2 == focus.width - POPUP_LIST_SPACING) {
|
||||
let parentRightPadding = this.actor.get_parent().get_theme_node().get_padding(St.Side.RIGHT);
|
||||
if (this.actor.allocation.x2 == focus.x + focus.width - parentRightPadding) {
|
||||
if (this._squareItems)
|
||||
childWidth = childHeight;
|
||||
else
|
||||
childWidth = children[0].get_preferred_width(childHeight)[0];
|
||||
else {
|
||||
let [childMin, childNat] = children[0].get_preferred_width(childHeight);
|
||||
childWidth = childMin;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
@ -679,36 +767,6 @@ SwitcherList.prototype = {
|
||||
let topPadding = this.actor.get_theme_node().get_padding(St.Side.TOP);
|
||||
let bottomPadding = this.actor.get_theme_node().get_padding(St.Side.BOTTOM);
|
||||
|
||||
// Show the arrows and gradients when scrolling is needed
|
||||
if (children[children.length - 1].allocation.x2 > this.actor.width - leftPadding - rightPadding && !this._scrollable) {
|
||||
this._leftGradient.set_height(this.actor.height);
|
||||
this._leftGradient.x = this.actor.x;
|
||||
this._leftGradient.y = this.actor.y;
|
||||
|
||||
this._rightGradient.set_height(this.actor.height);
|
||||
this._rightGradient.x = this.actor.x + (this.actor.allocation.x2 - this.actor.allocation.x1) - this._rightGradient.width;
|
||||
this._rightGradient.y = this.actor.y;
|
||||
|
||||
let arrowWidth = Math.floor(leftPadding / 3);
|
||||
let arrowHeight = arrowWidth * 2;
|
||||
this._leftArrow.set_size(arrowWidth, arrowHeight);
|
||||
this._leftArrow.set_position(POPUP_LIST_SPACING, this.actor.height / 2 - arrowWidth);
|
||||
|
||||
arrowWidth = Math.floor(rightPadding / 3);
|
||||
arrowHeight = arrowWidth * 2;
|
||||
this._rightArrow.set_size(arrowWidth, arrowHeight);
|
||||
this._rightArrow.set_position(this._rightGradient.width - arrowHeight, this.actor.height / 2 - arrowWidth);
|
||||
|
||||
this._scrollable = true;
|
||||
|
||||
this._leftGradient.hide();
|
||||
this._rightGradient.show();
|
||||
}
|
||||
else if (!this._scrollable){
|
||||
this._leftGradient.hide();
|
||||
this._rightGradient.hide();
|
||||
}
|
||||
|
||||
// Clip the area for scrolling
|
||||
this._clipBin.set_clip(0, -topPadding, (this.actor.allocation.x2 - this.actor.allocation.x1) - leftPadding - rightPadding, this.actor.height + bottomPadding);
|
||||
}
|
||||
@ -723,7 +781,7 @@ function AppIcon(app) {
|
||||
AppIcon.prototype = {
|
||||
_init: function(app) {
|
||||
this.app = app;
|
||||
this.actor = new St.BoxLayout({ style_class: "alt-tab-app",
|
||||
this.actor = new St.BoxLayout({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
this.icon = null;
|
||||
this._iconBin = new St.Bin();
|
||||
@ -783,6 +841,8 @@ AppSwitcher.prototype = {
|
||||
|
||||
_getPreferredHeight: function (actor, forWidth, alloc) {
|
||||
let j = 0;
|
||||
let height = 0;
|
||||
|
||||
while(this._items.length > 1 && this._items[j].style_class != 'item-box') {
|
||||
j++;
|
||||
}
|
||||
@ -793,16 +853,11 @@ AppSwitcher.prototype = {
|
||||
if (this._separator)
|
||||
totalSpacing += this._separator.width + this._list.spacing;
|
||||
|
||||
// We just assume the whole screen here due to weirdness happing with the passed width
|
||||
let focus = global.get_focus_monitor();
|
||||
let availWidth = focus.width - POPUP_LIST_SPACING * 2 - this.actor.get_theme_node().get_horizontal_padding();
|
||||
let height = 0;
|
||||
|
||||
for(let i = 0; i < iconSizes.length; i++) {
|
||||
this._iconSize = iconSizes[i];
|
||||
height = iconSizes[i] + iconSpacing;
|
||||
let w = height * this._items.length + totalSpacing;
|
||||
if (w <= availWidth)
|
||||
if (w <= forWidth)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -811,17 +866,17 @@ AppSwitcher.prototype = {
|
||||
height = iconSizes[0] + iconSpacing;
|
||||
}
|
||||
|
||||
alloc.min_size = height;
|
||||
alloc.natural_size = height;
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
for(let i = 0; i < this.icons.length; i++) {
|
||||
if (this.icons[i].icon != null)
|
||||
break;
|
||||
this.icons[i].set_size(this._iconSize);
|
||||
}
|
||||
|
||||
alloc.min_size = height;
|
||||
alloc.natural_size = height;
|
||||
},
|
||||
|
||||
_allocate: function (actor, box, flags) {
|
||||
// Allocate the main list items
|
||||
SwitcherList.prototype._allocate.call(this, actor, box, flags);
|
||||
|
||||
@ -846,16 +901,13 @@ AppSwitcher.prototype = {
|
||||
// thumbnails are visible (ie, when the app icon is supposed to be
|
||||
// in justOutline mode). Apps with multiple windows will normally
|
||||
// show a dim arrow, but show a bright arrow when they are
|
||||
// highlighted; their redraw handler will use the right color
|
||||
// based on this._curApp; we just need to do a queue_relayout() to
|
||||
// force it to redraw. (queue_redraw() doesn't work because
|
||||
// ShellDrawingArea only redraws on allocate.)
|
||||
// highlighted.
|
||||
highlight : function(n, justOutline) {
|
||||
if (this._curApp != -1) {
|
||||
if (this.icons[this._curApp].cachedWindows.length == 1)
|
||||
this._arrows[this._curApp].hide();
|
||||
else
|
||||
this._arrows[this._curApp].queue_relayout();
|
||||
this._arrows[this._curApp].remove_style_pseudo_class('highlighted');
|
||||
}
|
||||
|
||||
SwitcherList.prototype.highlight.call(this, n, justOutline);
|
||||
@ -865,7 +917,7 @@ AppSwitcher.prototype = {
|
||||
if (justOutline && this.icons[this._curApp].cachedWindows.length == 1)
|
||||
this._arrows[this._curApp].show();
|
||||
else
|
||||
this._arrows[this._curApp].queue_relayout();
|
||||
this._arrows[this._curApp].add_style_pseudo_class('highlighted');
|
||||
}
|
||||
},
|
||||
|
||||
@ -874,12 +926,10 @@ AppSwitcher.prototype = {
|
||||
this.addItem(appIcon.actor);
|
||||
|
||||
let n = this._arrows.length;
|
||||
let arrow = new St.DrawingArea();
|
||||
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
|
||||
arrow.connect('repaint', Lang.bind(this,
|
||||
function (area) {
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.DOWN,
|
||||
TRANSPARENT_COLOR,
|
||||
this._curApp == n ? POPUP_ARROW_COLOR : POPUP_UNFOCUSED_ARROW_COLOR);
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.DOWN);
|
||||
}));
|
||||
this._list.add_actor(arrow);
|
||||
this._arrows.push(arrow);
|
||||
@ -914,7 +964,7 @@ ThumbnailList.prototype = {
|
||||
|
||||
let activeWorkspace = global.screen.get_active_workspace();
|
||||
|
||||
// We fake the value of "separatorAdded" when the app has no window
|
||||
// We fake the value of 'separatorAdded' when the app has no window
|
||||
// on the current workspace, to avoid displaying a useless separator in
|
||||
// that case.
|
||||
let separatorAdded = windows.length == 0 || windows[0].get_workspace() != activeWorkspace;
|
||||
@ -930,10 +980,10 @@ ThumbnailList.prototype = {
|
||||
separatorAdded = true;
|
||||
}
|
||||
|
||||
let box = new St.BoxLayout({ style_class: "thumbnail-box",
|
||||
let box = new St.BoxLayout({ style_class: 'thumbnail-box',
|
||||
vertical: true });
|
||||
|
||||
let bin = new St.Bin({ style_class: "thumbnail" });
|
||||
let bin = new St.Bin({ style_class: 'thumbnail' });
|
||||
|
||||
box.add_actor(bin);
|
||||
this._thumbnailBins.push(bin);
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Pango = imports.gi.Pango;
|
||||
const GLib = imports.gi.GLib;
|
||||
@ -23,6 +22,7 @@ const Workspace = imports.ui.workspace;
|
||||
|
||||
const APPICON_SIZE = 48;
|
||||
const WELL_MAX_COLUMNS = 8;
|
||||
const MENU_POPUP_TIMEOUT = 600;
|
||||
|
||||
function AllAppView() {
|
||||
this._init();
|
||||
@ -286,17 +286,12 @@ BaseAppSearchProvider.prototype = {
|
||||
|
||||
activateResult: function(id) {
|
||||
let app = this._appSys.get_app(id);
|
||||
let windows = app.get_windows();
|
||||
|
||||
if (windows.length > 0)
|
||||
Main.activateWindow(windows[0]);
|
||||
else
|
||||
app.launch();
|
||||
app.activate();
|
||||
},
|
||||
|
||||
dragActivateResult: function(id) {
|
||||
let app = this._appSys.get_app(id);
|
||||
app.launch();
|
||||
app.open_new_window();
|
||||
}
|
||||
};
|
||||
|
||||
@ -328,7 +323,7 @@ AppSearchProvider.prototype = {
|
||||
},
|
||||
|
||||
expandSearch: function(terms) {
|
||||
log("TODO expand search");
|
||||
log('TODO expand search');
|
||||
}
|
||||
};
|
||||
|
||||
@ -391,7 +386,6 @@ function AppWellIcon(app) {
|
||||
AppWellIcon.prototype = {
|
||||
_init : function(app) {
|
||||
this.app = app;
|
||||
this._running = false;
|
||||
this.actor = new St.Clickable({ style_class: 'app-well-app',
|
||||
reactive: true,
|
||||
x_fill: true,
|
||||
@ -404,68 +398,73 @@ AppWellIcon.prototype = {
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this._menu = null;
|
||||
|
||||
this._draggable = DND.makeDraggable(this.actor,
|
||||
{ manualMode: true });
|
||||
this._dragStartX = null;
|
||||
this._dragStartY = null;
|
||||
this._draggable = DND.makeDraggable(this.actor);
|
||||
this._draggable.connect('drag-begin', Lang.bind(this,
|
||||
function () {
|
||||
this._removeMenuTimeout();
|
||||
}));
|
||||
|
||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||
this.actor.connect('notify::hover', Lang.bind(this, this._onHoverChange));
|
||||
this.actor.connect('show', Lang.bind(this, this._onShow));
|
||||
this.actor.connect('hide', Lang.bind(this, this._onHideDestroy));
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onHideDestroy));
|
||||
|
||||
this._appWindowChangedId = 0;
|
||||
this._stateChangedId = 0;
|
||||
this._menuTimeoutId = 0;
|
||||
},
|
||||
|
||||
_onShow: function() {
|
||||
this._appWindowChangedId = this.app.connect('windows-changed',
|
||||
Lang.bind(this,
|
||||
this._updateStyleClass));
|
||||
this._updateStyleClass();
|
||||
this._stateChangedId = this.app.connect('notify::state',
|
||||
Lang.bind(this,
|
||||
this._onStateChanged));
|
||||
this._onStateChanged();
|
||||
},
|
||||
|
||||
_onHideDestroy: function() {
|
||||
if (this._appWindowChangedId > 0)
|
||||
this.app.disconnect(this._appWindowChangedId);
|
||||
if (this._stateChangedId > 0)
|
||||
this.app.disconnect(this._stateChangedId);
|
||||
this._removeMenuTimeout();
|
||||
},
|
||||
|
||||
_updateStyleClass: function() {
|
||||
let windows = this.app.get_windows();
|
||||
let running = windows.length > 0;
|
||||
this._running = running;
|
||||
let style = "app-well-app";
|
||||
if (this._running)
|
||||
style += " running";
|
||||
if (this._selected)
|
||||
style += " selected";
|
||||
this.actor.style_class = style;
|
||||
_removeMenuTimeout: function() {
|
||||
if (this._menuTimeoutId > 0) {
|
||||
Mainloop.source_remove(this._menuTimeoutId);
|
||||
this._menuTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_onStateChanged: function() {
|
||||
if (this.app.state != Shell.AppState.STOPPED)
|
||||
this.actor.add_style_class_name('running');
|
||||
else
|
||||
this.actor.remove_style_class_name('running');
|
||||
},
|
||||
|
||||
_onButtonPress: function(actor, event) {
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._dragStartX = stageX;
|
||||
this._dragStartY = stageY;
|
||||
},
|
||||
|
||||
_onHoverChange: function(actor) {
|
||||
let hover = this.actor.hover;
|
||||
if (!hover) {
|
||||
if (this.actor.pressed && this._dragStartX != null) {
|
||||
this.actor.fake_release();
|
||||
this._draggable.startDrag(this._dragStartX, this._dragStartY,
|
||||
global.get_current_time());
|
||||
} else {
|
||||
this._dragStartX = null;
|
||||
this._dragStartY = null;
|
||||
}
|
||||
let button = event.get_button();
|
||||
if (button == 1) {
|
||||
this._removeMenuTimeout();
|
||||
this._menuTimeoutId = Mainloop.timeout_add(MENU_POPUP_TIMEOUT,
|
||||
Lang.bind(this, function() {
|
||||
this.popupMenu(button);
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_onClicked: function(actor, event) {
|
||||
this._removeMenuTimeout();
|
||||
|
||||
let button = event.get_button();
|
||||
if (button == 1) {
|
||||
this._onActivate(event);
|
||||
} else if (button == 2) {
|
||||
let newWorkspace = Main.overview.workspaces.addWorkspace();
|
||||
if (newWorkspace != null) {
|
||||
newWorkspace.activate(global.get_current_time());
|
||||
this.emit('launching');
|
||||
this.app.open_new_window();
|
||||
Main.overview.hide();
|
||||
}
|
||||
} else if (button == 3) {
|
||||
// Don't bind to the right click here; we want left click outside the
|
||||
// area to deactivate as well.
|
||||
@ -479,6 +478,9 @@ AppWellIcon.prototype = {
|
||||
},
|
||||
|
||||
popupMenu: function(activatingButton) {
|
||||
this._removeMenuTimeout();
|
||||
this.actor.fake_release();
|
||||
|
||||
if (!this._menu) {
|
||||
this._menu = new AppIconMenu(this);
|
||||
this._menu.connect('highlight-window', Lang.bind(this, function (menu, window) {
|
||||
@ -501,11 +503,6 @@ AppWellIcon.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
activateMostRecentWindow: function () {
|
||||
let mostRecentWindow = this.app.get_windows()[0];
|
||||
Main.activateWindow(mostRecentWindow);
|
||||
},
|
||||
|
||||
highlightWindow: function(metaWindow) {
|
||||
if (this._didActivateWindow)
|
||||
return;
|
||||
@ -518,13 +515,17 @@ AppWellIcon.prototype = {
|
||||
if (metaWindow) {
|
||||
this._didActivateWindow = true;
|
||||
Main.activateWindow(metaWindow);
|
||||
} else
|
||||
} else {
|
||||
Main.overview.hide();
|
||||
}
|
||||
},
|
||||
|
||||
setSelected: function (isSelected) {
|
||||
this._selected = isSelected;
|
||||
this._updateStyleClass();
|
||||
if (this._selected)
|
||||
this.actor.add_style_class_name('selected');
|
||||
else
|
||||
this.actor.remove_style_class_name('selected');
|
||||
},
|
||||
|
||||
_onMenuPoppedUp: function() {
|
||||
@ -536,6 +537,8 @@ AppWellIcon.prototype = {
|
||||
},
|
||||
|
||||
_onMenuPoppedDown: function() {
|
||||
this.actor.sync_hover();
|
||||
|
||||
if (this._didActivateWindow)
|
||||
return;
|
||||
if (!this._setWindowSelection)
|
||||
@ -546,38 +549,24 @@ AppWellIcon.prototype = {
|
||||
},
|
||||
|
||||
_getRunning: function() {
|
||||
return this.app.get_windows().length > 0;
|
||||
return this.app.state != Shell.AppState.STOPPED;
|
||||
},
|
||||
|
||||
_onActivate: function (event) {
|
||||
let running = this._getRunning();
|
||||
this.emit('launching');
|
||||
let modifiers = Shell.get_event_state(event);
|
||||
|
||||
if (!running) {
|
||||
this.app.launch();
|
||||
Main.overview.hide();
|
||||
if (modifiers & Clutter.ModifierType.CONTROL_MASK
|
||||
&& this.app.state == Shell.AppState.RUNNING) {
|
||||
this.app.open_new_window();
|
||||
} else {
|
||||
let modifiers = Shell.get_event_state(event);
|
||||
|
||||
if (modifiers & Clutter.ModifierType.CONTROL_MASK) {
|
||||
this.app.launch();
|
||||
Main.overview.hide();
|
||||
} else {
|
||||
this.activateMostRecentWindow();
|
||||
}
|
||||
this.app.activate();
|
||||
}
|
||||
Main.overview.hide();
|
||||
},
|
||||
|
||||
shellWorkspaceLaunch : function() {
|
||||
// Here we just always launch the application again, even if we know
|
||||
// it was already running. For most applications this
|
||||
// should have the effect of creating a new window, whether that's
|
||||
// a second process (in the case of Calculator) or IPC to existing
|
||||
// instance (Firefox). There are a few less-sensical cases such
|
||||
// as say Pidgin, but ideally what we do there is have the app
|
||||
// express to us that it doesn't do relaunch=new-window in the
|
||||
// .desktop file.
|
||||
this.app.launch();
|
||||
this.app.open_new_window();
|
||||
},
|
||||
|
||||
getDragActor: function() {
|
||||
@ -600,26 +589,19 @@ AppIconMenu.prototype = {
|
||||
_init: function(source) {
|
||||
this._source = source;
|
||||
|
||||
this._arrowSize = 4; // CSS default
|
||||
this._spacing = 0; // CSS default
|
||||
|
||||
this._dragStartX = 0;
|
||||
this._dragStartY = 0;
|
||||
|
||||
this.actor = new Shell.GenericContainer({ reactive: true });
|
||||
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||
|
||||
this._windowContainerBox = new St.Bin({ style_class: 'app-well-menu' });
|
||||
this._windowContainer = new Shell.Menu({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
width: Main.overview._dash.actor.width });
|
||||
this._windowContainerBox.set_child(this._windowContainer);
|
||||
this._windowContainer = new Shell.Menu({ style_class: 'app-well-menu',
|
||||
vertical: true,
|
||||
width: Main.overview._dash.actor.width });
|
||||
this._windowContainer.connect('unselected', Lang.bind(this, this._onItemUnselected));
|
||||
this._windowContainer.connect('selected', Lang.bind(this, this._onItemSelected));
|
||||
this._windowContainer.connect('cancelled', Lang.bind(this, this._onWindowSelectionCancelled));
|
||||
this._windowContainer.connect('activate', Lang.bind(this, this._onItemActivate));
|
||||
this.actor.add_actor(this._windowContainerBox);
|
||||
this.actor.add_actor(this._windowContainer);
|
||||
|
||||
// Stay popped up on release over application icon
|
||||
this._windowContainer.set_persistent_source(this._source.actor);
|
||||
@ -629,16 +611,9 @@ AppIconMenu.prototype = {
|
||||
this._windowContainer.connect('leave-event', Lang.bind(this, this._onMenuLeave));
|
||||
this._windowContainer.connect('button-release-event', Lang.bind(this, this._onMenuButtonRelease));
|
||||
|
||||
this._borderColor = new Clutter.Color();
|
||||
this._backgroundColor = new Clutter.Color();
|
||||
this._windowContainerBox.connect('style-changed', Lang.bind(this, this._onStyleChanged));
|
||||
|
||||
this._arrow = new St.DrawingArea();
|
||||
this._arrow = new St.DrawingArea({ style_class: 'app-well-menu-arrow' });
|
||||
this._arrow.connect('repaint', Lang.bind(this, function (area) {
|
||||
Shell.draw_box_pointer(area,
|
||||
Shell.PointerDirection.LEFT,
|
||||
this._borderColor,
|
||||
this._backgroundColor);
|
||||
Shell.draw_box_pointer(area, Shell.PointerDirection.LEFT);
|
||||
}));
|
||||
this.actor.add_actor(this._arrow);
|
||||
|
||||
@ -649,43 +624,44 @@ AppIconMenu.prototype = {
|
||||
}));
|
||||
source.actor.connect('destroy', Lang.bind(this, function () { this.actor.destroy(); }));
|
||||
|
||||
global.stage.add_actor(this.actor);
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let [min, natural] = this._windowContainerBox.get_preferred_width(forHeight);
|
||||
min += this._arrowSize;
|
||||
natural += this._arrowSize;
|
||||
alloc.min_size = min;
|
||||
alloc.natural_size = natural;
|
||||
let [menuMin, menuNatural] = this._windowContainer.get_preferred_width(forHeight);
|
||||
let [arrowMin, arrowNatural] = this._arrow.get_preferred_width(forHeight);
|
||||
alloc.min_size = menuMin + arrowMin;
|
||||
alloc.natural_size = menuNatural + arrowNatural;
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let [min, natural] = this._windowContainerBox.get_preferred_height(forWidth);
|
||||
let [min, natural] = this._windowContainer.get_preferred_height(forWidth);
|
||||
alloc.min_size = min;
|
||||
alloc.natural_size = natural;
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let themeNode = this._windowContainerBox.get_theme_node();
|
||||
let themeNode = this._windowContainer.get_theme_node();
|
||||
|
||||
let width = box.x2 - box.x1;
|
||||
let height = box.y2 - box.y1;
|
||||
|
||||
let [arrowMinWidth, arrowWidth] = this._arrow.get_preferred_width(height);
|
||||
|
||||
childBox.x1 = 0;
|
||||
childBox.x2 = this._arrowSize;
|
||||
childBox.y1 = Math.floor((height / 2) - (this._arrowSize / 2));
|
||||
childBox.y2 = childBox.y1 + this._arrowSize;
|
||||
childBox.x2 = arrowWidth;
|
||||
childBox.y1 = Math.floor((height / 2) - (arrowWidth / 2));
|
||||
childBox.y2 = childBox.y1 + arrowWidth;
|
||||
this._arrow.allocate(childBox, flags);
|
||||
|
||||
// Ensure the arrow is above the border area
|
||||
let border = themeNode.get_border_width(St.Side.LEFT);
|
||||
childBox.x1 = this._arrowSize - border;
|
||||
childBox.x1 = arrowWidth - border;
|
||||
childBox.x2 = width;
|
||||
childBox.y1 = 0;
|
||||
childBox.y2 = height;
|
||||
this._windowContainerBox.allocate(childBox, flags);
|
||||
this._windowContainer.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
_redisplay: function() {
|
||||
@ -737,8 +713,8 @@ AppIconMenu.prototype = {
|
||||
},
|
||||
|
||||
_appendSeparator: function () {
|
||||
let bin = new St.Bin({ style_class: "app-well-menu-separator" });
|
||||
this._windowContainer.append_separator(bin, Big.BoxPackFlags.NONE);
|
||||
let bin = new St.Bin({ style_class: 'app-well-menu-separator' });
|
||||
this._windowContainer.add_actor(bin);
|
||||
},
|
||||
|
||||
_appendMenuItem: function(labelText) {
|
||||
@ -746,7 +722,7 @@ AppIconMenu.prototype = {
|
||||
reactive: true });
|
||||
let label = new St.Label({ text: labelText });
|
||||
box.add(label);
|
||||
this._windowContainer.append(box, Big.BoxPackFlags.NONE);
|
||||
this._windowContainer.add_actor(box);
|
||||
return box;
|
||||
},
|
||||
|
||||
@ -797,12 +773,12 @@ AppIconMenu.prototype = {
|
||||
|
||||
_updateHighlight: function (item) {
|
||||
if (this._highlightedItem) {
|
||||
this._highlightedItem.set_style_pseudo_class(null);
|
||||
this._highlightedItem.remove_style_pseudo_class('hover');
|
||||
this.emit('highlight-window', null);
|
||||
}
|
||||
this._highlightedItem = item;
|
||||
if (this._highlightedItem) {
|
||||
item.set_style_pseudo_class('hover');
|
||||
item.add_style_pseudo_class('hover');
|
||||
let window = this._highlightedItem._window;
|
||||
if (window)
|
||||
this.emit('highlight-window', window);
|
||||
@ -848,7 +824,7 @@ AppIconMenu.prototype = {
|
||||
let metaWindow = child._window;
|
||||
this.emit('activate-window', metaWindow);
|
||||
} else if (child == this._newWindowMenuItem) {
|
||||
this._source.app.launch();
|
||||
this._source.app.open_new_window();
|
||||
this.emit('activate-window', null);
|
||||
} else if (child == this._toggleFavoriteMenuItem) {
|
||||
let favs = AppFavorites.getAppFavorites();
|
||||
@ -864,28 +840,6 @@ AppIconMenu.prototype = {
|
||||
_onWindowSelectionCancelled: function () {
|
||||
this.emit('highlight-window', null);
|
||||
this.popdown();
|
||||
},
|
||||
|
||||
_onStyleChanged: function() {
|
||||
let themeNode = this._windowContainerBox.get_theme_node();
|
||||
let [success, len] = themeNode.get_length('-shell-arrow-size', false);
|
||||
if (success) {
|
||||
this._arrowSize = len;
|
||||
this.actor.queue_relayout();
|
||||
}
|
||||
[success, len] = themeNode.get_length('-shell-menu-spacing', false)
|
||||
if (success) {
|
||||
this._windowContainer.spacing = len;
|
||||
}
|
||||
let color = new Clutter.Color();
|
||||
if (themeNode.get_background_color(color)) {
|
||||
this._backgroundColor = color;
|
||||
color = new Clutter.Color();
|
||||
}
|
||||
if (themeNode.get_border_color(St.Side.LEFT, color)) {
|
||||
this._borderColor = color;
|
||||
}
|
||||
this._arrow.queue_repaint();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(AppIconMenu.prototype);
|
||||
@ -896,7 +850,7 @@ function WellGrid() {
|
||||
|
||||
WellGrid.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ name: "dashAppWell", vertical: true });
|
||||
this.actor = new St.BoxLayout({ name: 'dashAppWell', vertical: true });
|
||||
// Pulled from CSS, but hardcode some defaults here
|
||||
this._spacing = 0;
|
||||
this._item_size = 48;
|
||||
@ -1027,15 +981,12 @@ AppWell.prototype = {
|
||||
|
||||
this._favorites = [];
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
this._grid = new WellGrid();
|
||||
this.actor = this._grid.actor;
|
||||
this.actor._delegate = this;
|
||||
|
||||
this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
|
||||
|
||||
this._grid = new WellGrid();
|
||||
this.actor.append(this._grid.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._tracker = Shell.WindowTracker.get_default();
|
||||
this._appSystem = Shell.AppSystem.get_default();
|
||||
|
||||
@ -1061,7 +1012,7 @@ AppWell.prototype = {
|
||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||
|
||||
/* hardcode here pending some design about how exactly desktop contexts behave */
|
||||
let contextId = "";
|
||||
let contextId = '';
|
||||
|
||||
let running = this._tracker.get_running_apps(contextId);
|
||||
let runningIds = this._appIdListToHash(running);
|
||||
|
164
js/ui/boxpointer.js
Normal file
164
js/ui/boxpointer.js
Normal file
@ -0,0 +1,164 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Cairo = imports.cairo;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
/**
|
||||
* BoxPointer:
|
||||
* @side: A St.Side type; currently only St.Side.TOP is implemented
|
||||
* @binProperties: Properties to set on contained bin
|
||||
*
|
||||
* An actor which displays a triangle "arrow" pointing to a given
|
||||
* side. The .bin property is a container in which content can be
|
||||
* placed. The arrow position may be controlled via setArrowOrigin().
|
||||
*
|
||||
*/
|
||||
function BoxPointer(side, binProperties) {
|
||||
this._init(side, binProperties);
|
||||
}
|
||||
|
||||
BoxPointer.prototype = {
|
||||
_init: function(arrowSide, binProperties) {
|
||||
if (arrowSide != St.Side.TOP)
|
||||
throw new Error('Not implemented');
|
||||
this._arrowSide = arrowSide;
|
||||
this._arrowOrigin = 0;
|
||||
this.actor = new St.Bin({ x_fill: true,
|
||||
y_fill: true });
|
||||
this._container = new Shell.GenericContainer();
|
||||
this.actor.set_child(this._container);
|
||||
this._container.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||
this._container.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||
this._container.connect('allocate', Lang.bind(this, this._allocate));
|
||||
this.bin = new St.Bin(binProperties);
|
||||
this._container.add_actor(this.bin);
|
||||
this._border = new St.DrawingArea();
|
||||
this._border.connect('repaint', Lang.bind(this, this._drawBorder));
|
||||
this._container.add_actor(this._border);
|
||||
this.bin.raise(this._border);
|
||||
},
|
||||
|
||||
_adjustAllocationForArrow: function(isWidth, alloc) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let found, borderWidth, base, rise;
|
||||
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||
alloc.min_size += borderWidth * 2;
|
||||
alloc.natural_size += borderWidth * 2;
|
||||
if ((!isWidth && (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM))
|
||||
|| (isWidth && (this._arrowSide == St.Side.LEFT || this._arrowSide == St.Side.RIGHT))) {
|
||||
let [found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||
alloc.min_size += rise;
|
||||
alloc.natural_size += rise;
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let [minInternalSize, natInternalSize] = this.bin.get_preferred_width(forHeight);
|
||||
alloc.min_size = minInternalSize;
|
||||
alloc.natural_size = natInternalSize;
|
||||
this._adjustAllocationForArrow(true, alloc);
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let [minSize, naturalSize] = this.bin.get_preferred_height(forWidth);
|
||||
alloc.min_size = minSize;
|
||||
alloc.natural_size = naturalSize;
|
||||
this._adjustAllocationForArrow(false, alloc);
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
let found, borderWidth, borderRadius, rise, base;
|
||||
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||
[found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||
let childBox = new Clutter.ActorBox();
|
||||
let availWidth = box.x2 - box.x1;
|
||||
let availHeight = box.y2 - box.y1;
|
||||
|
||||
childBox.x1 = 0;
|
||||
childBox.y1 = 0;
|
||||
childBox.x2 = availWidth;
|
||||
childBox.y2 = availHeight;
|
||||
this._border.allocate(childBox, flags);
|
||||
switch (this._arrowSide) {
|
||||
case St.Side.TOP:
|
||||
childBox.x1 = borderWidth;
|
||||
childBox.y1 = rise + borderWidth;
|
||||
childBox.x2 = availWidth - borderWidth;
|
||||
childBox.y2 = availHeight - borderWidth;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.bin.allocate(childBox, flags);
|
||||
},
|
||||
|
||||
_drawBorder: function(area) {
|
||||
let themeNode = this.actor.get_theme_node();
|
||||
|
||||
let found, borderWidth, borderRadius, rise, base;
|
||||
[found, borderWidth] = themeNode.get_length('-arrow-border-width', false);
|
||||
[found, base] = themeNode.get_length('-arrow-base', false);
|
||||
[found, rise] = themeNode.get_length('-arrow-rise', false);
|
||||
[found, borderRadius] = themeNode.get_length('-arrow-border-radius', false);
|
||||
|
||||
let halfBorder = borderWidth / 2;
|
||||
|
||||
let borderColor = new Clutter.Color();
|
||||
themeNode.get_color('-arrow-border-color', false, borderColor);
|
||||
let backgroundColor = new Clutter.Color();
|
||||
themeNode.get_color('-arrow-background-color', false, backgroundColor);
|
||||
|
||||
let [width, height] = area.get_surface_size();
|
||||
let [boxWidth, boxHeight] = [width, height];
|
||||
if (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM) {
|
||||
boxHeight -= rise;
|
||||
} else {
|
||||
boxWidth -= rise;
|
||||
}
|
||||
let cr = area.get_context();
|
||||
Clutter.cairo_set_source_color(cr, borderColor);
|
||||
if (this._arrowSide == St.Side.TOP) {
|
||||
cr.translate(0, rise);
|
||||
}
|
||||
cr.moveTo(borderRadius, halfBorder);
|
||||
if (this._arrowSide == St.Side.TOP) {
|
||||
cr.translate(0, -rise);
|
||||
let halfBase = Math.floor(base/2);
|
||||
cr.lineTo(this._arrowOrigin - halfBase, rise + halfBorder);
|
||||
cr.lineTo(this._arrowOrigin, halfBorder);
|
||||
cr.lineTo(this._arrowOrigin + halfBase, rise + halfBorder);
|
||||
cr.translate(0, rise);
|
||||
}
|
||||
cr.lineTo(boxWidth - borderRadius, halfBorder);
|
||||
cr.arc(boxWidth - borderRadius - halfBorder, borderRadius + halfBorder, borderRadius,
|
||||
3*Math.PI/2, Math.PI*2);
|
||||
cr.lineTo(boxWidth - halfBorder, boxHeight - borderRadius);
|
||||
cr.arc(boxWidth - borderRadius - halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||
0, Math.PI/2);
|
||||
cr.lineTo(borderRadius, boxHeight - halfBorder);
|
||||
cr.arc(borderRadius + halfBorder, boxHeight - borderRadius - halfBorder, borderRadius,
|
||||
Math.PI/2, Math.PI);
|
||||
cr.lineTo(halfBorder, borderRadius);
|
||||
cr.arc(borderRadius + halfBorder, borderRadius + halfBorder, borderRadius,
|
||||
Math.PI, 3*Math.PI/2);
|
||||
Clutter.cairo_set_source_color(cr, backgroundColor);
|
||||
cr.fillPreserve();
|
||||
Clutter.cairo_set_source_color(cr, borderColor);
|
||||
cr.setLineWidth(borderWidth);
|
||||
cr.stroke();
|
||||
},
|
||||
|
||||
// @origin: Coordinate specifying middle of the arrow, along
|
||||
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
|
||||
// the left for St.Side.TOP and St.Side.BOTTOM.
|
||||
setArrowOrigin: function(origin) {
|
||||
if (this._arrowOrigin != origin) {
|
||||
this._arrowOrigin = origin;
|
||||
this._border.queue_repaint();
|
||||
}
|
||||
}
|
||||
};
|
@ -24,27 +24,27 @@ Calendar.prototype = {
|
||||
// GTK+ by preference uses nl_langinfo (NL_TIME_FIRST_WEEKDAY). We probably
|
||||
// should add a C function so we can do the full handling.
|
||||
this._weekStart = NaN;
|
||||
let weekStartString = Gettext_gtk20.gettext("calendar:week_start:0");
|
||||
if (weekStartString.indexOf("calendar:week_start:") == 0) {
|
||||
let weekStartString = Gettext_gtk20.gettext('calendar:week_start:0');
|
||||
if (weekStartString.indexOf('calendar:week_start:') == 0) {
|
||||
this._weekStart = parseInt(weekStartString.substring(20));
|
||||
}
|
||||
|
||||
if (isNaN(this._weekStart) || this._weekStart < 0 || this._weekStart > 6) {
|
||||
log("Translation of 'calendar:week_start:0' in GTK+ is not correct");
|
||||
log('Translation of "calendar:week_start:0" in GTK+ is not correct');
|
||||
this._weekStart = 0;
|
||||
}
|
||||
|
||||
// Find the ordering for month/year in the calendar heading
|
||||
switch (Gettext_gtk20.gettext("calendar:MY")) {
|
||||
case "calendar:MY":
|
||||
this._headerFormat = "%B %Y";
|
||||
switch (Gettext_gtk20.gettext('calendar:MY')) {
|
||||
case 'calendar:MY':
|
||||
this._headerFormat = '%B %Y';
|
||||
break;
|
||||
case "calendar:YM":
|
||||
this._headerFormat = "%Y %B";
|
||||
case 'calendar:YM':
|
||||
this._headerFormat = '%Y %B';
|
||||
break;
|
||||
default:
|
||||
log("Translation of 'calendar:MY' in GTK+ is not correct");
|
||||
this._headerFormat = "%B %Y";
|
||||
log('Translation of "calendar:MY" in GTK+ is not correct');
|
||||
this._headerFormat = '%B %Y';
|
||||
break;
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ Calendar.prototype = {
|
||||
this.date = new Date();
|
||||
|
||||
this.actor = new St.Table({ homogeneous: false,
|
||||
style_class: "calendar",
|
||||
style_class: 'calendar',
|
||||
reactive: true });
|
||||
|
||||
this.actor.connect('scroll-event',
|
||||
@ -63,21 +63,21 @@ Calendar.prototype = {
|
||||
this.actor.add(this._topBox,
|
||||
{ row: 0, col: 0, col_span: 7 });
|
||||
|
||||
let [backlabel, forwardlabel] = ["<", ">"];
|
||||
let [backlabel, forwardlabel] = ['<', '>'];
|
||||
if (St.Widget.get_default_direction () == St.TextDirection.RTL) {
|
||||
[backlabel, forwardlabel] = [forwardlabel, backlabel];
|
||||
}
|
||||
|
||||
let back = new St.Button({ label: backlabel, style_class: 'calendar-change-month' });
|
||||
this._topBox.add(back);
|
||||
back.connect("clicked", Lang.bind(this, this._prevMonth));
|
||||
back.connect('clicked', Lang.bind(this, this._prevMonth));
|
||||
|
||||
this._dateLabel = new St.Label();
|
||||
this._topBox.add(this._dateLabel, { expand: true, x_fill: false, x_align: St.Align.MIDDLE });
|
||||
|
||||
let forward = new St.Button({ label: forwardlabel, style_class: 'calendar-change-month' });
|
||||
this._topBox.add(forward);
|
||||
forward.connect("clicked", Lang.bind(this, this._nextMonth));
|
||||
forward.connect('clicked', Lang.bind(this, this._nextMonth));
|
||||
|
||||
// We need to figure out the abbreviated localized names for the days of the week;
|
||||
// we do this by just getting the next 7 days starting from right now and then putting
|
||||
@ -86,7 +86,7 @@ Calendar.prototype = {
|
||||
iter.setSeconds(0); // Leap second protection. Hah!
|
||||
iter.setHours(12);
|
||||
for (let i = 0; i < 7; i++) {
|
||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat("%a") }),
|
||||
this.actor.add(new St.Label({ text: iter.toLocaleFormat('%a') }),
|
||||
{ row: 1,
|
||||
col: (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
@ -161,11 +161,11 @@ Calendar.prototype = {
|
||||
while (true) {
|
||||
let label = new St.Label({ text: iter.getDate().toString() });
|
||||
if (_sameDay(now, iter))
|
||||
label.style_class = "calendar-day calendar-today";
|
||||
label.style_class = 'calendar-day calendar-today';
|
||||
else if (iter.getMonth() != this.date.getMonth())
|
||||
label.style_class = "calendar-day calendar-other-month-day";
|
||||
label.style_class = 'calendar-day calendar-other-month-day';
|
||||
else
|
||||
label.style_class = "calendar-day";
|
||||
label.style_class = 'calendar-day';
|
||||
this.actor.add(label,
|
||||
{ row: row, col: (7 + iter.getDay() - this._weekStart) % 7,
|
||||
x_fill: false, x_align: St.Align.END });
|
||||
|
163
js/ui/chrome.js
163
js/ui/chrome.js
@ -5,6 +5,7 @@ const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Params = imports.misc.params;
|
||||
@ -13,6 +14,19 @@ const Params = imports.misc.params;
|
||||
// normal mode (ie, outside the Overview), that surrounds the main
|
||||
// workspace content.
|
||||
|
||||
const Visibility = {
|
||||
FULL: 1,
|
||||
FULLSCREEN: 2,
|
||||
OVERVIEW: 3
|
||||
};
|
||||
|
||||
const defaultParams = {
|
||||
visibleInOverview: false,
|
||||
visibleInFullscreen: false,
|
||||
affectsStruts: true,
|
||||
affectsInputRegion: true
|
||||
};
|
||||
|
||||
function Chrome() {
|
||||
this._init();
|
||||
}
|
||||
@ -20,12 +34,13 @@ function Chrome() {
|
||||
Chrome.prototype = {
|
||||
_init: function() {
|
||||
// The group itself has zero size so it doesn't interfere with DND
|
||||
this.actor = new Clutter.Group({ width: 0, height: 0 });
|
||||
global.stage.add_actor(this.actor);
|
||||
this.nonOverviewActor = new Clutter.Group();
|
||||
this.actor.add_actor(this.nonOverviewActor);
|
||||
this.actor = new Shell.GenericContainer({ width: 0, height: 0 });
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
this.actor.connect('allocate', Lang.bind(this, this._allocated));
|
||||
|
||||
this._obscuredByFullscreen = false;
|
||||
this._inFullscreen = false;
|
||||
this._inOverview = false;
|
||||
this.visibility = Visibility.FULL;
|
||||
|
||||
this._trackedActors = [];
|
||||
|
||||
@ -44,6 +59,12 @@ Chrome.prototype = {
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_allocated: function(actor, box, flags) {
|
||||
let children = this.actor.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].allocate_preferred_size(flags);
|
||||
},
|
||||
|
||||
_verifyAncestry: function(actor, ancestor) {
|
||||
while (actor) {
|
||||
if (actor == ancestor)
|
||||
@ -67,19 +88,15 @@ Chrome.prototype = {
|
||||
//
|
||||
// If %visibleInOverview is %true in @params, @actor will remain
|
||||
// visible when the overview is brought up. Otherwise it will
|
||||
// automatically be hidden. If %affectsStruts or %affectsInputRegion
|
||||
// is %false, the actor will not have the indicated effect.
|
||||
// automatically be hidden. Likewise, if %visibleInFullscreen is
|
||||
// %true, the actor will be visible even when a fullscreen window
|
||||
// should be covering it.
|
||||
//
|
||||
// If %affectsStruts or %affectsInputRegion is %false, the actor
|
||||
// will not have the indicated effect.
|
||||
addActor: function(actor, params) {
|
||||
params = Params.parse(params, { visibleInOverview: false,
|
||||
affectsStruts: true,
|
||||
affectsInputRegion: true });
|
||||
|
||||
if (params.visibleInOverview)
|
||||
this.actor.add_actor(actor);
|
||||
else
|
||||
this.nonOverviewActor.add_actor(actor);
|
||||
|
||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
||||
this.actor.add_actor(actor);
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
// trackActor:
|
||||
@ -89,13 +106,32 @@ Chrome.prototype = {
|
||||
// Tells the chrome to track @actor, which must be a descendant
|
||||
// of an actor added via addActor(). This can be used to extend the
|
||||
// struts or input region to cover specific children.
|
||||
//
|
||||
// @params can have any of the same values as in addActor(), though
|
||||
// some possibilities don't make sense (eg, trying to have a
|
||||
// %visibleInOverview child of a non-%visibleInOverview parent).
|
||||
// By default, @actor has the same params as its chrome ancestor.
|
||||
trackActor: function(actor, params) {
|
||||
if (!this._verifyAncestry(actor, this.actor))
|
||||
let ancestor = actor.get_parent();
|
||||
let index = this._findActor(ancestor);
|
||||
while (ancestor && index == -1) {
|
||||
ancestor = ancestor.get_parent();
|
||||
index = this._findActor(ancestor);
|
||||
}
|
||||
if (!ancestor)
|
||||
throw new Error('actor is not a descendent of the chrome layer');
|
||||
|
||||
params = Params.parse(params, { affectsStruts: true,
|
||||
affectsInputRegion: true });
|
||||
this._trackActor(actor, params.affectsInputRegion, params.affectsStruts);
|
||||
let ancestorData = this._trackedActors[index];
|
||||
if (!params)
|
||||
params = {};
|
||||
// We can't use Params.parse here because we want to drop
|
||||
// the extra values like ancestorData.actor
|
||||
for (let prop in defaultParams) {
|
||||
if (!params[prop])
|
||||
params[prop] = ancestorData[prop];
|
||||
}
|
||||
|
||||
this._trackActor(actor, params);
|
||||
},
|
||||
|
||||
// untrackActor:
|
||||
@ -111,10 +147,7 @@ Chrome.prototype = {
|
||||
//
|
||||
// Removes @actor from the chrome layer
|
||||
removeActor: function(actor) {
|
||||
if (actor.get_parent() == this.nonOverviewActor)
|
||||
this.nonOverviewActor.remove_actor(actor);
|
||||
else
|
||||
this.actor.remove_actor(actor);
|
||||
this.actor.remove_actor(actor);
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
@ -127,16 +160,12 @@ Chrome.prototype = {
|
||||
return -1;
|
||||
},
|
||||
|
||||
_trackActor: function(actor, inputRegion, strut) {
|
||||
let actorData;
|
||||
|
||||
_trackActor: function(actor, params) {
|
||||
if (this._findActor(actor) != -1)
|
||||
throw new Error('trying to re-track existing chrome actor');
|
||||
|
||||
actorData = { actor: actor,
|
||||
inputRegion: inputRegion,
|
||||
strut: strut };
|
||||
|
||||
let actorData = Params.parse(params, defaultParams);
|
||||
actorData.actor = actor;
|
||||
actorData.visibleId = actor.connect('notify::visible',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
actorData.allocationId = actor.connect('notify::allocation',
|
||||
@ -170,16 +199,40 @@ Chrome.prototype = {
|
||||
this._untrackActor(actor);
|
||||
},
|
||||
|
||||
_updateVisibility: function() {
|
||||
for (let i = 0; i < this._trackedActors.length; i++) {
|
||||
let actorData = this._trackedActors[i];
|
||||
if (this._inOverview && !actorData.visibleInOverview)
|
||||
this.actor.set_skip_paint(actorData.actor, true);
|
||||
else if (this._inFullscreen && !actorData.visibleInFullscreen)
|
||||
this.actor.set_skip_paint(actorData.actor, true);
|
||||
else
|
||||
this.actor.set_skip_paint(actorData.actor, false);
|
||||
}
|
||||
|
||||
let newVisibility;
|
||||
if (this._inOverview)
|
||||
newVisibility = Visibility.OVERVIEW;
|
||||
else if (this._inFullscreen)
|
||||
newVisibility = Visibility.FULLSCREEN;
|
||||
else
|
||||
newVisibility = Visibility.FULL;
|
||||
|
||||
if (newVisibility != this.visibility) {
|
||||
this.visibility = newVisibility;
|
||||
this.emit('visibility-changed', this.visibility);
|
||||
}
|
||||
},
|
||||
|
||||
_overviewShowing: function() {
|
||||
this.actor.show();
|
||||
this.nonOverviewActor.hide();
|
||||
this._inOverview = true;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_overviewHidden: function() {
|
||||
if (this._obscuredByFullscreen)
|
||||
this.actor.hide();
|
||||
this.nonOverviewActor.show();
|
||||
this._inOverview = false;
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
@ -196,7 +249,7 @@ Chrome.prototype = {
|
||||
// The chrome layer should be visible unless there is a window
|
||||
// with layer FULLSCREEN, or a window with layer
|
||||
// OVERRIDE_REDIRECT that covers the whole screen.
|
||||
// ("override_redirect" is not actually a layer above all
|
||||
// ('override_redirect' is not actually a layer above all
|
||||
// other windows, but this seems to be how mutter treats it
|
||||
// currently...) If we wanted to be extra clever, we could
|
||||
// figure out when an OVERRIDE_REDIRECT window was trying to
|
||||
@ -205,13 +258,23 @@ Chrome.prototype = {
|
||||
|
||||
// @windows is sorted bottom to top.
|
||||
|
||||
this._obscuredByFullscreen = false;
|
||||
let wasInFullscreen = this._inFullscreen;
|
||||
this._inFullscreen = false;
|
||||
for (let i = windows.length - 1; i > -1; i--) {
|
||||
let layer = windows[i].get_meta_window().get_layer();
|
||||
|
||||
// There are 3 cases we check here for:
|
||||
// 1.) Monitor sized window
|
||||
// 2.) Window with a position somewhere on the primary screen having the _NET_WM_FULLSCREEN flag set
|
||||
// 3.) Window that is partly off screen (tries to hide its decorations) which might have negative coords
|
||||
// We check for 1.) and 2.) by checking if the upper right corner is on the primary monitor, but avoid the case
|
||||
// where it overlaps with the secondary screen (like window.x + window.width == primary.x + primary.width)
|
||||
// For 3.) we just ignore negative values as they don't really make sense
|
||||
|
||||
if (layer == Meta.StackLayer.FULLSCREEN) {
|
||||
if (windows[i].x >= primary.x && windows[i].x <= primary.x + primary.width &&
|
||||
windows[i].y >= primary.y && windows[i].y <= primary.y + primary.height) {
|
||||
this._obscuredByFullscreen = true;
|
||||
if (Math.max(windows[i].x, 0) >= primary.x && Math.max(windows[i].x, 0) < primary.x + primary.width &&
|
||||
Math.max(windows[i].y, 0) >= primary.y && Math.max(windows[i].y, 0) < primary.y + primary.height) {
|
||||
this._inFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -220,16 +283,15 @@ Chrome.prototype = {
|
||||
windows[i].x + windows[i].width >= primary.x + primary.width &&
|
||||
windows[i].y <= primary.y &&
|
||||
windows[i].y + windows[i].height >= primary.y + primary.height) {
|
||||
this._obscuredByFullscreen = true;
|
||||
this._inFullscreen = true;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
let shouldBeVisible = !this._obscuredByFullscreen || Main.overview.visible;
|
||||
if (this.actor.visible != shouldBeVisible) {
|
||||
this.actor.visible = shouldBeVisible;
|
||||
if (this._inFullscreen != wasInFullscreen) {
|
||||
this._updateVisibility();
|
||||
this._queueUpdateRegions();
|
||||
}
|
||||
},
|
||||
@ -241,7 +303,7 @@ Chrome.prototype = {
|
||||
|
||||
for (i = 0; i < this._trackedActors.length; i++) {
|
||||
let actorData = this._trackedActors[i];
|
||||
if (!actorData.inputRegion && !actorData.strut)
|
||||
if (!actorData.affectsInputRegion && !actorData.affectsStruts)
|
||||
continue;
|
||||
|
||||
let [x, y] = actorData.actor.get_transformed_position();
|
||||
@ -252,10 +314,12 @@ Chrome.prototype = {
|
||||
h = Math.round(h);
|
||||
let rect = new Meta.Rectangle({ x: x, y: y, width: w, height: h});
|
||||
|
||||
if (actorData.inputRegion && actorData.actor.get_paint_visibility())
|
||||
if (actorData.affectsInputRegion &&
|
||||
actorData.actor.get_paint_visibility() &&
|
||||
!this.actor.get_skip_paint(actorData.actor))
|
||||
rects.push(rect);
|
||||
|
||||
if (!actorData.strut)
|
||||
if (!actorData.affectsStruts)
|
||||
continue;
|
||||
|
||||
// Metacity wants to know what side of the screen the
|
||||
@ -307,3 +371,4 @@ Chrome.prototype = {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Chrome.prototype);
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Mainloop = imports.mainloop;
|
||||
@ -23,10 +22,8 @@ const Search = imports.ui.search;
|
||||
// 25 search results (per result type) should be enough for everyone
|
||||
const MAX_RENDERED_SEARCH_RESULTS = 25;
|
||||
|
||||
const DEFAULT_PADDING = 4;
|
||||
|
||||
const DOCS = "docs";
|
||||
const PLACES = "places";
|
||||
const DOCS = 'docs';
|
||||
const PLACES = 'places';
|
||||
|
||||
/*
|
||||
* Returns the index in an array of a given length that is obtained
|
||||
@ -57,7 +54,7 @@ Pane.prototype = {
|
||||
_init: function () {
|
||||
this._open = false;
|
||||
|
||||
this.actor = new St.BoxLayout({ style_class: "dash-pane",
|
||||
this.actor = new St.BoxLayout({ style_class: 'dash-pane',
|
||||
vertical: true,
|
||||
reactive: true });
|
||||
this.actor.connect('button-press-event', Lang.bind(this, function (a, e) {
|
||||
@ -116,14 +113,12 @@ function ResultArea(displayType, flags) {
|
||||
|
||||
ResultArea.prototype = {
|
||||
_init : function(displayType, flags) {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.resultsContainer = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_PADDING
|
||||
});
|
||||
this.actor.append(this.resultsContainer, Big.BoxPackFlags.EXPAND);
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
this.resultsContainer = new St.BoxLayout({ style_class: 'dash-results-container' });
|
||||
this.actor.add(this.resultsContainer, { expand: true });
|
||||
|
||||
this.display = _createDisplay(displayType, flags);
|
||||
this.resultsContainer.append(this.display.actor, Big.BoxPackFlags.EXPAND);
|
||||
this.resultsContainer.add(this.display.actor, { expand: true });
|
||||
this.display.load();
|
||||
}
|
||||
};
|
||||
@ -190,7 +185,7 @@ function SearchEntry() {
|
||||
|
||||
SearchEntry.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new St.Entry({ name: "searchEntry",
|
||||
this.actor = new St.Entry({ name: 'searchEntry',
|
||||
hint_text: _("Find") });
|
||||
this.entry = this.actor.clutter_text;
|
||||
|
||||
@ -198,7 +193,7 @@ SearchEntry.prototype = {
|
||||
function() {
|
||||
if (this.isActive())
|
||||
this.actor.set_secondary_icon_from_file(global.imagedir +
|
||||
"close-black.svg");
|
||||
'close-black.svg');
|
||||
else
|
||||
this.actor.set_secondary_icon_from_file(null);
|
||||
}));
|
||||
@ -359,7 +354,10 @@ SearchResult.prototype = {
|
||||
},
|
||||
|
||||
setSelected: function(selected) {
|
||||
this._content.set_style_pseudo_class(selected ? 'selected' : null);
|
||||
if (selected)
|
||||
this._content.add_style_pseudo_class('selected');
|
||||
else
|
||||
this._content.remove_style_pseudo_class('selected');
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
@ -532,7 +530,7 @@ SearchResults.prototype = {
|
||||
let meta = this._metaForProvider(provider);
|
||||
meta.actor.show();
|
||||
meta.resultDisplay.renderResults(providerResults, terms);
|
||||
meta.count.set_text(""+providerResults.length);
|
||||
meta.count.set_text('' + providerResults.length);
|
||||
}
|
||||
|
||||
this.selectDown(false);
|
||||
@ -610,11 +608,11 @@ function MoreLink() {
|
||||
|
||||
MoreLink.prototype = {
|
||||
_init : function () {
|
||||
this.actor = new St.BoxLayout({ style_class: "more-link",
|
||||
this.actor = new St.BoxLayout({ style_class: 'more-link',
|
||||
reactive: true });
|
||||
this.pane = null;
|
||||
|
||||
this._expander = new St.Bin({ style_class: "more-link-expander" });
|
||||
this._expander = new St.Bin({ style_class: 'more-link-expander' });
|
||||
this.actor.add(this._expander, { expand: true, y_fill: false });
|
||||
},
|
||||
|
||||
@ -630,10 +628,10 @@ MoreLink.prototype = {
|
||||
setPane: function (pane) {
|
||||
this._pane = pane;
|
||||
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||
if (!isOpen)
|
||||
this._expander.style_class = 'more-link-expander';
|
||||
if (isOpen)
|
||||
this._expander.add_style_class_name('open');
|
||||
else
|
||||
this._expander.style_class = 'more-link-expander open';
|
||||
this._expander.remove_style_class_name('open');
|
||||
}));
|
||||
}
|
||||
};
|
||||
@ -646,9 +644,9 @@ function BackLink() {
|
||||
|
||||
BackLink.prototype = {
|
||||
_init : function () {
|
||||
this.actor = new St.Button({ style_class: "section-header-back",
|
||||
this.actor = new St.Button({ style_class: 'section-header-back',
|
||||
reactive: true });
|
||||
this.actor.set_child(new St.Bin({ style_class: "section-header-back-image" }));
|
||||
this.actor.set_child(new St.Bin({ style_class: 'section-header-back-image' }));
|
||||
}
|
||||
};
|
||||
|
||||
@ -658,12 +656,12 @@ function SectionHeader(title, suppressBrowse) {
|
||||
|
||||
SectionHeader.prototype = {
|
||||
_init : function (title, suppressBrowse) {
|
||||
this.actor = new St.Bin({ style_class: "section-header",
|
||||
this.actor = new St.Bin({ style_class: 'section-header',
|
||||
x_align: St.Align.START,
|
||||
x_fill: true,
|
||||
y_fill: true,
|
||||
reactive: !suppressBrowse });
|
||||
this._innerBox = new St.BoxLayout({ style_class: "section-header-inner" });
|
||||
this._innerBox = new St.BoxLayout({ style_class: 'section-header-inner' });
|
||||
this.actor.set_child(this._innerBox);
|
||||
|
||||
this.backLink = new BackLink();
|
||||
@ -673,12 +671,12 @@ SectionHeader.prototype = {
|
||||
this.emit('back-link-activated');
|
||||
}));
|
||||
|
||||
let textBox = new St.BoxLayout({ style_class: "section-text-content" });
|
||||
this.text = new St.Label({ style_class: "section-title",
|
||||
let textBox = new St.BoxLayout({ style_class: 'section-text-content' });
|
||||
this.text = new St.Label({ style_class: 'section-title',
|
||||
text: title });
|
||||
textBox.add(this.text, { x_align: St.Align.START });
|
||||
|
||||
this.countText = new St.Label({ style_class: "section-count" });
|
||||
this.countText = new St.Label({ style_class: 'section-count' });
|
||||
textBox.add(this.countText, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||
this.countText.hide();
|
||||
|
||||
@ -714,7 +712,7 @@ SectionHeader.prototype = {
|
||||
},
|
||||
|
||||
setCountText : function(countText) {
|
||||
if (countText == "") {
|
||||
if (countText == '') {
|
||||
this.countText.hide();
|
||||
} else {
|
||||
this.countText.show();
|
||||
@ -731,14 +729,14 @@ function SearchSectionHeader(title, onClick) {
|
||||
|
||||
SearchSectionHeader.prototype = {
|
||||
_init : function(title, onClick) {
|
||||
this.actor = new St.Button({ style_class: "dash-search-section-header",
|
||||
this.actor = new St.Button({ style_class: 'dash-search-section-header',
|
||||
x_fill: true,
|
||||
y_fill: true });
|
||||
let box = new St.BoxLayout();
|
||||
this.actor.set_child(box);
|
||||
let titleText = new St.Label({ style_class: "dash-search-section-title",
|
||||
let titleText = new St.Label({ style_class: 'dash-search-section-title',
|
||||
text: title });
|
||||
this.countText = new St.Label({ style_class: "dash-search-section-count" });
|
||||
this.countText = new St.Label({ style_class: 'dash-search-section-count' });
|
||||
|
||||
box.add(titleText);
|
||||
box.add(this.countText, { expand: true, x_fill: false, x_align: St.Align.END });
|
||||
@ -778,14 +776,14 @@ Dash.prototype = {
|
||||
// of the Group actor ends up including the width of its hidden children, so we were getting a reactive object as
|
||||
// wide as the details pane that was blocking the clicks to the workspaces underneath it even when the details pane
|
||||
// was actually hidden.
|
||||
this.actor = new St.BoxLayout({ name: "dash",
|
||||
this.actor = new St.BoxLayout({ name: 'dash',
|
||||
vertical: true,
|
||||
reactive: true });
|
||||
|
||||
// The searchArea just holds the entry
|
||||
this.searchArea = new St.BoxLayout({ name: "dashSearchArea",
|
||||
this.searchArea = new St.BoxLayout({ name: 'dashSearchArea',
|
||||
vertical: true });
|
||||
this.sectionArea = new St.BoxLayout({ name: "dashSections",
|
||||
this.sectionArea = new St.BoxLayout({ name: 'dashSections',
|
||||
vertical: true });
|
||||
|
||||
this.actor.add(this.searchArea);
|
||||
|
32
js/ui/dnd.js
32
js/ui/dnd.js
@ -1,10 +1,12 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil -*- */
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const St = imports.gi.St;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const Params = imports.misc.params;
|
||||
|
||||
@ -21,7 +23,7 @@ function _getEventHandlerActor() {
|
||||
eventHandlerActor = new Clutter.Rectangle();
|
||||
eventHandlerActor.width = 0;
|
||||
eventHandlerActor.height = 0;
|
||||
global.stage.add_actor(eventHandlerActor);
|
||||
Main.uiGroup.add_actor(eventHandlerActor);
|
||||
// We connect to 'event' rather than 'captured-event' because the capturing phase doesn't happen
|
||||
// when you've grabbed the pointer.
|
||||
eventHandlerActor.connect('event',
|
||||
@ -61,13 +63,20 @@ _Draggable.prototype = {
|
||||
},
|
||||
|
||||
_onButtonPress : function (actor, event) {
|
||||
// FIXME: we should make sure it's button 1, but we can't currently
|
||||
// check that from JavaScript
|
||||
if (event.get_button() != 1)
|
||||
return false;
|
||||
|
||||
if (Tweener.getTweenCount(actor))
|
||||
return false;
|
||||
|
||||
this._buttonDown = true;
|
||||
this._grabActor();
|
||||
// special case St.Clickable: grabbing the pointer would mess up the
|
||||
// internal state, so we start the drag manually on hover change
|
||||
if (this.actor instanceof St.Clickable)
|
||||
this.actor.connect('notify::hover',
|
||||
Lang.bind(this, this._onClickableHoverChanged));
|
||||
else
|
||||
this._grabActor();
|
||||
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._dragStartX = stageX;
|
||||
@ -76,6 +85,15 @@ _Draggable.prototype = {
|
||||
return false;
|
||||
},
|
||||
|
||||
_onClickableHoverChanged: function(button) {
|
||||
if (button.hover || !button.held)
|
||||
return;
|
||||
|
||||
button.fake_release();
|
||||
this.startDrag(this._dragStartX, this._dragStartY,
|
||||
global.get_current_time());
|
||||
},
|
||||
|
||||
_grabActor: function() {
|
||||
Clutter.grab_pointer(this.actor);
|
||||
this._onEventId = this.actor.connect('event',
|
||||
@ -236,7 +254,7 @@ _Draggable.prototype = {
|
||||
{ scale_x: scale * origScale,
|
||||
scale_y: scale * origScale,
|
||||
time: SCALE_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onUpdate: function() {
|
||||
let currentScale = this._dragActor.scale_x / origScale;
|
||||
this._dragOffsetX = currentScale * origDragOffsetX;
|
||||
@ -350,7 +368,7 @@ _Draggable.prototype = {
|
||||
scale_y: this._snapBackScale,
|
||||
opacity: this._dragOrigOpacity,
|
||||
time: SNAP_BACK_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._onSnapBackComplete,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [this._dragActor, eventTime]
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
@ -42,7 +41,7 @@ DocDisplayItem.prototype = {
|
||||
GenericDisplay.GenericDisplayItem.prototype._init.call(this);
|
||||
this._docInfo = docInfo;
|
||||
|
||||
this._setItemInfo(docInfo.name, "");
|
||||
this._setItemInfo(docInfo.name, '');
|
||||
|
||||
this._timeoutTime = -1;
|
||||
this._resetTimeDisplay(currentSecs);
|
||||
@ -81,7 +80,7 @@ DocDisplayItem.prototype = {
|
||||
// Creates and returns a large preview icon, but only if this._docInfo is an image file
|
||||
// and we were able to generate a pixbuf from it successfully.
|
||||
_createLargePreviewIcon : function() {
|
||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
|
||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf('image/') != 0)
|
||||
return null;
|
||||
|
||||
try {
|
||||
@ -267,24 +266,26 @@ function DashDocDisplayItem(docInfo) {
|
||||
DashDocDisplayItem.prototype = {
|
||||
_init: function(docInfo) {
|
||||
this._info = docInfo;
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_SPACING,
|
||||
reactive: true });
|
||||
this.actor.connect('button-release-event', Lang.bind(this, function () {
|
||||
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
||||
|
||||
this.actor = new St.Clickable({ style_class: 'recent-docs-item',
|
||||
reactive: true,
|
||||
x_align: St.Align.START });
|
||||
|
||||
let box = new St.BoxLayout({ style_class: 'recent-docs-item-box' });
|
||||
this.actor.set_child(box);
|
||||
|
||||
box.add(this._icon);
|
||||
|
||||
let text = new St.Label({ text: docInfo.name });
|
||||
box.add(text);
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, function () {
|
||||
docInfo.launch();
|
||||
Main.overview.hide();
|
||||
}));
|
||||
|
||||
this.actor._delegate = this;
|
||||
|
||||
this._icon = docInfo.createIcon(DASH_DOCS_ICON_SIZE);
|
||||
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
let name = new St.Label({ style_class: 'dash-recent-docs-item',
|
||||
text: docInfo.name });
|
||||
this.actor.append(name, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
},
|
||||
|
||||
@ -512,6 +513,6 @@ DocSearchProvider.prototype = {
|
||||
},
|
||||
|
||||
expandSearch: function(terms) {
|
||||
log("TODO expand docs search");
|
||||
log('TODO expand docs search');
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Gettext_gtk20 = imports.gettext.domain('gtk20');
|
||||
|
||||
@ -28,15 +29,57 @@ function _patchContainerClass(containerClass) {
|
||||
};
|
||||
}
|
||||
|
||||
_patchContainerClass(St.BoxLayout);
|
||||
_patchContainerClass(St.Table);
|
||||
// Replace @method with something that throws an error instead
|
||||
function _blockMethod(method, replacement, reason) {
|
||||
let match = method.match(/^(.+)\.([^.]+)$/);
|
||||
if (!match)
|
||||
throw new Error('Bad method name "' + method + '"');
|
||||
let proto = 'imports.gi.' + match[1] + '.prototype';
|
||||
let property = match[2];
|
||||
|
||||
if (!global.set_property_mutable(proto, property, true))
|
||||
throw new Error('Bad method name "' + method + '"');
|
||||
|
||||
// eval() is evil in general, but we know it's safe here since
|
||||
// set_property_mutable() would have failed if proto was
|
||||
// malformed.
|
||||
let node = eval(proto);
|
||||
|
||||
let msg = 'Do not use "' + method + '".';
|
||||
if (replacement)
|
||||
msg += ' Use "' + replacement + '" instead.';
|
||||
if (reason)
|
||||
msg += ' (' + reason + ')';
|
||||
|
||||
node[property] = function() {
|
||||
throw new Error(msg);
|
||||
};
|
||||
|
||||
global.set_property_mutable(proto, property, false);
|
||||
}
|
||||
|
||||
function init() {
|
||||
Tweener.init();
|
||||
String.prototype.format = Format.format;
|
||||
|
||||
// Set the default direction for St widgets (this needs to be done before any use of St)
|
||||
if (Gettext_gtk20.gettext("default:LTR") == "default:RTL") {
|
||||
if (Gettext_gtk20.gettext('default:LTR') == 'default:RTL') {
|
||||
St.Widget.set_default_direction(St.TextDirection.RTL);
|
||||
}
|
||||
|
||||
_patchContainerClass(St.BoxLayout);
|
||||
_patchContainerClass(St.Table);
|
||||
|
||||
_blockMethod('Clutter.Event.get_state', 'Shell.get_event_state',
|
||||
'gjs\'s handling of Clutter.ModifierType is broken. See bug 597292.');
|
||||
_blockMethod('Gdk.Display.get_pointer', 'global.get_pointer',
|
||||
'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
|
||||
_blockMethod('Gdk.Window.get_pointer', 'global.get_pointer',
|
||||
'gjs\'s handling of Gdk.ModifierType is broken. See bug 597292.');
|
||||
|
||||
// Now close the back door to prevent extensions from trying to
|
||||
// abuse it. We can't actually delete it since
|
||||
// Shell.Global.prototype itself is read-only.
|
||||
global.set_property_mutable('imports.gi.Shell.Global.prototype', 'set_property_mutable', true);
|
||||
Shell.Global.prototype.set_property_mutable = undefined;
|
||||
}
|
||||
|
@ -119,13 +119,12 @@ function loadExtension(dir, enabled, type) {
|
||||
}
|
||||
|
||||
function init() {
|
||||
let userConfigPath = GLib.get_user_config_dir();
|
||||
let userExtensionsPath = GLib.build_filenamev([userConfigPath, 'gnome-shell', 'extensions']);
|
||||
let userExtensionsPath = GLib.build_filenamev([global.userdatadir, 'extensions']);
|
||||
userExtensionsDir = Gio.file_new_for_path(userExtensionsPath);
|
||||
try {
|
||||
userExtensionsDir.make_directory_with_parents(null);
|
||||
} catch (e) {
|
||||
global.logError(""+e);
|
||||
global.logError('' + e);
|
||||
}
|
||||
|
||||
disabledExtensions = Shell.GConf.get_default().get_string_list('disabled_extensions');
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
@ -21,25 +20,9 @@ const RedisplayFlags = { NONE: 0,
|
||||
SUBSEARCH: 1 << 2,
|
||||
IMMEDIATE: 1 << 3 };
|
||||
|
||||
const ITEM_DISPLAY_DESCRIPTION_COLOR = new Clutter.Color();
|
||||
ITEM_DISPLAY_DESCRIPTION_COLOR.from_pixel(0xffffffbb);
|
||||
const DISPLAY_CONTROL_SELECTED_COLOR = new Clutter.Color();
|
||||
DISPLAY_CONTROL_SELECTED_COLOR.from_pixel(0x112288ff);
|
||||
const PREVIEW_BOX_BACKGROUND_COLOR = new Clutter.Color();
|
||||
PREVIEW_BOX_BACKGROUND_COLOR.from_pixel(0xADADADf0);
|
||||
|
||||
const DEFAULT_PADDING = 4;
|
||||
|
||||
// Used by subclasses
|
||||
const ITEM_DISPLAY_ICON_SIZE = 48;
|
||||
const DEFAULT_COLUMN_GAP = 6;
|
||||
|
||||
const PREVIEW_ICON_SIZE = 96;
|
||||
const PREVIEW_BOX_PADDING = 6;
|
||||
const PREVIEW_BOX_SPACING = DEFAULT_PADDING;
|
||||
const PREVIEW_BOX_CORNER_RADIUS = 10;
|
||||
// how far relative to the full item width the preview box should be placed
|
||||
const PREVIEW_PLACING = 3/4;
|
||||
const PREVIEW_DETAILS_MIN_WIDTH = PREVIEW_ICON_SIZE * 2;
|
||||
|
||||
/* This is a virtual class that represents a single display item containing
|
||||
* a name, a description, and an icon. It allows selecting an item and represents
|
||||
@ -51,7 +34,7 @@ function GenericDisplayItem() {
|
||||
|
||||
GenericDisplayItem.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ style_class: "generic-display-item",
|
||||
this.actor = new St.BoxLayout({ style_class: 'generic-display-item',
|
||||
reactive: true });
|
||||
|
||||
this.actor._delegate = this;
|
||||
@ -105,7 +88,10 @@ GenericDisplayItem.prototype = {
|
||||
// Highlights the item by setting a different background color than the default
|
||||
// if isSelected is true, removes the highlighting otherwise.
|
||||
markSelected: function(isSelected) {
|
||||
this.actor.set_style_pseudo_class(isSelected ? "selected" : null);
|
||||
if (isSelected)
|
||||
this.actor.add_style_pseudo_class('selected');
|
||||
else
|
||||
this.actor.remove_style_pseudo_class('selected');
|
||||
},
|
||||
|
||||
/*
|
||||
@ -114,11 +100,10 @@ GenericDisplayItem.prototype = {
|
||||
*/
|
||||
createDetailsActor: function() {
|
||||
|
||||
let details = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
let details = new St.BoxLayout({ style_class: 'generic-display-container',
|
||||
vertical: true });
|
||||
|
||||
let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
let mainDetails = new St.BoxLayout({ style_class: 'generic-display-container' });
|
||||
|
||||
// Inner box with name and description
|
||||
let textDetails = new St.BoxLayout({ style_class: 'generic-display-details',
|
||||
@ -132,21 +117,19 @@ GenericDisplayItem.prototype = {
|
||||
|
||||
this._detailsDescriptions.push(detailsDescription);
|
||||
|
||||
mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
|
||||
mainDetails.add(textDetails, { expand: true });
|
||||
|
||||
let previewIcon = this._createPreviewIcon();
|
||||
let largePreviewIcon = this._createLargePreviewIcon();
|
||||
|
||||
if (previewIcon != null && largePreviewIcon == null) {
|
||||
mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE);
|
||||
mainDetails.insert_actor(previewIcon, 0);
|
||||
}
|
||||
|
||||
details.append(mainDetails, Big.BoxPackFlags.NONE);
|
||||
details.add(mainDetails);
|
||||
|
||||
if (largePreviewIcon != null) {
|
||||
let largePreview = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
largePreview.append(largePreviewIcon, Big.BoxPackFlags.NONE);
|
||||
details.append(largePreview, Big.BoxPackFlags.NONE);
|
||||
details.add(largePreviewIcon);
|
||||
}
|
||||
|
||||
return details;
|
||||
@ -161,7 +144,7 @@ GenericDisplayItem.prototype = {
|
||||
|
||||
// Performes an action associated with launching this item, such as opening a file or an application.
|
||||
launch: function() {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
//// Protected methods ////
|
||||
@ -193,12 +176,12 @@ GenericDisplayItem.prototype = {
|
||||
this._icon = this._createIcon();
|
||||
this._iconBin.set_child(this._icon);
|
||||
|
||||
this._name = new St.Label({ style_class: "generic-display-item-name",
|
||||
this._name = new St.Label({ style_class: 'generic-display-item-name',
|
||||
text: nameText });
|
||||
this._infoText.add(this._name);
|
||||
|
||||
this._description = new St.Label({ style_class: "generic-display-item-description",
|
||||
text: descriptionText ? descriptionText : "" });
|
||||
this._description = new St.Label({ style_class: 'generic-display-item-description',
|
||||
text: descriptionText ? descriptionText : '' });
|
||||
this._infoText.add(this._description);
|
||||
},
|
||||
|
||||
@ -225,12 +208,12 @@ GenericDisplayItem.prototype = {
|
||||
|
||||
// Returns an icon for the item.
|
||||
_createIcon: function() {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
// Returns a preview icon for the item.
|
||||
_createPreviewIcon: function() {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
//// Private methods ////
|
||||
@ -373,7 +356,7 @@ GenericDisplay.prototype = {
|
||||
// TODO: figure out why this._list.displayedCount is returning a
|
||||
// positive number when this._mathedItems.length is 0
|
||||
// This can be triggered if a search string is entered for which there are no matches.
|
||||
// log("this._mathedItems.length: " + this._matchedItems.length + " this._list.displayedCount " + this._list.displayedCount);
|
||||
// log('this._mathedItems.length: ' + this._matchedItems.length + ' this._list.displayedCount ' + this._list.displayedCount);
|
||||
return this._matchedItemKeys.length > 0;
|
||||
},
|
||||
|
||||
@ -419,7 +402,7 @@ GenericDisplay.prototype = {
|
||||
// and adds it to the list of displayed items, but does not yet display it.
|
||||
_addDisplayItem : function(itemId) {
|
||||
if (this._displayedItems.hasOwnProperty(itemId)) {
|
||||
log("Tried adding a display item for " + itemId + ", but an item with this item id is already among displayed items.");
|
||||
log('Tried adding a display item for ' + itemId + ', but an item with this item id is already among displayed items.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -478,7 +461,7 @@ GenericDisplay.prototype = {
|
||||
// Return true if there's an active search or other constraint
|
||||
// on the list
|
||||
_filterActive: function() {
|
||||
return this._search != "";
|
||||
return this._search != '';
|
||||
},
|
||||
|
||||
// Called when we are resetting state
|
||||
@ -601,13 +584,13 @@ GenericDisplay.prototype = {
|
||||
// Implementation should return %true if we are up to date, and %false
|
||||
// if a full reload occurred.
|
||||
_refreshCache: function() {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
// Sets the list of the displayed items based on the default sorting order.
|
||||
// The default sorting order is specific to each implementing class.
|
||||
_setDefaultList: function() {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
// Compares items associated with the item ids based on the order in which the
|
||||
@ -615,18 +598,18 @@ GenericDisplay.prototype = {
|
||||
// Intended to be used as a compareFunction for array.sort().
|
||||
// Returns an integer value indicating the result of the comparison.
|
||||
_compareItems: function(itemIdA, itemIdB) {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
// Checks if the item info can be a match for the search string.
|
||||
// Returns a boolean flag indicating if that's the case.
|
||||
_isInfoMatching: function(itemInfo, search) {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
// Creates a display item based on itemInfo.
|
||||
_createDisplayItem: function(itemInfo) {
|
||||
throw new Error("Not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
//// Private methods ////
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const St = imports.gi.St;
|
||||
|
||||
/**
|
||||
@ -60,8 +61,13 @@ Lightbox.prototype = {
|
||||
},
|
||||
|
||||
_allocationChanged : function(container, box, flags) {
|
||||
this.actor.width = this._container.width;
|
||||
this.actor.height = this._container.height;
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
||||
this.actor.width = this.width;
|
||||
this.actor.height = this.height;
|
||||
return false;
|
||||
}));
|
||||
this.width = this._container.width;
|
||||
this.height = this._container.height;
|
||||
},
|
||||
|
||||
_actorAdded : function(container, newChild) {
|
||||
|
@ -12,6 +12,7 @@ function Link(props) {
|
||||
Link.prototype = {
|
||||
_init : function(props) {
|
||||
let realProps = { reactive: true,
|
||||
track_hover: true,
|
||||
style_class: 'shell-link' };
|
||||
// The user can pass in reactive: false to override the above and get
|
||||
// a non-reactive link (a link to the current page, perhaps)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Pango = imports.gi.Pango;
|
||||
const St = imports.gi.St;
|
||||
@ -18,22 +18,22 @@ const Tweener = imports.ui.tweener;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
/* Imports...feel free to add here as needed */
|
||||
var commandHeader = "const Clutter = imports.gi.Clutter; " +
|
||||
"const GLib = imports.gi.GLib; " +
|
||||
"const Gtk = imports.gi.Gtk; " +
|
||||
"const Mainloop = imports.mainloop; " +
|
||||
"const Meta = imports.gi.Meta; " +
|
||||
"const Shell = imports.gi.Shell; " +
|
||||
"const Main = imports.ui.main; " +
|
||||
"const Lang = imports.lang; " +
|
||||
"const Tweener = imports.ui.tweener; " +
|
||||
var commandHeader = 'const Clutter = imports.gi.Clutter; ' +
|
||||
'const GLib = imports.gi.GLib; ' +
|
||||
'const Gtk = imports.gi.Gtk; ' +
|
||||
'const Mainloop = imports.mainloop; ' +
|
||||
'const Meta = imports.gi.Meta; ' +
|
||||
'const Shell = imports.gi.Shell; ' +
|
||||
'const Main = imports.ui.main; ' +
|
||||
'const Lang = imports.lang; ' +
|
||||
'const Tweener = imports.ui.tweener; ' +
|
||||
/* Utility functions...we should probably be able to use these
|
||||
* in the shell core code too. */
|
||||
"const stage = global.stage; " +
|
||||
"const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; " +
|
||||
'const stage = global.stage; ' +
|
||||
'const color = function(pixel) { let c= new Clutter.Color(); c.from_pixel(pixel); return c; }; ' +
|
||||
/* Special lookingGlass functions */
|
||||
"const it = Main.lookingGlass.getIt(); " +
|
||||
"const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ";
|
||||
'const it = Main.lookingGlass.getIt(); ' +
|
||||
'const r = Lang.bind(Main.lookingGlass, Main.lookingGlass.getResult); ';
|
||||
|
||||
function Notebook() {
|
||||
this._init();
|
||||
@ -43,14 +43,16 @@ Notebook.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
|
||||
this.tabControls = new St.BoxLayout({ style_class: "labels" });
|
||||
this.tabControls = new St.BoxLayout({ style_class: 'labels' });
|
||||
|
||||
this._selectedIndex = -1;
|
||||
this._tabs = [];
|
||||
},
|
||||
|
||||
appendPage: function(name, child) {
|
||||
let labelBox = new St.BoxLayout({ style_class: "notebook-tab" });
|
||||
let labelBox = new St.BoxLayout({ style_class: 'notebook-tab',
|
||||
reactive: true,
|
||||
track_hover: true });
|
||||
let label = new St.Button({ label: name });
|
||||
label.connect('clicked', Lang.bind(this, function () {
|
||||
this.selectChild(child);
|
||||
@ -84,7 +86,7 @@ Notebook.prototype = {
|
||||
if (this._selectedIndex < 0)
|
||||
return;
|
||||
let tabData = this._tabs[this._selectedIndex];
|
||||
tabData.labelBox.set_style_pseudo_class(null);
|
||||
tabData.labelBox.remove_style_pseudo_class('selected');
|
||||
tabData.scrollView.hide();
|
||||
this._selectedIndex = -1;
|
||||
},
|
||||
@ -98,7 +100,7 @@ Notebook.prototype = {
|
||||
return;
|
||||
}
|
||||
let tabData = this._tabs[index];
|
||||
tabData.labelBox.set_style_pseudo_class('selected');
|
||||
tabData.labelBox.add_style_pseudo_class('selected');
|
||||
tabData.scrollView.show();
|
||||
this._selectedIndex = index;
|
||||
this.emit('selection', tabData.child);
|
||||
@ -139,6 +141,40 @@ Notebook.prototype = {
|
||||
};
|
||||
Signals.addSignalMethods(Notebook.prototype);
|
||||
|
||||
function objectToString(o) {
|
||||
if (typeof(o) == typeof(objectToString)) {
|
||||
// special case this since the default is way, way too verbose
|
||||
return "<js function>";
|
||||
} else {
|
||||
return "" + o;
|
||||
}
|
||||
}
|
||||
|
||||
function ObjLink(o, title) {
|
||||
this._init(o, title);
|
||||
}
|
||||
|
||||
ObjLink.prototype = {
|
||||
__proto__: Link.Link,
|
||||
|
||||
_init: function(o, title) {
|
||||
let text;
|
||||
if (title)
|
||||
text = title;
|
||||
else
|
||||
text = objectToString(o);
|
||||
text = GLib.markup_escape_text(text, -1);
|
||||
this._obj = o;
|
||||
Link.Link.prototype._init.call(this, { label: text });
|
||||
this.actor.get_child().single_line_mode = true;
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
},
|
||||
|
||||
_onClicked: function (link) {
|
||||
Main.lookingGlass.inspectObject(this._obj, this.actor);
|
||||
}
|
||||
};
|
||||
|
||||
function Result(command, o, index) {
|
||||
this._init(command, o, index);
|
||||
}
|
||||
@ -148,108 +184,175 @@ Result.prototype = {
|
||||
this.index = index;
|
||||
this.o = o;
|
||||
|
||||
this.actor = new Big.Box();
|
||||
this.actor = new St.BoxLayout({ vertical: true });
|
||||
|
||||
let cmdTxt = new St.Label({ text: command });
|
||||
cmdTxt.ellipsize = Pango.EllipsizeMode.END;
|
||||
|
||||
this.actor.append(cmdTxt, Big.BoxPackFlags.NONE);
|
||||
let resultTxt = new St.Label({ text: "r(" + index + ") = " + o });
|
||||
resultTxt.ellipsize = Pango.EllipsizeMode.END;
|
||||
|
||||
this.actor.append(resultTxt, Big.BoxPackFlags.NONE);
|
||||
let line = new Clutter.Rectangle({ name: "Separator",
|
||||
height: 1 });
|
||||
let padBin = new St.Bin({ name: "Separator", x_fill: true, y_fill: true });
|
||||
cmdTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
this.actor.add(cmdTxt);
|
||||
let box = new St.BoxLayout({});
|
||||
this.actor.add(box);
|
||||
let resultTxt = new St.Label({ text: 'r(' + index + ') = ' });
|
||||
resultTxt.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
box.add(resultTxt);
|
||||
let objLink = new ObjLink(o);
|
||||
box.add(objLink.actor);
|
||||
let line = new Clutter.Rectangle({ name: 'Separator' });
|
||||
let padBin = new St.Bin({ name: 'Separator', x_fill: true, y_fill: true });
|
||||
padBin.add_actor(line);
|
||||
this.actor.append(padBin, Big.BoxPackFlags.NONE);
|
||||
this.actor.add(padBin);
|
||||
}
|
||||
};
|
||||
|
||||
function ActorHierarchy() {
|
||||
function WindowList() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ActorHierarchy.prototype = {
|
||||
WindowList.prototype = {
|
||||
_init : function () {
|
||||
this._previousTarget = null;
|
||||
this._target = null;
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
this.actor = new St.BoxLayout({ name: "ActorHierarchy", vertical: true });
|
||||
this.actor = new St.BoxLayout({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||
let display = global.screen.get_display();
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
this._updateId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._updateWindowList));
|
||||
display.connect('window-created', Lang.bind(this, this._updateWindowList));
|
||||
tracker.connect('tracked-windows-changed', Lang.bind(this, this._updateWindowList));
|
||||
},
|
||||
|
||||
setTarget: function(actor) {
|
||||
this._previousTarget = this._target;
|
||||
this.target = actor;
|
||||
|
||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
||||
|
||||
if (!(actor instanceof Clutter.Actor))
|
||||
return;
|
||||
|
||||
if (this.target == null)
|
||||
return;
|
||||
|
||||
this._parentList = [];
|
||||
let parent = actor;
|
||||
while ((parent = parent.get_parent()) != null) {
|
||||
this._parentList.push(parent);
|
||||
|
||||
let link = new St.Label({ reactive: true,
|
||||
text: "" + parent });
|
||||
this.actor.add_actor(link);
|
||||
let parentTarget = parent;
|
||||
link.connect('button-press-event', Lang.bind(this, function () {
|
||||
this._selectByActor(parentTarget);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
this.emit('selection', actor);
|
||||
},
|
||||
|
||||
_selectByActor: function(actor) {
|
||||
let idx = this._parentList.indexOf(actor);
|
||||
let children = this.actor.get_children();
|
||||
let link = children[idx];
|
||||
this.emit('selection', actor);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ActorHierarchy.prototype);
|
||||
|
||||
function PropertyInspector() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
PropertyInspector.prototype = {
|
||||
_init : function () {
|
||||
this._target = null;
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
this.actor = new St.BoxLayout({ name: "PropertyInspector", vertical: true });
|
||||
},
|
||||
|
||||
setTarget: function(actor) {
|
||||
this.target = actor;
|
||||
|
||||
this.actor.get_children().forEach(function (child) { child.destroy(); });
|
||||
|
||||
for (let propName in actor) {
|
||||
let valueStr;
|
||||
try {
|
||||
valueStr = "" + actor[propName];
|
||||
} catch (e) {
|
||||
valueStr = '<error>';
|
||||
_updateWindowList: function() {
|
||||
this.actor.get_children().forEach(function (actor) { actor.destroy(); });
|
||||
let windows = global.get_windows();
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
let metaWindow = windows[i].metaWindow;
|
||||
metaWindow.connect('unmanaged', Lang.bind(this, this._updateWindowList));
|
||||
let box = new St.BoxLayout({ vertical: true });
|
||||
this.actor.add(box);
|
||||
let windowLink = new ObjLink(metaWindow, metaWindow.title);
|
||||
box.add(windowLink.actor, { x_align: St.Align.START, x_fill: false });
|
||||
let propsBox = new St.BoxLayout({ vertical: true, style: 'padding-left: 6px;' });
|
||||
box.add(propsBox);
|
||||
propsBox.add(new St.Label({ text: 'wmclass: ' + metaWindow.get_wm_class() }));
|
||||
let app = tracker.get_window_app(metaWindow);
|
||||
if (app != null && !app.is_transient()) {
|
||||
let icon = app.create_icon_texture(22);
|
||||
let propBox = new St.BoxLayout({ style: 'spacing: 6px; ' });
|
||||
propsBox.add(propBox);
|
||||
propBox.add(new St.Label({ text: 'app: ' }), { y_fill: false });
|
||||
let appLink = new ObjLink(app, app.get_id());
|
||||
propBox.add(appLink.actor, { y_fill: false });
|
||||
propBox.add(icon, { y_fill: false });
|
||||
} else {
|
||||
propsBox.add(new St.Label({ text: '<untracked>' }));
|
||||
}
|
||||
let propText = propName + ": " + valueStr;
|
||||
let propDisplay = new St.Label({ reactive: true,
|
||||
text: propText });
|
||||
this.actor.add_actor(propDisplay);
|
||||
}
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(WindowList.prototype);
|
||||
|
||||
function ObjInspector() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ObjInspector.prototype = {
|
||||
_init : function () {
|
||||
this._obj = null;
|
||||
this._previousObj = null;
|
||||
|
||||
this._parentList = [];
|
||||
|
||||
this.actor = new St.ScrollView({ x_fill: true, y_fill: true });
|
||||
this.actor.get_hscroll_bar().hide();
|
||||
this._container = new St.BoxLayout({ name: 'LookingGlassPropertyInspector',
|
||||
style_class: 'lg-dialog',
|
||||
vertical: true });
|
||||
this.actor.add_actor(this._container);
|
||||
},
|
||||
|
||||
selectObject: function(obj, skipPrevious) {
|
||||
if (!skipPrevious)
|
||||
this._previousObj = this._obj;
|
||||
else
|
||||
this._previousObj = null;
|
||||
this._obj = obj;
|
||||
|
||||
this._container.get_children().forEach(function (child) { child.destroy(); });
|
||||
|
||||
let hbox = new St.BoxLayout({ style_class: 'lg-obj-inspector-title' });
|
||||
this._container.add_actor(hbox);
|
||||
let label = new St.Label({ text: 'Inspecting: %s: %s'.format(typeof(obj),
|
||||
objectToString(obj)) });
|
||||
label.single_line_mode = true;
|
||||
hbox.add(label, { expand: true, y_fill: false });
|
||||
let button = new St.Button({ label: 'Insert', style_class: 'lg-obj-inspector-button' });
|
||||
button.connect('clicked', Lang.bind(this, this._onInsert));
|
||||
hbox.add(button);
|
||||
|
||||
if (this._previousObj != null) {
|
||||
button = new St.Button({ label: 'Back', style_class: 'lg-obj-inspector-button' });
|
||||
button.connect('clicked', Lang.bind(this, this._onBack));
|
||||
hbox.add(button);
|
||||
}
|
||||
|
||||
button = new St.Button({ style_class: 'window-close' });
|
||||
button.connect('clicked', Lang.bind(this, this.close));
|
||||
hbox.add(button);
|
||||
if (typeof(obj) == typeof({})) {
|
||||
for (let propName in obj) {
|
||||
let valueStr;
|
||||
let link;
|
||||
try {
|
||||
let prop = obj[propName];
|
||||
link = new ObjLink(prop).actor;
|
||||
} catch (e) {
|
||||
link = new St.Label({ text: '<error>' });
|
||||
}
|
||||
let hbox = new St.BoxLayout();
|
||||
let propText = propName + ": " + valueStr;
|
||||
hbox.add(new St.Label({ text: propName + ': ' }));
|
||||
hbox.add(link);
|
||||
this._container.add_actor(hbox);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
open: function(sourceActor) {
|
||||
if (this._open)
|
||||
return;
|
||||
this._previousObj = null;
|
||||
this._open = true;
|
||||
this.actor.show();
|
||||
if (sourceActor) {
|
||||
this.actor.set_scale(0, 0);
|
||||
let [sourceX, sourceY] = sourceActor.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
|
||||
this.actor.move_anchor_point(Math.floor(sourceX + sourceWidth / 2),
|
||||
Math.floor(sourceY + sourceHeight / 2));
|
||||
Tweener.addTween(this.actor, { scale_x: 1, scale_y: 1,
|
||||
transition: "easeOutQuad",
|
||||
time: 0.2 });
|
||||
} else {
|
||||
this.actor.set_scale(1, 1);
|
||||
}
|
||||
},
|
||||
|
||||
close: function() {
|
||||
if (!this._open)
|
||||
return;
|
||||
this._open = false;
|
||||
this.actor.hide();
|
||||
this._previousObj = null;
|
||||
this._obj = null;
|
||||
},
|
||||
|
||||
_onInsert: function() {
|
||||
let obj = this._obj;
|
||||
this.close();
|
||||
Main.lookingGlass.insertObject(obj);
|
||||
},
|
||||
|
||||
_onBack: function() {
|
||||
this.selectObject(this._previousObj, true);
|
||||
}
|
||||
};
|
||||
|
||||
function Inspector() {
|
||||
this._init();
|
||||
@ -259,14 +362,14 @@ Inspector.prototype = {
|
||||
_init: function() {
|
||||
let width = 150;
|
||||
let primary = global.get_primary_monitor();
|
||||
let eventHandler = new St.BoxLayout({ name: "LookingGlassDialog",
|
||||
let eventHandler = new St.BoxLayout({ name: 'LookingGlassDialog',
|
||||
vertical: false,
|
||||
y: primary.y + Math.floor(primary.height / 2),
|
||||
reactive: true });
|
||||
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
||||
eventHandler.x = primary.x + Math.floor((primary.width - eventHandler.width) / 2);
|
||||
}));
|
||||
global.stage.add_actor(eventHandler);
|
||||
Main.uiGroup.add_actor(eventHandler);
|
||||
let displayText = new St.Label();
|
||||
eventHandler.add(displayText, { expand: true });
|
||||
|
||||
@ -345,7 +448,7 @@ ErrorLog.prototype = {
|
||||
let stack = Main._getAndClearErrorStack();
|
||||
for (let i = 0; i < stack.length; i++) {
|
||||
let logItem = stack[i];
|
||||
text += logItem.category + " t=" + this._formatTime(new Date(logItem.timestamp)) + " " + logItem.message + "\n";
|
||||
text += logItem.category + ' t=' + this._formatTime(new Date(logItem.timestamp)) + ' ' + logItem.message + '\n';
|
||||
}
|
||||
this.text.text = text;
|
||||
}
|
||||
@ -405,7 +508,7 @@ Extensions.prototype = {
|
||||
case ExtensionSystem.ExtensionState.OUT_OF_DATE:
|
||||
return _("Out of date");
|
||||
}
|
||||
return "Unknown"; // Not translated, shouldn't appear
|
||||
return 'Unknown'; // Not translated, shouldn't appear
|
||||
},
|
||||
|
||||
_createExtensionDisplay: function(meta) {
|
||||
@ -451,7 +554,7 @@ function LookingGlass() {
|
||||
LookingGlass.prototype = {
|
||||
_init : function() {
|
||||
this._idleHistorySaveId = 0;
|
||||
let historyPath = global.configdir + "/lookingglass-history.txt";
|
||||
let historyPath = global.userdatadir + '/lookingglass-history.txt';
|
||||
this._historyFile = Gio.file_new_for_path(historyPath);
|
||||
this._savedText = null;
|
||||
this._historyNavIndex = -1;
|
||||
@ -470,19 +573,24 @@ LookingGlass.prototype = {
|
||||
// Sort of magic, but...eh.
|
||||
this._maxItems = 150;
|
||||
|
||||
this.actor = new St.BoxLayout({ name: "LookingGlassDialog",
|
||||
this.actor = new St.BoxLayout({ name: 'LookingGlassDialog',
|
||||
style_class: 'lg-dialog',
|
||||
vertical: true,
|
||||
visible: false });
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
gconf.watch_directory("/desktop/gnome/interface");
|
||||
gconf.connect("changed::/desktop/gnome/interface/monospace_font_name",
|
||||
gconf.watch_directory('/desktop/gnome/interface');
|
||||
gconf.connect('changed::/desktop/gnome/interface/monospace_font_name',
|
||||
Lang.bind(this, this._updateFont));
|
||||
this._updateFont();
|
||||
|
||||
global.stage.add_actor(this.actor);
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
|
||||
let toolbar = new St.BoxLayout({ name: "Toolbar" });
|
||||
this._objInspector = new ObjInspector();
|
||||
Main.uiGroup.add_actor(this._objInspector.actor);
|
||||
this._objInspector.actor.hide();
|
||||
|
||||
let toolbar = new St.BoxLayout({ name: 'Toolbar' });
|
||||
this.actor.add_actor(toolbar);
|
||||
let inspectIcon = St.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
|
||||
24);
|
||||
@ -493,7 +601,6 @@ LookingGlass.prototype = {
|
||||
inspector.connect('target', Lang.bind(this, function(i, target, stageX, stageY) {
|
||||
this._pushResult('<inspect x:' + stageX + ' y:' + stageY + '>',
|
||||
target);
|
||||
this._hierarchy.setTarget(target);
|
||||
}));
|
||||
inspector.connect('closed', Lang.bind(this, function() {
|
||||
this.actor.show();
|
||||
@ -511,18 +618,17 @@ LookingGlass.prototype = {
|
||||
toolbar.add(emptyBox, { expand: true });
|
||||
toolbar.add_actor(notebook.tabControls);
|
||||
|
||||
this._evalBox = new St.BoxLayout({ name: "EvalBox", vertical: true });
|
||||
this._evalBox = new St.BoxLayout({ name: 'EvalBox', vertical: true });
|
||||
notebook.appendPage('Evaluator', this._evalBox);
|
||||
|
||||
this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: 4 });
|
||||
this._resultsArea = new St.BoxLayout({ name: 'ResultsArea', vertical: true });
|
||||
this._evalBox.add(this._resultsArea, { expand: true });
|
||||
|
||||
let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
let entryArea = new St.BoxLayout({ name: 'EntryArea' });
|
||||
this._evalBox.add_actor(entryArea);
|
||||
|
||||
let label = new St.Label({ text: 'js>>> ' });
|
||||
entryArea.append(label, Big.BoxPackFlags.NONE);
|
||||
entryArea.add(label);
|
||||
|
||||
this._entry = new St.Entry();
|
||||
/* unmapping the edit box will un-focus it, undo that */
|
||||
@ -530,17 +636,14 @@ LookingGlass.prototype = {
|
||||
if (child == this._evalBox)
|
||||
global.stage.set_key_focus(this._entry);
|
||||
}));
|
||||
entryArea.append(this._entry, Big.BoxPackFlags.EXPAND);
|
||||
entryArea.add(this._entry, { expand: true });
|
||||
|
||||
this._hierarchy = new ActorHierarchy();
|
||||
notebook.appendPage('Hierarchy', this._hierarchy.actor);
|
||||
|
||||
this._propInspector = new PropertyInspector();
|
||||
notebook.appendPage('Properties', this._propInspector.actor);
|
||||
this._hierarchy.connect('selection', Lang.bind(this, function (h, actor) {
|
||||
this._pushResult('<parent selection>', actor);
|
||||
this._windowList = new WindowList();
|
||||
this._windowList.connect('selected', Lang.bind(this, function(list, window) {
|
||||
notebook.selectIndex(0);
|
||||
this._pushResult('<window selection>', window);
|
||||
}));
|
||||
notebook.appendPage('Windows', this._windowList.actor);
|
||||
|
||||
this._errorLog = new ErrorLog();
|
||||
notebook.appendPage('Errors', this._errorLog.actor);
|
||||
@ -554,7 +657,7 @@ LookingGlass.prototype = {
|
||||
// newline-separated.
|
||||
text.replace('\n', ' ');
|
||||
// Strip leading and trailing whitespace
|
||||
text = text.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
||||
text = text.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||
if (text == '')
|
||||
return true;
|
||||
this._evaluate(text);
|
||||
@ -590,7 +693,7 @@ LookingGlass.prototype = {
|
||||
|
||||
_updateFont: function() {
|
||||
let gconf = Shell.GConf.get_default();
|
||||
let fontName = gconf.get_string("/desktop/gnome/interface/monospace_font_name");
|
||||
let fontName = gconf.get_string('/desktop/gnome/interface/monospace_font_name');
|
||||
// This is mishandled by the scanner - should by Pango.FontDescription_from_string(fontName);
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=595889
|
||||
let fontDesc = Pango.Font.description_from_string(fontName);
|
||||
@ -628,8 +731,7 @@ LookingGlass.prototype = {
|
||||
let index = this._results.length + this._offset;
|
||||
let result = new Result('>>> ' + command, obj, index);
|
||||
this._results.push(result);
|
||||
this._resultsArea.append(result.actor, Big.BoxPackFlags.NONE);
|
||||
this._propInspector.setTarget(obj);
|
||||
this._resultsArea.add(result.actor);
|
||||
if (this._borderPaintTarget != null) {
|
||||
this._borderPaintTarget.disconnect(this._borderPaintId);
|
||||
this._borderPaintTarget = null;
|
||||
@ -664,11 +766,10 @@ LookingGlass.prototype = {
|
||||
try {
|
||||
resultObj = eval(fullCmd);
|
||||
} catch (e) {
|
||||
resultObj = "<exception " + e + ">";
|
||||
resultObj = '<exception ' + e + '>';
|
||||
}
|
||||
|
||||
this._pushResult(command, resultObj);
|
||||
this._hierarchy.setTarget(null);
|
||||
this._entry.text = '';
|
||||
},
|
||||
|
||||
@ -698,6 +799,9 @@ LookingGlass.prototype = {
|
||||
this.actor.y = this._hiddenY;
|
||||
this.actor.width = myWidth;
|
||||
this.actor.height = myHeight;
|
||||
this._objInspector.actor.set_size(Math.floor(myWidth * 0.8), Math.floor(myHeight * 0.8));
|
||||
this._objInspector.actor.set_position(this.actor.x + Math.floor(myWidth * 0.1),
|
||||
this._targetY + Math.floor(myHeight * 0.1));
|
||||
},
|
||||
|
||||
slaveTo: function(actor) {
|
||||
@ -708,11 +812,24 @@ LookingGlass.prototype = {
|
||||
this._resizeTo(actor);
|
||||
},
|
||||
|
||||
insertObject: function(obj) {
|
||||
this._pushResult('<insert>', obj);
|
||||
},
|
||||
|
||||
inspectObject: function(obj, sourceActor) {
|
||||
this._objInspector.open(sourceActor);
|
||||
this._objInspector.selectObject(obj);
|
||||
},
|
||||
|
||||
// Handle key events which are relevant for all tabs of the LookingGlass
|
||||
_globalKeyPressEvent : function(actor, event) {
|
||||
let symbol = event.get_key_symbol();
|
||||
if (symbol == Clutter.Escape) {
|
||||
this.close();
|
||||
if (this._objInspector.actor.visible) {
|
||||
this._objInspector.close();
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -737,7 +854,7 @@ LookingGlass.prototype = {
|
||||
global.stage.set_key_focus(this._entry);
|
||||
|
||||
Tweener.addTween(this.actor, { time: 0.5,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
y: this._targetY
|
||||
});
|
||||
},
|
||||
@ -749,6 +866,8 @@ LookingGlass.prototype = {
|
||||
if (this._keyPressEventId)
|
||||
global.stage.disconnect(this._keyPressEventId);
|
||||
|
||||
this._objInspector.actor.hide();
|
||||
|
||||
this._historyNavIndex = -1;
|
||||
this._open = false;
|
||||
Tweener.removeTweens(this.actor);
|
||||
@ -762,7 +881,7 @@ LookingGlass.prototype = {
|
||||
Main.popModal(this.actor);
|
||||
|
||||
Tweener.addTween(this.actor, { time: 0.5,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
y: this._hiddenY,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.hide();
|
||||
|
1479
js/ui/magnifier.js
Normal file
1479
js/ui/magnifier.js
Normal file
File diff suppressed because it is too large
Load Diff
375
js/ui/magnifierDBus.js
Normal file
375
js/ui/magnifierDBus.js
Normal file
@ -0,0 +1,375 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
|
||||
const MAG_SERVICE_PATH = '/org/gnome/Magnifier';
|
||||
const ZOOM_SERVICE_NAME = 'org.gnome.Magnifier.ZoomRegion';
|
||||
const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
|
||||
|
||||
// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See:
|
||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
|
||||
const MagnifierIface = {
|
||||
name: MAG_SERVICE_NAME,
|
||||
methods: [
|
||||
{ name: 'setActive', inSignature: 'b', outSignature: '' },
|
||||
{ name: 'isActive', inSignature: '', outSignature: 'b' },
|
||||
{ name: 'showCursor', inSignature: '', outSignature: '' },
|
||||
{ name: 'hideCursor', inSignature: '', outSignature: '' },
|
||||
{ name: 'createZoomRegion', inSignature: 'ddaiai', outSignature: 'o' },
|
||||
{ name: 'addZoomRegion', inSignature: 'o', outSignature: 'b' },
|
||||
{ name: 'getZoomRegions', inSignature: '', outSignature: 'ao' },
|
||||
{ name: 'clearAllZoomRegions', inSignature: '', outSignature: '' },
|
||||
{ name: 'fullScreenCapable', inSignature: '', outSignature: 'b' },
|
||||
|
||||
{ name: 'setCrosswireSize', inSignature: 'i', outSignature: '' },
|
||||
{ name: 'getCrosswireSize', inSignature: '', outSignature: 'i' },
|
||||
{ name: 'setCrosswireLength', inSignature: 'i', outSignature: '' },
|
||||
{ name: 'getCrosswireLength', inSignature: '', outSignature: 'i' },
|
||||
{ name: 'setCrosswireClip', inSignature: 'b', outSignature: '' },
|
||||
{ name: 'getCrosswireClip', inSignature: '', outSignature: 'b' },
|
||||
{ name: 'setCrosswireColor', inSignature: 'u', outSignature: '' },
|
||||
{ name: 'getCrosswireColor', inSignature: '', outSignature: 'u' }
|
||||
],
|
||||
signals: [],
|
||||
properties: []
|
||||
};
|
||||
|
||||
// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See:
|
||||
// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
|
||||
const ZoomRegionIface = {
|
||||
name: ZOOM_SERVICE_NAME,
|
||||
methods: [
|
||||
{ name: 'setMagFactor', inSignature: 'dd', outSignature: ''},
|
||||
{ name: 'getMagFactor', inSignature: '', outSignature: 'dd' },
|
||||
{ name: 'setRoi', inSignature: 'ai', outSignature: '' },
|
||||
{ name: 'getRoi', inSignature: '', outSignature: 'ai' },
|
||||
{ name: 'shiftContentsTo', inSignature: 'ii', outSignature: 'b' },
|
||||
{ name: 'moveResize', inSignature: 'ai', outSignature: '' }
|
||||
],
|
||||
signals: [],
|
||||
properties: []
|
||||
};
|
||||
|
||||
// For making unique ZoomRegion DBus proxy object paths of the form:
|
||||
// '/org/gnome/Magnifier/ZoomRegion/zoomer0',
|
||||
// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc.
|
||||
let _zoomRegionInstanceCount = 0;
|
||||
|
||||
function ShellMagnifier() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ShellMagnifier.prototype = {
|
||||
_init: function() {
|
||||
this._zoomers = {};
|
||||
DBus.session.exportObject(MAG_SERVICE_PATH, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* setActive:
|
||||
* @activate: Boolean to activate or de-activate the magnifier.
|
||||
*/
|
||||
setActive: function(activate) {
|
||||
Main.magnifier.setActive(activate);
|
||||
},
|
||||
|
||||
/**
|
||||
* isActive:
|
||||
* @return Whether the magnifier is active (boolean).
|
||||
*/
|
||||
isActive: function() {
|
||||
return Main.magnifier.isActive();
|
||||
},
|
||||
|
||||
/**
|
||||
* showCursor:
|
||||
* Show the system mouse pointer.
|
||||
*/
|
||||
showCursor: function() {
|
||||
Main.magnifier.showSystemCursor();
|
||||
},
|
||||
|
||||
/**
|
||||
* hideCursor:
|
||||
* Hide the system mouse pointer.
|
||||
*/
|
||||
hideCursor: function() {
|
||||
Main.magnifier.hideSystemCursor();
|
||||
},
|
||||
|
||||
/**
|
||||
* createZoomRegion:
|
||||
* Create a new ZoomRegion and return its object path.
|
||||
* @xMagFactor: The power to set horizontal magnification of the
|
||||
* ZoomRegion. A value of 1.0 means no magnification. A
|
||||
* value of 2.0 doubles the size.
|
||||
* @yMagFactor: The power to set the vertical magnification of the
|
||||
* ZoomRegion.
|
||||
* @roi Array of integers defining the region of the
|
||||
* screen/desktop to magnify. The array has the form
|
||||
* [x, y, width, height].
|
||||
* @viewPort Array of integers, [ x, y, width, height ] that defines
|
||||
* the position of the ZoomRegion on screen.
|
||||
* @return The newly created ZoomRegion.
|
||||
*/
|
||||
createZoomRegion: function(xMagFactor, yMagFactor, roi, viewPort) {
|
||||
let ROI = { x: roi[0], y: roi[1], width: roi[2], height: roi[3] };
|
||||
let viewBox = { x: viewPort[0], y: viewPort[1], width: viewPort[2], height: viewPort[3] };
|
||||
let realZoomRegion = Main.magnifier.createZoomRegion(xMagFactor, yMagFactor, ROI, viewBox);
|
||||
let objectPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
||||
_zoomRegionInstanceCount++;
|
||||
|
||||
let zoomRegionProxy = new ShellMagnifierZoomRegion(objectPath, realZoomRegion);
|
||||
let proxyAndZoomRegion = {};
|
||||
proxyAndZoomRegion.proxy = zoomRegionProxy;
|
||||
proxyAndZoomRegion.zoomRegion = realZoomRegion;
|
||||
this._zoomers[objectPath] = proxyAndZoomRegion;
|
||||
return objectPath;
|
||||
},
|
||||
|
||||
/**
|
||||
* addZoomRegion:
|
||||
* Append the given ZoomRegion to the magnifier's list of ZoomRegions.
|
||||
* @zoomerObjectPath: The object path for the zoom region proxy.
|
||||
*/
|
||||
addZoomRegion: function(zoomerObjectPath) {
|
||||
let proxyAndZoomRegion = this._zoomers[zoomerObjectPath];
|
||||
if (proxyAndZoomRegion && proxyAndZoomRegion.zoomRegion) {
|
||||
Main.magnifier.addZoomRegion(proxyAndZoomRegion.zoomRegion);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* getZoomRegions:
|
||||
* Return a list of ZoomRegion object paths for this Magnifier.
|
||||
* @return: The Magnifier's zoom region list as an array of DBus object
|
||||
* paths.
|
||||
*/
|
||||
getZoomRegions: function() {
|
||||
// There may be more ZoomRegions in the magnifier itself than have
|
||||
// been added through dbus. Make sure all of them are associated with
|
||||
// an object path and proxy.
|
||||
let zoomRegions = Main.magnifier.getZoomRegions();
|
||||
let objectPaths = [];
|
||||
let thoseZoomers = this._zoomers;
|
||||
zoomRegions.forEach (function(aZoomRegion, index, array) {
|
||||
let found = false;
|
||||
for (let objectPath in thoseZoomers) {
|
||||
let proxyAndZoomRegion = thoseZoomers[objectPath];
|
||||
if (proxyAndZoomRegion.zoomRegion === aZoomRegion) {
|
||||
objectPaths.push(objectPath);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Got a ZoomRegion with no DBus proxy, make one.
|
||||
let newPath = ZOOM_SERVICE_PATH + '/zoomer' + _zoomRegionInstanceCount;
|
||||
_zoomRegionInstanceCount++;
|
||||
let zoomRegionProxy = new ShellMagnifierZoomRegion(newPath, aZoomRegion);
|
||||
let proxyAndZoomer = {};
|
||||
proxyAndZoomer.proxy = zoomRegionProxy;
|
||||
proxyAndZoomer.zoomRegion = aZoomRegion;
|
||||
thoseZoomers[newPath] = proxyAndZoomer;
|
||||
objectPaths.push(newPath);
|
||||
}
|
||||
});
|
||||
return objectPaths;
|
||||
},
|
||||
|
||||
/**
|
||||
* clearAllZoomRegions:
|
||||
* Remove all the zoom regions from this Magnfier's ZoomRegion list.
|
||||
*/
|
||||
clearAllZoomRegions: function() {
|
||||
Main.magnifier.clearAllZoomRegions();
|
||||
for (let objectPath in this._zoomers) {
|
||||
let proxyAndZoomer = this._zoomers[objectPath];
|
||||
proxyAndZoomer.proxy = null;
|
||||
proxyAndZoomer.zoomRegion = null;
|
||||
delete this._zoomers[objectPath];
|
||||
DBus.session.unexportObject(proxyAndZoomer);
|
||||
}
|
||||
this._zoomers = {};
|
||||
},
|
||||
|
||||
/**
|
||||
* fullScreenCapable:
|
||||
* Consult if the Magnifier can magnify in full-screen mode.
|
||||
* @return Always return true.
|
||||
*/
|
||||
fullScreenCapable: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* setCrosswireSize:
|
||||
* Set the crosswire size of all ZoomRegions.
|
||||
* @size: The thickness of each line in the cross wire.
|
||||
*/
|
||||
setCrosswireSize: function(size) {
|
||||
Main.magnifier.setCrosshairsThickness(size);
|
||||
},
|
||||
|
||||
/**
|
||||
* getCrosswireSize:
|
||||
* Get the crosswire size of all ZoomRegions.
|
||||
* @return: The thickness of each line in the cross wire.
|
||||
*/
|
||||
getCrosswireSize: function() {
|
||||
return Main.magnifier.getCrosshairsThickness();
|
||||
},
|
||||
|
||||
/**
|
||||
* setCrosswireLength:
|
||||
* Set the crosswire length of all zoom-regions..
|
||||
* @size: The length of each line in the cross wire.
|
||||
*/
|
||||
setCrosswireLength: function(length) {
|
||||
Main.magnifier.setCrosshairsLength(length);
|
||||
},
|
||||
|
||||
/**
|
||||
* setCrosswireSize:
|
||||
* Set the crosswire size of all zoom-regions.
|
||||
* @size: The thickness of each line in the cross wire.
|
||||
*/
|
||||
getCrosswireLength: function() {
|
||||
return Main.magnifier.getCrosshairsLength();
|
||||
},
|
||||
|
||||
/**
|
||||
* setCrosswireClip:
|
||||
* Set if the crosswire will be clipped by the cursor image..
|
||||
* @clip: Flag to indicate whether to clip the crosswire.
|
||||
*/
|
||||
setCrosswireClip: function(clip) {
|
||||
Main.magnifier.setCrosshairsClip(clip);
|
||||
},
|
||||
|
||||
/**
|
||||
* getCrosswireClip:
|
||||
* Get the crosswire clip value.
|
||||
* @return: Whether the crosswire is clipped by the cursor image.
|
||||
*/
|
||||
getCrosswireClip: function() {
|
||||
return Main.magnifier.getCrosshairsClip();
|
||||
},
|
||||
|
||||
/**
|
||||
* setCrosswireColor:
|
||||
* Set the crosswire color of all ZoomRegions.
|
||||
* @color: Unsigned int of the form rrggbbaa.
|
||||
*/
|
||||
setCrosswireColor: function(color) {
|
||||
Main.magnifier.setCrosshairsColor('#' + color.toString(16));
|
||||
},
|
||||
|
||||
/**
|
||||
* getCrosswireClip:
|
||||
* Get the crosswire color of all ZoomRegions.
|
||||
* @return: The crosswire color as an unsigned int in the form rrggbbaa.
|
||||
*/
|
||||
getCrosswireColor: function() {
|
||||
let colorString = Main.magnifier.getCrosshairsColor();
|
||||
// Drop the leading '#'.
|
||||
return parseInt(colorString.slice(1), 16);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ShellMagnifierZoomRegion:
|
||||
* Object that implements the DBus ZoomRegion interface.
|
||||
* @zoomerObjectPath: String that is the path to a DBus ZoomRegion.
|
||||
* @zoomRegion: The actual zoom region associated with the object path.
|
||||
*/
|
||||
function ShellMagnifierZoomRegion(zoomerObjectPath, zoomRegion) {
|
||||
this._init(zoomerObjectPath, zoomRegion);
|
||||
}
|
||||
|
||||
ShellMagnifierZoomRegion.prototype = {
|
||||
_init: function(zoomerObjectPath, zoomRegion) {
|
||||
this._zoomRegion = zoomRegion;
|
||||
DBus.session.proxifyObject(this, ZOOM_SERVICE_NAME, zoomerObjectPath);
|
||||
DBus.session.exportObject(zoomerObjectPath, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* setMagFactor:
|
||||
* @xMagFactor: The power to set the horizontal magnification factor to
|
||||
* of the magnified view. A value of 1.0 means no
|
||||
* magnification. A value of 2.0 doubles the size.
|
||||
* @yMagFactor: The power to set the vertical magnification factor to
|
||||
* of the magnified view.
|
||||
*/
|
||||
setMagFactor: function(xMagFactor, yMagFactor) {
|
||||
this._zoomRegion.setMagFactor(xMagFactor, yMagFactor);
|
||||
},
|
||||
|
||||
/**
|
||||
* getMagFactor:
|
||||
* @return an array, [xMagFactor, yMagFactor], containing the horizontal
|
||||
* and vertical magnification powers. A value of 1.0 means no
|
||||
* magnification. A value of 2.0 means the contents are doubled
|
||||
* in size, and so on.
|
||||
*/
|
||||
getMagFactor: function() {
|
||||
return this._zoomRegion.getMagFactor();
|
||||
},
|
||||
|
||||
/**
|
||||
* setRoi:
|
||||
* Sets the "region of interest" that the ZoomRegion is magnifying.
|
||||
* @roi Array, [x, y, width, height], defining the region of the screen to
|
||||
* magnify. The values are in screen (unmagnified) coordinate
|
||||
* space.
|
||||
*/
|
||||
setRoi: function(roi) {
|
||||
let roiObject = { x: roi[0], y: roi[1], width: roi[2], height: roi[3] };
|
||||
this._zoomRegion.setROI(roiObject);
|
||||
},
|
||||
|
||||
/**
|
||||
* getRoi:
|
||||
* Retrieves the "region of interest" -- the rectangular bounds of that part
|
||||
* of the desktop that the magnified view is showing (x, y, width, height).
|
||||
* The bounds are given in non-magnified coordinates.
|
||||
* @return an array, [x, y, width, height], representing the bounding
|
||||
* rectangle of what is shown in the magnified view.
|
||||
*/
|
||||
getRoi: function() {
|
||||
return this._zoomRegion.getROI();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the "region of interest" by centering the given screen coordinate
|
||||
* within the zoom region.
|
||||
* @x The x-coord of the point to place at the center of the zoom region.
|
||||
* @y The y-coord.
|
||||
* @return Whether the shift was successful (for GS-mag, this is always
|
||||
* true).
|
||||
*/
|
||||
shiftContentsTo: function(x, y) {
|
||||
this._zoomRegion.scrollContentsTo(x, y);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* moveResize
|
||||
* Sets the position and size of the ZoomRegion on screen.
|
||||
* @viewPort Array, [x, y, width, height], defining the position and size
|
||||
* on screen to place the zoom region.
|
||||
*/
|
||||
moveResize: function(viewPort) {
|
||||
let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2], height: viewPort[3] };
|
||||
this._zoomRegion.setViewPort(viewRect);
|
||||
}
|
||||
};
|
||||
|
||||
DBus.conformExport(ShellMagnifier.prototype, MagnifierIface);
|
||||
DBus.conformExport(ShellMagnifierZoomRegion.prototype, ZoomRegionIface);
|
@ -1,5 +1,11 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
imports.gi.versions.Clutter = '1.0';
|
||||
imports.gi.versions.Gio = '2.0';
|
||||
imports.gi.versions.Gdk = '2.0';
|
||||
imports.gi.versions.GdkPixbuf = '2.0';
|
||||
imports.gi.versions.Gtk = '2.0';
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const DBus = imports.dbus;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
@ -23,37 +29,41 @@ const RunDialog = imports.ui.runDialog;
|
||||
const LookingGlass = imports.ui.lookingGlass;
|
||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||
const Scripting = imports.ui.scripting;
|
||||
const ShellDBus = imports.ui.shellDBus;
|
||||
const Sidebar = imports.ui.sidebar;
|
||||
const TelepathyClient = imports.ui.telepathyClient;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
const Magnifier = imports.ui.magnifier;
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
|
||||
DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
||||
|
||||
let chrome = null;
|
||||
let panel = null;
|
||||
let sidebar = null;
|
||||
let placesManager = null;
|
||||
let overview = null;
|
||||
let runDialog = null;
|
||||
let lookingGlass = null;
|
||||
let wm = null;
|
||||
let notificationDaemon = null;
|
||||
let messageTray = null;
|
||||
let notificationDaemon = null;
|
||||
let windowAttentionHandler = null;
|
||||
let telepathyClient = null;
|
||||
let recorder = null;
|
||||
let shellDBusService = null;
|
||||
let modalCount = 0;
|
||||
let modalActorFocusStack = [];
|
||||
let uiGroup = null;
|
||||
let magnifier = null;
|
||||
let _errorLogStack = [];
|
||||
let _startDate;
|
||||
|
||||
let background = null;
|
||||
|
||||
function start() {
|
||||
// Add a binding for "global" in the global JS namespace; (gjs
|
||||
// Add a binding for 'global' in the global JS namespace; (gjs
|
||||
// keeps the web browser convention of having that namespace be
|
||||
// called "window".)
|
||||
// called 'window'.)
|
||||
window.global = Shell.Global.get();
|
||||
|
||||
// Now monkey patch utility functions into the global proxy;
|
||||
@ -62,7 +72,7 @@ function start() {
|
||||
global.logError = _logError;
|
||||
global.log = _logDebug;
|
||||
|
||||
Gio.DesktopAppInfo.set_desktop_env("GNOME");
|
||||
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
||||
|
||||
global.grab_dbus_service();
|
||||
shellDBusService = new ShellDBus.GnomeShell();
|
||||
@ -91,29 +101,35 @@ function start() {
|
||||
global.stage.color = DEFAULT_BACKGROUND_COLOR;
|
||||
|
||||
let themeContext = St.ThemeContext.get_for_stage (global.stage);
|
||||
let stylesheetPath = global.datadir + "/theme/gnome-shell.css";
|
||||
let stylesheetPath = global.datadir + '/theme/gnome-shell.css';
|
||||
let theme = new St.Theme ({ application_stylesheet: stylesheetPath });
|
||||
themeContext.set_theme (theme);
|
||||
|
||||
let shellwm = global.window_manager;
|
||||
shellwm.takeover_keybinding("panel_main_menu");
|
||||
shellwm.connect("keybinding::panel_main_menu", function () {
|
||||
shellwm.takeover_keybinding('panel_main_menu');
|
||||
shellwm.connect('keybinding::panel_main_menu', function () {
|
||||
overview.toggle();
|
||||
});
|
||||
shellwm.takeover_keybinding("panel_run_dialog");
|
||||
shellwm.connect("keybinding::panel_run_dialog", function () {
|
||||
shellwm.takeover_keybinding('panel_run_dialog');
|
||||
shellwm.connect('keybinding::panel_run_dialog', function () {
|
||||
getRunDialog().open();
|
||||
});
|
||||
|
||||
// Set up stage hierarchy to group all UI actors under one container.
|
||||
uiGroup = new Clutter.Group();
|
||||
global.window_group.reparent(uiGroup);
|
||||
global.overlay_group.reparent(uiGroup);
|
||||
global.stage.add_actor(uiGroup);
|
||||
|
||||
placesManager = new PlaceDisplay.PlacesManager();
|
||||
overview = new Overview.Overview();
|
||||
chrome = new Chrome.Chrome();
|
||||
panel = new Panel.Panel();
|
||||
sidebar = new Sidebar.Sidebar();
|
||||
wm = new WindowManager.WindowManager();
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
messageTray = new MessageTray.MessageTray();
|
||||
telepathyClient = new TelepathyClient.Client();
|
||||
|
||||
_startDate = new Date();
|
||||
|
||||
@ -127,9 +143,9 @@ function start() {
|
||||
} else {
|
||||
//read the parameters from GConf always in case they have changed
|
||||
let gconf = Shell.GConf.get_default();
|
||||
recorder.set_framerate(gconf.get_int("recorder/framerate"));
|
||||
recorder.set_filename("shell-%d%u-%c." + gconf.get_string("recorder/file_extension"));
|
||||
let pipeline = gconf.get_string("recorder/pipeline");
|
||||
recorder.set_framerate(gconf.get_int('recorder/framerate'));
|
||||
recorder.set_filename('shell-%d%u-%c.' + gconf.get_string('recorder/file_extension'));
|
||||
let pipeline = gconf.get_string('recorder/pipeline');
|
||||
if (!pipeline.match(/^\s*$/))
|
||||
recorder.set_pipeline(pipeline);
|
||||
else
|
||||
@ -155,10 +171,23 @@ function start() {
|
||||
|
||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
||||
|
||||
// Install magnifier.
|
||||
magnifier = new Magnifier.Magnifier();
|
||||
|
||||
// Perform initial relayout here
|
||||
_relayout();
|
||||
|
||||
_log('info', 'loaded at ' + _startDate);
|
||||
log('GNOME Shell started at ' + _startDate);
|
||||
|
||||
Mainloop.idle_add(_removeUnusedWorkspaces);
|
||||
|
||||
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
||||
if (perfModuleName) {
|
||||
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
|
||||
let module = eval('imports.perf.' + perfModuleName + ';');
|
||||
Scripting.runPerfScript(module, perfOutput);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,7 +208,7 @@ function _log(category, msg) {
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
text += JSON.stringify(arguments[i]);
|
||||
if (i < arguments.length - 1)
|
||||
text += " ";
|
||||
text += ' ';
|
||||
}
|
||||
}
|
||||
_errorLogStack.push({timestamp: new Date().getTime(),
|
||||
@ -268,8 +297,8 @@ function _globalKeyPressHandler(actor, event) {
|
||||
if (symbol == Clutter.Print) {
|
||||
// We want to be able to take screenshots of the shell at all times
|
||||
let gconf = Shell.GConf.get_default();
|
||||
let command = gconf.get_string("/apps/metacity/keybinding_commands/command_screenshot");
|
||||
if (command != null && command != "") {
|
||||
let command = gconf.get_string('/apps/metacity/keybinding_commands/command_screenshot');
|
||||
if (command != null && command != '') {
|
||||
let [ok, len, args] = GLib.shell_parse_argv(command);
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
@ -342,7 +371,7 @@ function _findModal(actor) {
|
||||
function pushModal(actor) {
|
||||
if (modalCount == 0) {
|
||||
if (!global.begin_modal(global.get_current_time())) {
|
||||
log("pushModal: invocation of begin_modal failed");
|
||||
log('pushModal: invocation of begin_modal failed');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -485,7 +514,7 @@ function _queueBeforeRedraw(workId) {
|
||||
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, function () {
|
||||
_runBeforeRedrawQueue();
|
||||
return false;
|
||||
}, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,7 +538,7 @@ function _queueBeforeRedraw(workId) {
|
||||
*/
|
||||
function initializeDeferredWork(actor, callback, props) {
|
||||
// Turn into a string so we can use as an object property
|
||||
let workId = "" + (++_deferredWorkSequence);
|
||||
let workId = '' + (++_deferredWorkSequence);
|
||||
_deferredWorkData[workId] = { 'actor': actor,
|
||||
'callback': callback };
|
||||
actor.connect('notify::mapped', function () {
|
||||
@ -539,7 +568,7 @@ function initializeDeferredWork(actor, callback, props) {
|
||||
function queueDeferredWork(workId) {
|
||||
let data = _deferredWorkData[workId];
|
||||
if (!data) {
|
||||
global.logError("invalid work id ", workId);
|
||||
global.logError('invalid work id ', workId);
|
||||
return;
|
||||
}
|
||||
if (_deferredWorkQueue.indexOf(workId) < 0)
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Pango = imports.gi.Pango;
|
||||
@ -15,7 +16,7 @@ const ANIMATION_TIME = 0.2;
|
||||
const NOTIFICATION_TIMEOUT = 4;
|
||||
const SUMMARY_TIMEOUT = 1;
|
||||
|
||||
const MESSAGE_TRAY_TIMEOUT = 0.2;
|
||||
const HIDE_TIMEOUT = 0.2;
|
||||
|
||||
const ICON_SIZE = 24;
|
||||
|
||||
@ -29,10 +30,10 @@ const State = {
|
||||
function _cleanMarkup(text) {
|
||||
// Support &, ", ', < and >, escape all other
|
||||
// occurrences of '&'.
|
||||
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, "&");
|
||||
let _text = text.replace(/&(?!amp;|quot;|apos;|lt;|gt;)/g, '&');
|
||||
// Support <b>, <i>, and <u>, escape anything else
|
||||
// so it displays as raw markup.
|
||||
return _text.replace(/<(\/?[^biu]>|[^>\/][^>])/g, "<$1");
|
||||
return _text.replace(/<(\/?[^biu]>|[^>\/][^>])/g, '<$1');
|
||||
}
|
||||
|
||||
// Notification:
|
||||
@ -46,11 +47,15 @@ function _cleanMarkup(text) {
|
||||
// @source's icon, @title (in bold) and @banner, all on a single line
|
||||
// (with @banner ellipsized if necessary).
|
||||
//
|
||||
// Additional notification details can be added via addBody(),
|
||||
// addAction(), and addActor(). If any of these are called, then the
|
||||
// notification will expand to show the additional actors (while
|
||||
// hiding the @banner) if the pointer is moved into it while it is
|
||||
// visible.
|
||||
// Additional notification details can be added, in which case the
|
||||
// notification can be expanded by moving the pointer into it. In
|
||||
// expanded mode, the banner text disappears, and there can be one or
|
||||
// more rows of additional content. This content is put inside a
|
||||
// scrollview, so if it gets too tall, the notification will scroll
|
||||
// rather than continuing to grow. In addition to this main content
|
||||
// area, there is also a single-row "action area", which is not
|
||||
// scrolled and can contain a single actor. There are also convenience
|
||||
// methods for creating a button box in the action area.
|
||||
//
|
||||
// If @bannerBody is %true, then @banner will also be used as the body
|
||||
// of the notification (as with addBody()) when the banner is expanded.
|
||||
@ -65,45 +70,52 @@ Notification.prototype = {
|
||||
this.id = id;
|
||||
this.source = source;
|
||||
this._bannerBody = bannerBody;
|
||||
this.urgent = false;
|
||||
|
||||
source.connect('clicked', Lang.bind(this,
|
||||
function() {
|
||||
this.emit('dismissed');
|
||||
}));
|
||||
|
||||
this.actor = new St.Table({ name: 'notification' });
|
||||
this.actor = new St.Table({ name: 'notification',
|
||||
reactive: true });
|
||||
this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
|
||||
this.update(title, banner, true);
|
||||
},
|
||||
|
||||
// update:
|
||||
// @title: the new title
|
||||
// @banner: the new banner
|
||||
// @clear: whether or not to clear out extra actors
|
||||
// @clear: whether or not to clear out body and action actors
|
||||
//
|
||||
// Updates the notification by regenerating its icon and updating
|
||||
// the title/banner. If @clear is %true, it will also remove any
|
||||
// additional actors/action buttons previously added.
|
||||
update: function(title, banner, clear) {
|
||||
let children = this.actor.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let meta = this.actor.get_child_meta(children[i]);
|
||||
if (clear || meta.row == 0 || (this._bannerBody && meta.row == 1))
|
||||
children[i].destroy();
|
||||
if (this._icon)
|
||||
this._icon.destroy();
|
||||
if (this._bannerBox)
|
||||
this._bannerBox.destroy();
|
||||
if (this._scrollArea && (this._bannerBody || clear)) {
|
||||
this._scrollArea.destroy();
|
||||
this._scrollArea = null;
|
||||
this._contentArea = null;
|
||||
}
|
||||
if (clear) {
|
||||
this.actions = {};
|
||||
this._actionBox = null;
|
||||
if (this._actionArea && clear) {
|
||||
this._actionArea.destroy();
|
||||
this._actionArea = null;
|
||||
this._buttonBox = null;
|
||||
}
|
||||
|
||||
let icon = this.source.createIcon(ICON_SIZE);
|
||||
icon.reactive = true;
|
||||
this.actor.add(icon, { row: 0,
|
||||
col: 0,
|
||||
x_expand: false,
|
||||
y_expand: false,
|
||||
y_fill: false });
|
||||
this._icon = this.source.createIcon(ICON_SIZE);
|
||||
this._icon.reactive = true;
|
||||
this.actor.add(this._icon, { row: 0,
|
||||
col: 0,
|
||||
x_expand: false,
|
||||
y_expand: false,
|
||||
y_fill: false });
|
||||
|
||||
icon.connect('button-release-event', Lang.bind(this,
|
||||
this._icon.connect('button-release-event', Lang.bind(this,
|
||||
function () {
|
||||
this.source.clicked();
|
||||
}));
|
||||
@ -136,67 +148,39 @@ Notification.prototype = {
|
||||
banner = banner ? _cleanMarkup(banner.replace(/\n/g, ' ')) : '';
|
||||
this._bannerLabel.clutter_text.set_markup(banner);
|
||||
this._bannerBox.add_actor(this._bannerLabel);
|
||||
|
||||
// Add the bannerBody now if we know for sure we'll need it
|
||||
if (this._bannerBodyText && this._bannerBodyText.indexOf('\n') > -1)
|
||||
this._addBannerBody();
|
||||
},
|
||||
|
||||
// addActor:
|
||||
// @actor: actor to add to the notification
|
||||
// @props: (optional) child properties
|
||||
// @actor: actor to add to the body of the notification
|
||||
//
|
||||
// Adds @actor to the notification's St.Table, using @props.
|
||||
//
|
||||
// If @props does not specify a %row, then @actor will be added
|
||||
// to the bottom of the notification (unless there are action
|
||||
// buttons present, in which case it will be added above them).
|
||||
//
|
||||
// If @props does not specify a %col, it will default to column 1.
|
||||
// (Normally only the icon is in column 0.)
|
||||
//
|
||||
// If @props specifies an already-occupied cell, then the existing
|
||||
// contents of the table will be shifted down to make room for it.
|
||||
addActor: function(actor, props) {
|
||||
if (!props)
|
||||
props = {};
|
||||
|
||||
if (!('col' in props))
|
||||
props.col = 1;
|
||||
|
||||
if ('row' in props) {
|
||||
let children = this.actor.get_children();
|
||||
let i, meta, collision = false;
|
||||
|
||||
for (i = 0; i < children.length; i++) {
|
||||
meta = this.actor.get_child_meta(children[i]);
|
||||
if (meta.row == props.row && meta.col == props.col) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
for (i = 0; i < children.length; i++) {
|
||||
meta = this.actor.get_child_meta(children[i]);
|
||||
if (meta.row >= props.row)
|
||||
meta.row++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this._actionBox) {
|
||||
props.row = this.actor.row_count - 1;
|
||||
this.actor.get_child_meta(this._actionBox).row++;
|
||||
} else {
|
||||
props.row = this.actor.row_count;
|
||||
}
|
||||
// Appends @actor to the notification's body
|
||||
addActor: function(actor) {
|
||||
if (!this._scrollArea) {
|
||||
this._scrollArea = new St.ScrollView({ name: 'notification-scrollview',
|
||||
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
||||
hscrollbar_policy: Gtk.PolicyType.NEVER,
|
||||
vshadows: true });
|
||||
this.actor.add(this._scrollArea, { row: 1,
|
||||
col: 1 });
|
||||
this._contentArea = new St.BoxLayout({ name: 'notification-body',
|
||||
vertical: true });
|
||||
this._scrollArea.add_actor(this._contentArea);
|
||||
}
|
||||
|
||||
this.actor.add(actor, props);
|
||||
this._contentArea.add(actor);
|
||||
},
|
||||
|
||||
// addBody:
|
||||
// @text: the text
|
||||
// @props: (optional) properties for addActor()
|
||||
//
|
||||
// Adds a multi-line label containing @text to the notification.
|
||||
addBody: function(text, props) {
|
||||
//
|
||||
// Return value: the newly-added label
|
||||
addBody: function(text) {
|
||||
let body = new St.Label();
|
||||
body.clutter_text.line_wrap = true;
|
||||
body.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
|
||||
@ -205,15 +189,56 @@ Notification.prototype = {
|
||||
text = text ? _cleanMarkup(text) : '';
|
||||
body.clutter_text.set_markup(text);
|
||||
|
||||
this.addActor(body, props);
|
||||
this.addActor(body);
|
||||
return body;
|
||||
},
|
||||
|
||||
_addBannerBody: function() {
|
||||
this.addBody(this._bannerBodyText, { row: 1 });
|
||||
this.addBody(this._bannerBodyText);
|
||||
this._bannerBodyText = null;
|
||||
},
|
||||
|
||||
// addAction:
|
||||
// scrollTo:
|
||||
// @side: St.Side.TOP or St.Side.BOTTOM
|
||||
//
|
||||
// Scrolls the content area (if scrollable) to the indicated edge
|
||||
scrollTo: function(side) {
|
||||
// Hack to force a relayout, since the caller probably
|
||||
// just added or removed something to scrollArea, and
|
||||
// the adjustment needs to reflect that.
|
||||
global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, 0, 0);
|
||||
|
||||
let adjustment = this._scrollArea.vscroll.adjustment;
|
||||
if (side == St.Side.TOP)
|
||||
adjustment.value = adjustment.lower;
|
||||
else if (side == St.Side.BOTTOM)
|
||||
adjustment.value = adjustment.upper;
|
||||
},
|
||||
|
||||
// setActionArea:
|
||||
// @actor: the actor
|
||||
// @props: (option) St.Table child properties
|
||||
//
|
||||
// Puts @actor into the action area of the notification, replacing
|
||||
// the previous contents
|
||||
setActionArea: function(actor, props) {
|
||||
if (this._actionArea) {
|
||||
this._actionArea.destroy();
|
||||
this._actionArea = null;
|
||||
if (this._buttonBox)
|
||||
this._buttonBox = null;
|
||||
}
|
||||
this._actionArea = actor;
|
||||
|
||||
if (!props)
|
||||
props = {};
|
||||
props.row = 2;
|
||||
props.col = 1;
|
||||
|
||||
this.actor.add(this._actionArea, props);
|
||||
},
|
||||
|
||||
// addButton:
|
||||
// @id: the action ID
|
||||
// @label: the label for the action's button
|
||||
//
|
||||
@ -223,31 +248,51 @@ Notification.prototype = {
|
||||
//
|
||||
// If the button is clicked, the notification will emit the
|
||||
// %action-invoked signal with @id as a parameter
|
||||
addAction: function(id, label) {
|
||||
if (!this._actionBox) {
|
||||
addButton: function(id, label) {
|
||||
if (!this._buttonBox) {
|
||||
if (this._bannerBodyText)
|
||||
this._addBannerBody();
|
||||
|
||||
let box = new St.BoxLayout({ name: 'notification-actions' });
|
||||
this.addActor(box, { x_expand: false,
|
||||
x_fill: false,
|
||||
x_align: St.Align.END });
|
||||
this._actionBox = box;
|
||||
this.setActionArea(box, { x_expand: false,
|
||||
x_fill: false,
|
||||
x_align: St.Align.END });
|
||||
this._buttonBox = box;
|
||||
}
|
||||
|
||||
let button = new St.Button({ style_class: 'notification-button',
|
||||
label: label });
|
||||
this._actionBox.add(button);
|
||||
this._buttonBox.add(button);
|
||||
button.connect('clicked', Lang.bind(this, function() { this.emit('action-invoked', id); }));
|
||||
},
|
||||
|
||||
setUrgent: function(urgent) {
|
||||
this.urgent = urgent;
|
||||
},
|
||||
|
||||
_styleChanged: function() {
|
||||
let [has_spacing, spacing] = this.actor.get_theme_node().get_length('spacing-columns', false);
|
||||
this._spacing = has_spacing ? spacing : 0;
|
||||
|
||||
// Figure out now (before allocation starts) whether or not we
|
||||
// need to be expandable, and add the expansion row if so
|
||||
if (this._bannerBodyText) {
|
||||
let [minBannerWidth, natBannerWidth] =
|
||||
this._bannerBox.get_preferred_width(-1);
|
||||
let [minNotificationWidth, natNotificationWidth] =
|
||||
this.actor.get_preferred_width(-1);
|
||||
|
||||
if (natBannerWidth > natNotificationWidth)
|
||||
this._addBannerBody();
|
||||
}
|
||||
},
|
||||
|
||||
_bannerBoxGetPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let [titleMin, titleNat] = this._titleLabel.get_preferred_width(forHeight);
|
||||
let [bannerMin, bannerNat] = this._bannerLabel.get_preferred_width(forHeight);
|
||||
let [has_spacing, spacing] = this.actor.get_theme_node().get_length('spacing-columns', false);
|
||||
|
||||
alloc.min_size = titleMin;
|
||||
alloc.natural_size = titleNat + (has_spacing ? spacing : 0) + bannerNat;
|
||||
alloc.natural_size = titleNat + this._spacing + bannerNat;
|
||||
},
|
||||
|
||||
_bannerBoxGetPreferredHeight: function(actor, forWidth, alloc) {
|
||||
@ -259,9 +304,6 @@ Notification.prototype = {
|
||||
let [titleMinW, titleNatW] = this._titleLabel.get_preferred_width(-1);
|
||||
let [titleMinH, titleNatH] = this._titleLabel.get_preferred_height(-1);
|
||||
let [bannerMinW, bannerNatW] = this._bannerLabel.get_preferred_width(-1);
|
||||
let [has_spacing, spacing] = this.actor.get_theme_node().get_length('spacing-columns', false);
|
||||
if (!has_spacing)
|
||||
spacing = 0;
|
||||
let availWidth = box.x2 - box.x1;
|
||||
|
||||
let titleBox = new Clutter.ActorBox();
|
||||
@ -270,26 +312,17 @@ Notification.prototype = {
|
||||
titleBox.y2 = titleNatH;
|
||||
this._titleLabel.allocate(titleBox, flags);
|
||||
|
||||
let overflow = false;
|
||||
if (titleBox.x2 + spacing > availWidth) {
|
||||
if (titleBox.x2 + this._spacing > availWidth) {
|
||||
this._bannerLabel.hide();
|
||||
overflow = true;
|
||||
} else {
|
||||
let bannerBox = new Clutter.ActorBox();
|
||||
bannerBox.x1 = titleBox.x2 + spacing;
|
||||
bannerBox.x1 = titleBox.x2 + this._spacing;
|
||||
bannerBox.y1 = 0;
|
||||
bannerBox.x2 = Math.min(bannerBox.x1 + bannerNatW, availWidth);
|
||||
bannerBox.y2 = titleNatH;
|
||||
this._bannerLabel.show();
|
||||
this._bannerLabel.allocate(bannerBox, flags);
|
||||
|
||||
if (bannerBox.x2 < bannerBox.x1 + bannerNatW)
|
||||
overflow = true;
|
||||
}
|
||||
|
||||
if (this._bannerBodyText &&
|
||||
(overflow || this._bannerBodyText.indexOf('\n') > -1))
|
||||
this._addBannerBody();
|
||||
},
|
||||
|
||||
popOut: function() {
|
||||
@ -299,7 +332,7 @@ Notification.prototype = {
|
||||
Tweener.addTween(this._bannerLabel,
|
||||
{ opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
transition: 'easeOutQuad' });
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -309,7 +342,7 @@ Notification.prototype = {
|
||||
Tweener.addTween(this._bannerLabel,
|
||||
{ opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
transition: 'easeOutQuad' });
|
||||
return true;
|
||||
},
|
||||
|
||||
@ -329,7 +362,6 @@ Source.prototype = {
|
||||
this.text = null;
|
||||
if (createIcon)
|
||||
this.createIcon = createIcon;
|
||||
this.handleReplacing = true;
|
||||
},
|
||||
|
||||
// This can be overridden by a subclass, or by the createIcon
|
||||
@ -339,6 +371,19 @@ Source.prototype = {
|
||||
},
|
||||
|
||||
notify: function(notification) {
|
||||
if (this.notification)
|
||||
this.notification.disconnect(this._notificationDestroyedId);
|
||||
|
||||
this.notification = notification;
|
||||
|
||||
this._notificationDestroyedId = notification.connect('destroy', Lang.bind(this,
|
||||
function () {
|
||||
if (this.notification == notification) {
|
||||
this.notification = null;
|
||||
this._notificationDestroyedId = 0;
|
||||
}
|
||||
}));
|
||||
|
||||
this.emit('notify', notification);
|
||||
},
|
||||
|
||||
@ -359,30 +404,35 @@ function MessageTray() {
|
||||
MessageTray.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new St.BoxLayout({ name: 'message-tray',
|
||||
reactive: true });
|
||||
reactive: true,
|
||||
track_hover: true });
|
||||
this.actor.connect('notify::hover', Lang.bind(this, this._onTrayHoverChanged));
|
||||
|
||||
this._notificationBin = new St.Bin({ reactive: true,
|
||||
x_align: St.Align.MIDDLE });
|
||||
this._notificationBin = new St.Bin();
|
||||
this.actor.add(this._notificationBin);
|
||||
this._notificationBin.hide();
|
||||
this._notificationQueue = [];
|
||||
this._notification = null;
|
||||
|
||||
this._summaryBin = new St.BoxLayout();
|
||||
this._summaryBin = new St.Bin({ anchor_gravity: Clutter.Gravity.NORTH_EAST });
|
||||
this.actor.add(this._summaryBin);
|
||||
this._summary = new St.BoxLayout({ name: 'summary-mode',
|
||||
reactive: true });
|
||||
this._summaryBin.add(this._summary, { x_align: St.Align.END,
|
||||
x_fill: false,
|
||||
expand: true });
|
||||
this._summary.connect('enter-event',
|
||||
Lang.bind(this, this._onSummaryEntered));
|
||||
this._summary.connect('leave-event',
|
||||
Lang.bind(this, this._onSummaryLeft));
|
||||
reactive: true,
|
||||
track_hover: true });
|
||||
this._summary.connect('notify::hover', Lang.bind(this, this._onSummaryHoverChanged));
|
||||
this._summaryBin.child = this._summary;
|
||||
this._summaryBin.opacity = 0;
|
||||
|
||||
this.actor.connect('enter-event', Lang.bind(this, this._onTrayEntered));
|
||||
this.actor.connect('leave-event', Lang.bind(this, this._onTrayLeft));
|
||||
this._summaryNotificationBin = new St.Bin({ name: 'summary-notification-bin',
|
||||
anchor_gravity: Clutter.Gravity.NORTH_EAST,
|
||||
reactive: true,
|
||||
track_hover: true });
|
||||
this.actor.add(this._summaryNotificationBin);
|
||||
this._summaryNotificationBin.lower_bottom();
|
||||
this._summaryNotificationBin.hide();
|
||||
this._summaryNotificationBin.connect('notify::hover', Lang.bind(this, this._onSummaryNotificationHoverChanged));
|
||||
this._summaryNotification = null;
|
||||
this._hoverSource = null;
|
||||
|
||||
this._trayState = State.HIDDEN;
|
||||
this._trayLeftTimeoutId = 0;
|
||||
@ -392,13 +442,15 @@ MessageTray.prototype = {
|
||||
this._pointerInSummary = false;
|
||||
this._notificationState = State.HIDDEN;
|
||||
this._notificationTimeoutId = 0;
|
||||
this._summaryNotificationState = State.HIDDEN;
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
this._overviewVisible = false;
|
||||
this._notificationRemoved = false;
|
||||
|
||||
this.actor.show();
|
||||
Main.chrome.addActor(this.actor, { affectsStruts: false,
|
||||
visibleInOverview: true });
|
||||
Main.chrome.trackActor(this._notificationBin, { affectsStruts: false });
|
||||
Main.chrome.trackActor(this._notificationBin);
|
||||
Main.chrome.trackActor(this._summaryNotificationBin);
|
||||
|
||||
global.connect('screen-size-changed',
|
||||
Lang.bind(this, this._setSizePosition));
|
||||
@ -424,9 +476,12 @@ MessageTray.prototype = {
|
||||
this.actor.x = primary.x;
|
||||
this.actor.y = primary.y + primary.height - 1;
|
||||
this.actor.width = primary.width;
|
||||
this._notificationBin.x = 0;
|
||||
this._notificationBin.width = primary.width;
|
||||
|
||||
this._notificationBin.x = this._summaryBin.x = 0;
|
||||
this._notificationBin.width = this._summaryBin.width = primary.width;
|
||||
// These work because of their anchor_gravity
|
||||
this._summaryBin.x = primary.width;
|
||||
this._summaryNotificationBin.x = primary.width;
|
||||
},
|
||||
|
||||
contains: function(source) {
|
||||
@ -439,7 +494,8 @@ MessageTray.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let iconBox = new St.Bin({ reactive: true });
|
||||
let iconBox = new St.Clickable({ style_class: 'summary-icon',
|
||||
reactive: true });
|
||||
iconBox.child = source.createIcon(ICON_SIZE);
|
||||
this._summary.insert_actor(iconBox, 0);
|
||||
this._summaryNeedsToBeShown = true;
|
||||
@ -448,7 +504,11 @@ MessageTray.prototype = {
|
||||
|
||||
source.connect('notify', Lang.bind(this, this._onNotify));
|
||||
|
||||
iconBox.connect('button-release-event', Lang.bind(this,
|
||||
iconBox.connect('notify::hover', Lang.bind(this,
|
||||
function () {
|
||||
this._onSourceHoverChanged(source, iconBox.hover);
|
||||
}));
|
||||
iconBox.connect('clicked', Lang.bind(this,
|
||||
function () {
|
||||
source.clicked();
|
||||
}));
|
||||
@ -479,14 +539,23 @@ MessageTray.prototype = {
|
||||
delete this._icons[source.id];
|
||||
delete this._sources[source.id];
|
||||
|
||||
let needUpdate = false;
|
||||
|
||||
if (this._notification && this._notification.source == source) {
|
||||
if (this._notificationTimeoutId) {
|
||||
Mainloop.source_remove(this._notificationTimeoutId);
|
||||
this._notificationTimeoutId = 0;
|
||||
}
|
||||
this._notificationRemoved = true;
|
||||
this._updateState();
|
||||
needUpdate = true;
|
||||
}
|
||||
if (this._hoverSource == source) {
|
||||
this._hoverSource = null;
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
if (needUpdate);
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
removeSourceByApp: function(app) {
|
||||
@ -527,42 +596,90 @@ MessageTray.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
lock: function() {
|
||||
this._locked = true;
|
||||
},
|
||||
|
||||
unlock: function() {
|
||||
this._locked = false;
|
||||
|
||||
this.actor.sync_hover();
|
||||
this._summary.sync_hover();
|
||||
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onNotify: function(source, notification) {
|
||||
if (!notification.source.handleReplacing || this._getNotification(notification.id, source) == null) {
|
||||
if (notification == this._summaryNotification)
|
||||
return;
|
||||
|
||||
if (this._getNotification(notification.id, source) == null) {
|
||||
notification.connect('destroy',
|
||||
Lang.bind(this, this.removeNotification));
|
||||
this._notificationQueue.push(notification);
|
||||
|
||||
if (notification.urgent)
|
||||
this._notificationQueue.unshift(notification);
|
||||
else
|
||||
this._notificationQueue.push(notification);
|
||||
}
|
||||
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onSummaryEntered: function() {
|
||||
this._pointerInSummary = true;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onSummaryLeft: function() {
|
||||
this._pointerInSummary = false;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onTrayEntered: function() {
|
||||
if (this._trayLeftTimeoutId) {
|
||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||
this._trayLeftTimeoutId = 0;
|
||||
_onSourceHoverChanged: function(source, hover) {
|
||||
if (!source.notification)
|
||||
return;
|
||||
|
||||
if (this._summaryNotificationTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._summaryNotificationTimeoutId);
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
}
|
||||
|
||||
this._pointerInTray = true;
|
||||
if (hover) {
|
||||
this._hoverSource = source;
|
||||
this._updateState();
|
||||
} else if (this._hoverSource == source) {
|
||||
let timeout = HIDE_TIMEOUT * 1000;
|
||||
this._summaryNotificationTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onSourceHoverChangedTimeout, source));
|
||||
}
|
||||
},
|
||||
|
||||
_onSourceHoverChangedTimeout: function(source) {
|
||||
this._summaryNotificationTimeoutId = 0;
|
||||
if (this._hoverSource == source) {
|
||||
this._hoverSource = null;
|
||||
this._updateState();
|
||||
}
|
||||
},
|
||||
|
||||
_onSummaryNotificationHoverChanged: function() {
|
||||
if (!this._summaryNotification)
|
||||
return;
|
||||
this._onSourceHoverChanged(this._summaryNotification.source,
|
||||
this._summaryNotificationBin.hover);
|
||||
},
|
||||
|
||||
_onSummaryHoverChanged: function() {
|
||||
this._pointerInSummary = this._summary.hover;
|
||||
this._updateState();
|
||||
},
|
||||
|
||||
_onTrayLeft: function() {
|
||||
// We wait just a little before hiding the message tray in case the
|
||||
// user quickly moves the mouse back into it.
|
||||
let timeout = MESSAGE_TRAY_TIMEOUT * 1000;
|
||||
this._trayLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onTrayLeftTimeout));
|
||||
_onTrayHoverChanged: function() {
|
||||
if (this.actor.hover) {
|
||||
if (this._trayLeftTimeoutId) {
|
||||
Mainloop.source_remove(this._trayLeftTimeoutId);
|
||||
this._trayLeftTimeoutId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this._pointerInTray = true;
|
||||
this._updateState();
|
||||
} else {
|
||||
// We wait just a little before hiding the message tray in case the
|
||||
// user quickly moves the mouse back into it.
|
||||
let timeout = HIDE_TIMEOUT * 1000;
|
||||
this._trayLeftTimeoutId = Mainloop.timeout_add(timeout, Lang.bind(this, this._onTrayLeftTimeout));
|
||||
}
|
||||
},
|
||||
|
||||
_onTrayLeftTimeout: function() {
|
||||
@ -575,7 +692,7 @@ MessageTray.prototype = {
|
||||
|
||||
// All of the logic for what happens when occurs here; the various
|
||||
// event handlers merely update variables such as
|
||||
// "this._pointerInTray", "this._summaryState", etc, and
|
||||
// 'this._pointerInTray', 'this._summaryState', etc, and
|
||||
// _updateState() figures out what (if anything) needs to be done
|
||||
// at the present time.
|
||||
_updateState: function() {
|
||||
@ -583,7 +700,7 @@ MessageTray.prototype = {
|
||||
let notificationsPending = this._notificationQueue.length > 0;
|
||||
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
|
||||
let notificationExpanded = this._notificationBin.y < 0;
|
||||
let notificationExpired = (this._notificationTimeoutId == 0 && !this._pointerInTray) || this._notificationRemoved;
|
||||
let notificationExpired = (this._notificationTimeoutId == 0 && !this._pointerInTray && !this._locked) || this._notificationRemoved;
|
||||
|
||||
if (this._notificationState == State.HIDDEN) {
|
||||
if (notificationsPending)
|
||||
@ -613,6 +730,22 @@ MessageTray.prototype = {
|
||||
this._hideSummary();
|
||||
}
|
||||
|
||||
// Summary notification
|
||||
let haveSummaryNotification = this._hoverSource != null;
|
||||
let summaryNotificationIsMainNotification = (haveSummaryNotification &&
|
||||
this._hoverSource.notification == this._notification);
|
||||
let canShowSummaryNotification = this._summaryState == State.SHOWN;
|
||||
let wrongSummaryNotification = (haveSummaryNotification &&
|
||||
this._summaryNotification != this._hoverSource.notification);
|
||||
|
||||
if (this._summaryNotificationState == State.HIDDEN) {
|
||||
if (haveSummaryNotification && !summaryNotificationIsMainNotification && canShowSummaryNotification)
|
||||
this._showSummaryNotification();
|
||||
} else if (this._summaryNotificationState == State.SHOWN) {
|
||||
if (!haveSummaryNotification || !canShowSummaryNotification || wrongSummaryNotification)
|
||||
this._hideSummaryNotification();
|
||||
}
|
||||
|
||||
// Tray itself
|
||||
let trayIsVisible = (this._trayState == State.SHOWING ||
|
||||
this._trayState == State.SHOWN);
|
||||
@ -649,19 +782,19 @@ MessageTray.prototype = {
|
||||
|
||||
_showTray: function() {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._tween(this.actor, "_trayState", State.SHOWN,
|
||||
this._tween(this.actor, '_trayState', State.SHOWN,
|
||||
{ y: primary.y + primary.height - this.actor.height,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
_hideTray: function() {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._tween(this.actor, "_trayState", State.HIDDEN,
|
||||
this._tween(this.actor, '_trayState', State.HIDDEN,
|
||||
{ y: primary.y + primary.height - 1,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
@ -673,14 +806,23 @@ MessageTray.prototype = {
|
||||
this._notificationBin.y = this.actor.height;
|
||||
this._notificationBin.show();
|
||||
|
||||
this._tween(this._notificationBin, "_notificationState", State.SHOWN,
|
||||
this._tween(this._notificationBin, '_notificationState', State.SHOWN,
|
||||
{ y: 0,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._showNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
|
||||
if (this._notification.urgent) {
|
||||
// This will overwrite the y tween, but leave the opacity
|
||||
// tween, and so the onComplete will remain as well.
|
||||
this._expandNotification();
|
||||
}
|
||||
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
this._lastSeenMouseY = y;
|
||||
},
|
||||
|
||||
_showNotificationCompleted: function() {
|
||||
@ -690,19 +832,37 @@ MessageTray.prototype = {
|
||||
},
|
||||
|
||||
_notificationTimeout: function() {
|
||||
this._notificationTimeoutId = 0;
|
||||
this._updateState();
|
||||
let [x, y, mods] = global.get_pointer();
|
||||
if (y > this._lastSeenMouseY + 10 && y < this.actor.y) {
|
||||
// The mouse is moving towards the notification, so don't
|
||||
// hide it yet. (We just create a new timeout (and destroy
|
||||
// the old one) each time because the bookkeeping is
|
||||
// simpler.)
|
||||
this._lastSeenMouseY = y;
|
||||
this._notificationTimeoutId =
|
||||
Mainloop.timeout_add(1000,
|
||||
Lang.bind(this, this._notificationTimeout));
|
||||
} else {
|
||||
this._notificationTimeoutId = 0;
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_hideNotification: function() {
|
||||
this._notification.popIn();
|
||||
|
||||
this._tween(this._notificationBin, "_notificationState", State.HIDDEN,
|
||||
if (this._reExpandNotificationId) {
|
||||
this._notificationBin.disconnect(this._reExpandNotificationId);
|
||||
this._reExpandNotificationId = 0;
|
||||
}
|
||||
|
||||
this._tween(this._notificationBin, '_notificationState', State.HIDDEN,
|
||||
{ y: this.actor.height,
|
||||
opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._hideNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
@ -717,11 +877,14 @@ MessageTray.prototype = {
|
||||
|
||||
_expandNotification: function() {
|
||||
if (this._notification && this._notification.popOut()) {
|
||||
this._tween(this._notificationBin, "_notificationState", State.SHOWN,
|
||||
this._tween(this._notificationBin, '_notificationState', State.SHOWN,
|
||||
{ y: this.actor.height - this._notificationBin.height,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
|
||||
if (!this._reExpandNotificationId)
|
||||
this._reExpandNotificationId = this._notificationBin.connect('notify::height', Lang.bind(this, this._expandNotification));
|
||||
}
|
||||
},
|
||||
|
||||
@ -729,11 +892,11 @@ MessageTray.prototype = {
|
||||
let primary = global.get_primary_monitor();
|
||||
this._summaryBin.opacity = 0;
|
||||
this._summaryBin.y = this.actor.height;
|
||||
this._tween(this._summaryBin, "_summaryState", State.SHOWN,
|
||||
this._tween(this._summaryBin, '_summaryState', State.SHOWN,
|
||||
{ y: 0,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._showSummaryCompleted,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [withTimeout]
|
||||
@ -757,11 +920,68 @@ MessageTray.prototype = {
|
||||
},
|
||||
|
||||
_hideSummary: function() {
|
||||
this._tween(this._summaryBin, "_summaryState", State.HIDDEN,
|
||||
this._tween(this._summaryBin, '_summaryState', State.HIDDEN,
|
||||
{ opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
this._summaryNeedsToBeShown = false;
|
||||
},
|
||||
|
||||
_showSummaryNotification: function() {
|
||||
this._summaryNotification = this._hoverSource.notification;
|
||||
|
||||
let index = this._notificationQueue.indexOf(this._summaryNotification);
|
||||
if (index != -1)
|
||||
this._notificationQueue.splice(index, 1);
|
||||
|
||||
this._summaryNotificationBin.child = this._summaryNotification.actor;
|
||||
this._summaryNotification.popOut();
|
||||
|
||||
this._summaryNotificationBin.opacity = 0;
|
||||
this._summaryNotificationBin.y = this.actor.height;
|
||||
this._summaryNotificationBin.show();
|
||||
|
||||
this._tween(this._summaryNotificationBin, '_summaryNotificationState', State.SHOWN,
|
||||
{ y: this.actor.height - this._summaryNotificationBin.height,
|
||||
opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
|
||||
if (!this._reExpandSummaryNotificationId)
|
||||
this._reExpandSummaryNotificationId = this._summaryNotificationBin.connect('notify::height', Lang.bind(this, this._reExpandSummaryNotification));
|
||||
},
|
||||
|
||||
_reExpandSummaryNotification: function() {
|
||||
this._tween(this._summaryNotificationBin, '_summaryNotificationState', State.SHOWN,
|
||||
{ y: this.actor.height - this._summaryNotificationBin.height,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
_hideSummaryNotification: function() {
|
||||
this._summaryNotification.popIn();
|
||||
|
||||
this._tween(this._summaryNotificationBin, '_summaryNotificationState', State.HIDDEN,
|
||||
{ y: this.actor.height,
|
||||
opacity: 0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._hideSummaryNotificationCompleted,
|
||||
onCompleteScope: this
|
||||
});
|
||||
|
||||
if (this._reExpandSummaryNotificationId) {
|
||||
this._summaryNotificationBin.disconnect(this._reExpandSummaryNotificationId);
|
||||
this._reExpandSummaryNotificationId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_hideSummaryNotificationCompleted: function() {
|
||||
this._summaryNotificationBin.hide();
|
||||
this._summaryNotificationBin.child = null;
|
||||
this._summaryNotification = null;
|
||||
}
|
||||
};
|
||||
|
@ -11,8 +11,6 @@ const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Params = imports.misc.params;
|
||||
|
||||
const EMPATHY = 'Empathy';
|
||||
|
||||
let nextNotificationId = 1;
|
||||
|
||||
// Should really be defined in dbus.js
|
||||
@ -123,10 +121,10 @@ NotificationDaemon.prototype = {
|
||||
// kill the notification-daemon. pkill is more portable
|
||||
// than killall, but on Linux at least it won't match if
|
||||
// you pass more than 15 characters of the process name...
|
||||
// However, if you use the "-f" flag to match the entire
|
||||
// However, if you use the '-f' flag to match the entire
|
||||
// command line, it will work, but we have to be careful
|
||||
// in that case that we don't match "gedit
|
||||
// notification-daemon.c" or whatever...
|
||||
// in that case that we don't match 'gedit
|
||||
// notification-daemon.c' or whatever...
|
||||
let p = new Shell.Process({ args: ['pkill', '-f',
|
||||
'^([^ ]*/)?(notification-daemon|notify-osd)$']});
|
||||
p.run();
|
||||
@ -139,46 +137,27 @@ NotificationDaemon.prototype = {
|
||||
|
||||
Notify: function(appName, replacesId, icon, summary, body,
|
||||
actions, hints, timeout) {
|
||||
let notification, id;
|
||||
// We associate each application with a source and set the source id to be based on
|
||||
// the appName. We support application updates by creating a new Notification object
|
||||
// only if replacesId was not specified or if we no longer have the notification with
|
||||
// the specified replacesId.
|
||||
//
|
||||
// We are planning to add Empathy-specific features in the message tray, but in the
|
||||
// meantime we handle Empathy notifications received through the notification daemon
|
||||
// differently from other notifications.
|
||||
// 1) We display different people sending messages as different sources. So we use
|
||||
// notification id instead of the appName when creating id for the source.
|
||||
// 2) We queue notification with different messages to show them one after another,
|
||||
// rather than replace the notification on the spot. So we create a new Notification
|
||||
// object each time, disregarding the fact that we might already have another
|
||||
// notification with the same replacesId.
|
||||
// Empathy uses replacesId for all the notifications from the same window until the
|
||||
// notification with that id is dismissed. Notifications from different people in
|
||||
// different tabs have the same replacesId. So while being closer to the eventual design,
|
||||
// our special-handling of Empathy notifications is somewhat buggy. The user might end up
|
||||
// with multiple icons for the same person if the user dismisses the window for that person
|
||||
// (which doesn't result in removing the icon) or the user might not get the icon for
|
||||
// the person after a new notification in one of the tabs of the chat window for which
|
||||
// another person's icon is already displayed.
|
||||
let source = Main.messageTray.getSource(this._sourceId(appName));
|
||||
let id = null;
|
||||
|
||||
let isEmpathy = appName == EMPATHY;
|
||||
if (replacesId != 0) {
|
||||
id = replacesId;
|
||||
if (!isEmpathy)
|
||||
notification = this._currentNotifications[id];
|
||||
} else {
|
||||
// Filter out notifications from Empathy, since we
|
||||
// handle that information from telepathyClient.js
|
||||
if (appName == 'Empathy') {
|
||||
id = nextNotificationId++;
|
||||
Mainloop.idle_add(Lang.bind(this,
|
||||
function () {
|
||||
this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
|
||||
}));
|
||||
return id;
|
||||
}
|
||||
|
||||
let sourceId = this._sourceId(isEmpathy ? id : appName);
|
||||
let source = Main.messageTray.getSource(sourceId);
|
||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||
|
||||
// Source may be null if we have never received a notification from
|
||||
// this app or if all notifications from this app have been acknowledged.
|
||||
// Source may be null if we have never received a notification
|
||||
// from this app or if all notifications from this app have
|
||||
// been acknowledged.
|
||||
if (source == null) {
|
||||
source = new Source(sourceId, icon, hints);
|
||||
source = new Source(this._sourceId(appName), icon, hints);
|
||||
Main.messageTray.add(source);
|
||||
|
||||
source.connect('clicked', Lang.bind(this,
|
||||
@ -190,7 +169,8 @@ NotificationDaemon.prototype = {
|
||||
let busProxy = new Bus();
|
||||
busProxy.GetConnectionUnixProcessIDRemote(sender, function (result, excp) {
|
||||
let app = Shell.WindowTracker.get_default().get_app_from_pid(result);
|
||||
source.setApp(app);
|
||||
if (app)
|
||||
source.setApp(app);
|
||||
});
|
||||
} else {
|
||||
source.update(icon, hints);
|
||||
@ -207,14 +187,15 @@ NotificationDaemon.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
let notification;
|
||||
if (replacesId != 0) {
|
||||
id = replacesId;
|
||||
notification = this._currentNotifications[id];
|
||||
}
|
||||
|
||||
if (notification == null) {
|
||||
id = nextNotificationId++;
|
||||
notification = new MessageTray.Notification(id, source, summary, body, true);
|
||||
// This will result in us keeping only the latest Empathy notification with the given
|
||||
// id in this._currentNotifications, which will only affect not being able to close all
|
||||
// the Empathy notifications with a given id in CloseNotification(). Since this not a
|
||||
// a likely scenario and this special-casing of Empathy in the notification daemon is
|
||||
// temporary, it doesn't seem worthwhile to change this._currentNotifications to
|
||||
// {id, [array of notifications]} just for that case.
|
||||
this._currentNotifications[id] = notification;
|
||||
notification.connect('dismissed', Lang.bind(this,
|
||||
function(n) {
|
||||
@ -229,10 +210,12 @@ NotificationDaemon.prototype = {
|
||||
|
||||
if (actions.length) {
|
||||
for (let i = 0; i < actions.length - 1; i += 2)
|
||||
notification.addAction(actions[i], actions[i + 1]);
|
||||
notification.addButton(actions[i], actions[i + 1]);
|
||||
notification.connect('action-invoked', Lang.bind(this, this._actionInvoked, source, id));
|
||||
}
|
||||
|
||||
notification.setUrgent(hints.urgency == Urgency.CRITICAL);
|
||||
|
||||
source.notify(notification);
|
||||
return id;
|
||||
},
|
||||
@ -268,7 +251,8 @@ NotificationDaemon.prototype = {
|
||||
|
||||
_onFocusAppChanged: function() {
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
Main.messageTray.removeSourceByApp(tracker.focus_app);
|
||||
if (tracker.focus_app)
|
||||
Main.messageTray.removeSourceByApp(tracker.focus_app);
|
||||
},
|
||||
|
||||
_actionInvoked: function(notification, action, source, id) {
|
||||
@ -311,8 +295,6 @@ Source.prototype = {
|
||||
},
|
||||
|
||||
update: function(icon, hints) {
|
||||
hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
|
||||
|
||||
this._icon = icon;
|
||||
this._iconData = hints.icon_data;
|
||||
this._urgency = hints.urgency;
|
||||
@ -358,9 +340,6 @@ Source.prototype = {
|
||||
this.app = app;
|
||||
if (this._openAppRequested)
|
||||
this.openApp();
|
||||
|
||||
if (app.get_name() == EMPATHY)
|
||||
this.handleReplacing = false;
|
||||
},
|
||||
|
||||
openApp: function() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
@ -73,7 +72,7 @@ const SHADOW_WIDTH = 6;
|
||||
|
||||
const NUMBER_OF_SECTIONS_IN_SEARCH = 2;
|
||||
|
||||
const INFO_BAR_HIDE_TIMEOUT = 30;
|
||||
const INFO_BAR_HIDE_TIMEOUT = 10;
|
||||
|
||||
let wideScreen = false;
|
||||
let displayGridColumnWidth = null;
|
||||
@ -108,9 +107,6 @@ InfoBar.prototype = {
|
||||
|
||||
this._undoCallback = null;
|
||||
this._undo.connect('clicked', Lang.bind(this, this._onUndoClicked));
|
||||
|
||||
this._overviewWasHidden = false;
|
||||
this._hidingOverviewId = 0;
|
||||
},
|
||||
|
||||
_onUndoClicked: function() {
|
||||
@ -128,7 +124,6 @@ InfoBar.prototype = {
|
||||
},
|
||||
|
||||
_hide: function() {
|
||||
this._overviewWasHidden = false;
|
||||
Tweener.addTween(this.actor,
|
||||
{ opacity: 0,
|
||||
transition: 'easeOutQuad',
|
||||
@ -140,31 +135,15 @@ InfoBar.prototype = {
|
||||
|
||||
_onTimeout: function() {
|
||||
this._timeoutId = 0;
|
||||
if (this._overviewWasHidden)
|
||||
this._hide();
|
||||
this._hide();
|
||||
return false;
|
||||
},
|
||||
|
||||
_onOverviewHiding: function() {
|
||||
if (this._timeoutId == 0)
|
||||
this._hide();
|
||||
else
|
||||
this._overviewWasHidden = true;
|
||||
},
|
||||
|
||||
setMessage: function(text, undoCallback, undoLabel) {
|
||||
if (this._timeoutId)
|
||||
Mainloop.source_remove(this._timeoutId);
|
||||
|
||||
if (this._hidingOverviewId == 0) {
|
||||
// Set here, because when constructor is called, overview is null.
|
||||
if (!Main.overview)
|
||||
return;
|
||||
// We don't actually use the ID, it's just a way of tracking whether we've hooked up the signal
|
||||
this._hidingOverviewId = Main.overview.connect('hiding', Lang.bind(this, this._onOverviewHiding));
|
||||
}
|
||||
this._timeout = false;
|
||||
this._overviewWasHidden = false;
|
||||
|
||||
this._label.text = text;
|
||||
|
||||
@ -251,19 +230,19 @@ Overview.prototype = {
|
||||
|
||||
this._coverPane.lower_bottom();
|
||||
|
||||
this._workspaces = null;
|
||||
this.workspaces = null;
|
||||
},
|
||||
|
||||
_onViewChanged: function() {
|
||||
if (!this.visible)
|
||||
return;
|
||||
|
||||
this._workspaces = this._workspacesManager.workspacesView;
|
||||
this.workspaces = this._workspacesManager.workspacesView;
|
||||
|
||||
// Show new workspacesView
|
||||
this._group.add_actor(this._workspaces.actor);
|
||||
this._workspacesBar.raise(this._workspaces.actor);
|
||||
this._dash.actor.raise(this._workspaces.actor);
|
||||
this._group.add_actor(this.workspaces.actor);
|
||||
this._workspacesBar.raise(this.workspaces.actor);
|
||||
this._dash.actor.raise(this.workspaces.actor);
|
||||
},
|
||||
|
||||
_recalculateGridSizes: function () {
|
||||
@ -382,7 +361,7 @@ Overview.prototype = {
|
||||
this._activeDisplayPane.close();
|
||||
return true;
|
||||
}));
|
||||
this._workspaces.actor.opacity = 64;
|
||||
this.workspaces.actor.opacity = 64;
|
||||
} else if (pane == this._activeDisplayPane) {
|
||||
this._activeDisplayPane = null;
|
||||
if (backgroundEventId != null) {
|
||||
@ -391,7 +370,7 @@ Overview.prototype = {
|
||||
}
|
||||
this._transparentBackground.lower_bottom();
|
||||
this._paneContainer.hide();
|
||||
this._workspaces.actor.opacity = 255;
|
||||
this.workspaces.actor.opacity = 255;
|
||||
}
|
||||
}));
|
||||
},
|
||||
@ -417,13 +396,13 @@ Overview.prototype = {
|
||||
// Returns the scale the Overview has when we just start zooming out
|
||||
// to overview mode. That is, when just the active workspace is showing.
|
||||
getZoomedInScale : function() {
|
||||
return 1 / this._workspaces.getScale();
|
||||
return 1 / this.workspaces.getScale();
|
||||
},
|
||||
|
||||
// Returns the position the Overview has when we just start zooming out
|
||||
// to overview mode. That is, when just the active workspace is showing.
|
||||
getZoomedInPosition : function() {
|
||||
let [posX, posY] = this._workspaces.getActiveWorkspacePosition();
|
||||
let [posX, posY] = this.workspaces.getActiveWorkspacePosition();
|
||||
let scale = this.getZoomedInScale();
|
||||
|
||||
return [- posX * scale, - posY * scale];
|
||||
@ -458,13 +437,13 @@ Overview.prototype = {
|
||||
this._workspacesY);
|
||||
this._workspacesManager.connect('view-changed',
|
||||
Lang.bind(this, this._onViewChanged));
|
||||
this._workspaces = this._workspacesManager.workspacesView;
|
||||
this._group.add_actor(this._workspaces.actor);
|
||||
this.workspaces = this._workspacesManager.workspacesView;
|
||||
this._group.add_actor(this.workspaces.actor);
|
||||
|
||||
// The workspaces actor is as big as the screen, so we have to raise the dash above it
|
||||
// for drag and drop to work. In the future we should fix the workspaces to not
|
||||
// be as big as the screen.
|
||||
this._dash.actor.raise(this._workspaces.actor);
|
||||
this._dash.actor.raise(this.workspaces.actor);
|
||||
|
||||
this._workspacesBar = this._workspacesManager.controlsBar.actor;
|
||||
this._workspacesBar.set_position(this._workspacesBarX,
|
||||
@ -472,7 +451,7 @@ Overview.prototype = {
|
||||
this._workspacesBar.width = this._workspacesBarWidth;
|
||||
|
||||
this._group.add_actor(this._workspacesBar);
|
||||
this._workspacesBar.raise(this._workspaces.actor);
|
||||
this._workspacesBar.raise(this.workspaces.actor);
|
||||
|
||||
// All the the actors in the window group are completely obscured,
|
||||
// hiding the group holding them while the Overview is displayed greatly
|
||||
@ -522,7 +501,7 @@ Overview.prototype = {
|
||||
this._hideInProgress = true;
|
||||
if (this._activeDisplayPane != null)
|
||||
this._activeDisplayPane.close();
|
||||
this._workspaces.hide();
|
||||
this.workspaces.hide();
|
||||
|
||||
// Create a zoom in effect by transforming the Overview group so that
|
||||
// the active workspace fills up the whole screen. The opposite
|
||||
@ -567,7 +546,7 @@ Overview.prototype = {
|
||||
* and will return %null.
|
||||
*/
|
||||
getWorkspacesForWindow: function(metaWindow) {
|
||||
return this._workspaces;
|
||||
return this.workspaces;
|
||||
},
|
||||
|
||||
//// Private methods ////
|
||||
@ -585,8 +564,8 @@ Overview.prototype = {
|
||||
_hideDone: function() {
|
||||
global.window_group.show();
|
||||
|
||||
this._workspaces.destroy();
|
||||
this._workspaces = null;
|
||||
this.workspaces.destroy();
|
||||
this.workspaces = null;
|
||||
|
||||
this._workspacesBar.destroy();
|
||||
this._workspacesBar = null;
|
||||
|
859
js/ui/panel.js
859
js/ui/panel.js
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Pango = imports.gi.Pango;
|
||||
const GLib = imports.gi.GLib;
|
||||
@ -72,7 +71,7 @@ PlaceDeviceInfo.prototype = {
|
||||
this._mount = mount;
|
||||
this.name = mount.get_name();
|
||||
this._lowerName = this.name.toLowerCase();
|
||||
this.id = "mount:" + mount.get_root().get_uri();
|
||||
this.id = 'mount:' + mount.get_root().get_uri();
|
||||
},
|
||||
|
||||
iconFactory: function(size) {
|
||||
@ -93,12 +92,18 @@ PlaceDeviceInfo.prototype = {
|
||||
if (!this.isRemovable())
|
||||
return;
|
||||
|
||||
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish));
|
||||
if (this._mount.can_eject())
|
||||
this._mount.eject(0, null, Lang.bind(this, this._removeFinish));
|
||||
else
|
||||
this._mount.unmount(0, null, Lang.bind(this, this._removeFinish));
|
||||
},
|
||||
|
||||
_removeFinish: function(o, res, data) {
|
||||
try {
|
||||
this._mount.unmount_finish(res);
|
||||
if (this._mount.can_eject())
|
||||
this._mount.eject_finish(res);
|
||||
else
|
||||
this._mount.unmount_finish(res);
|
||||
} catch (e) {
|
||||
let message = _("Failed to unmount '%s'").format(o.get_name());
|
||||
Main.overview.infoBar.setMessage(message,
|
||||
@ -150,7 +155,7 @@ PlacesManager.prototype = {
|
||||
|
||||
this._connect = new PlaceInfo('special:connect', _("Connect to..."),
|
||||
function (size) {
|
||||
return St.TextureCache.get_default().load_icon_name("applications-internet", size);
|
||||
return St.TextureCache.get_default().load_icon_name('applications-internet', size);
|
||||
},
|
||||
function () {
|
||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||
@ -163,7 +168,7 @@ PlacesManager.prototype = {
|
||||
try {
|
||||
networkApp = Shell.AppSystem.get_default().load_from_desktop_file('network-scheme.desktop');
|
||||
} catch(e) {
|
||||
log("Cannot create \"Network\" item, .desktop file not found or corrupt.");
|
||||
log('Cannot create "Network" item, .desktop file not found or corrupt.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,7 +208,7 @@ PlacesManager.prototype = {
|
||||
this._volumeMonitor.connect('drive-changed', Lang.bind(this, this._updateDevices));
|
||||
this._updateDevices();
|
||||
|
||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), ".gtk-bookmarks"]);
|
||||
this._bookmarksPath = GLib.build_filenamev([GLib.get_home_dir(), '.gtk-bookmarks']);
|
||||
this._bookmarksFile = Gio.file_new_for_path(this._bookmarksPath);
|
||||
let monitor = this._bookmarksFile.monitor_file(Gio.FileMonitorFlags.NONE, null);
|
||||
this._bookmarkTimeoutId = 0;
|
||||
@ -335,7 +340,7 @@ PlacesManager.prototype = {
|
||||
this._isDesktopHome = gconf.get_boolean(DESKTOP_IS_HOME_KEY);
|
||||
|
||||
if (this._isDesktopHome)
|
||||
this._removeById(this._defaultPlaces, "special:desktop");
|
||||
this._removeById(this._defaultPlaces, 'special:desktop');
|
||||
else
|
||||
this._defaultPlaces.splice(this._desktopMenuIndex, 0,
|
||||
this._desktopMenu);
|
||||
@ -435,18 +440,9 @@ DashPlaceDisplayItem.prototype = {
|
||||
}
|
||||
|
||||
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
||||
this.actor.connect('notify::hover',
|
||||
Lang.bind(this, this._onHoverChanged));
|
||||
this.actor.connect('button-press-event',
|
||||
Lang.bind(this, this._onButtonPress));
|
||||
this.actor.connect('button-release-event',
|
||||
Lang.bind(this, this._onButtonRelease));
|
||||
|
||||
this.actor._delegate = this;
|
||||
this._dragStartX = null;
|
||||
this._dragStartY = null;
|
||||
this._draggable = DND.makeDraggable(this.actor,
|
||||
{ manualMode: true });
|
||||
this._draggable = DND.makeDraggable(this.actor);
|
||||
},
|
||||
|
||||
_onClicked: function(b) {
|
||||
@ -454,36 +450,6 @@ DashPlaceDisplayItem.prototype = {
|
||||
Main.overview.hide();
|
||||
},
|
||||
|
||||
_onButtonPress: function(actor, event) {
|
||||
if (event.get_button() != 1)
|
||||
return false;
|
||||
|
||||
let [stageX, stageY] = event.get_coords();
|
||||
this._dragStartX = stageX;
|
||||
this._dragStartY = stageY;
|
||||
return false;
|
||||
},
|
||||
|
||||
_onButtonRelease: function(actor, event) {
|
||||
if (event.get_button() != 1)
|
||||
return false;
|
||||
|
||||
this._dragStartX = null;
|
||||
this._dragStartY = null;
|
||||
return false;
|
||||
},
|
||||
|
||||
_onHoverChanged: function(button) {
|
||||
let hover = button.hover;
|
||||
if (!hover) {
|
||||
if (button.pressed && this._dragStartX != null) {
|
||||
button.fake_release();
|
||||
this._draggable.startDrag(this._dragStartX, this._dragStartY,
|
||||
global.get_current_time());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._icon;
|
||||
},
|
||||
@ -510,28 +476,12 @@ DashPlaceDisplay.prototype = {
|
||||
// look better in that there would be an even number of items left+right,
|
||||
// but it seems like we want some sort of differentiation between actions
|
||||
// like "Connect to server..." and regular folders
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4 });
|
||||
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.actor.append(this._leftBox, Big.BoxPackFlags.EXPAND);
|
||||
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL });
|
||||
this.actor.append(this._rightBox, Big.BoxPackFlags.EXPAND);
|
||||
this.actor = new St.Table({ style_class: 'places-section',
|
||||
homogeneous: true });
|
||||
|
||||
// Subdivide left into actions and devices
|
||||
this._actionsBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
vertical: true });
|
||||
|
||||
this._devBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
name: 'placesDevices',
|
||||
vertical: true });
|
||||
|
||||
this._dirsBox = new St.BoxLayout({ style_class: 'places-actions',
|
||||
vertical: true });
|
||||
|
||||
this._leftBox.append(this._actionsBox, Big.BoxPackFlags.NONE);
|
||||
this._leftBox.append(this._devBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._rightBox.append(this._dirsBox, Big.BoxPackFlags.NONE);
|
||||
this._defaultsList = [];
|
||||
this._bookmarksList = [];
|
||||
this._mountsList = [];
|
||||
|
||||
Main.placesManager.connect('defaults-updated', Lang.bind(this, this._updateDefaults));
|
||||
Main.placesManager.connect('bookmarks-updated', Lang.bind(this, this._updateBookmarks));
|
||||
@ -543,27 +493,40 @@ DashPlaceDisplay.prototype = {
|
||||
},
|
||||
|
||||
_updateDefaults: function() {
|
||||
this._actionsBox.destroy_children();
|
||||
for (let i = 0; i < this._defaultsList.length; i++)
|
||||
this._defaultsList[i].destroy();
|
||||
|
||||
this._defaultsList = [];
|
||||
let places = Main.placesManager.getDefaultPlaces();
|
||||
for (let i = 0; i < places.length; i++)
|
||||
this._actionsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
for (let i = 0; i < places.length; i++) {
|
||||
this._defaultsList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||
this.actor.add(this._defaultsList[i], {row: i, col: 0});
|
||||
}
|
||||
this._updateMounts();
|
||||
},
|
||||
|
||||
_updateMounts: function() {
|
||||
this._devBox.destroy_children();
|
||||
for (let i = 0; i < this._mountsList.length; i++)
|
||||
this._mountsList[i].destroy();
|
||||
|
||||
this._mountsList = [];
|
||||
let places = Main.placesManager.getMounts();
|
||||
for (let i = 0; i < places.length; i++)
|
||||
this._devBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
for (let i = 0; i < places.length; i++) {
|
||||
this._mountsList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||
this.actor.add(this._mountsList[i], {row: this._defaultsList.length + i, col: 0});
|
||||
}
|
||||
},
|
||||
|
||||
_updateBookmarks: function() {
|
||||
this._dirsBox.destroy_children();
|
||||
for (let i = 0; i < this._bookmarksList.length; i++)
|
||||
this._bookmarksList[i].destroy();
|
||||
|
||||
this._bookmarksList = [];
|
||||
let places = Main.placesManager.getBookmarks();
|
||||
for (let i = 0; i < places.length; i ++)
|
||||
this._dirsBox.add(new DashPlaceDisplayItem(places[i]).actor);
|
||||
for (let i = 0; i < places.length; i ++) {
|
||||
this._bookmarksList[i] = new DashPlaceDisplayItem(places[i]).actor;
|
||||
this.actor.add(this._bookmarksList[i], {row: i, col: 1});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
@ -52,7 +51,7 @@ CommandCompleter.prototype = {
|
||||
this._paths[i] = file.get_path();
|
||||
this._monitors[i] = file.monitor_directory(Gio.FileMonitorFlags.NONE, null);
|
||||
if (this._monitors[i] != null) {
|
||||
this._monitors[i].connect("changed", Lang.bind(this, this._onChanged));
|
||||
this._monitors[i].connect('changed', Lang.bind(this, this._onChanged));
|
||||
}
|
||||
}
|
||||
this._paths = this._paths.filter(function(a) {
|
||||
@ -133,7 +132,7 @@ CommandCompleter.prototype = {
|
||||
},
|
||||
|
||||
getCompletion: function(text) {
|
||||
let common = "";
|
||||
let common = '';
|
||||
let notInit = true;
|
||||
if (!this._valid) {
|
||||
this._update(0);
|
||||
@ -146,7 +145,7 @@ CommandCompleter.prototype = {
|
||||
break;
|
||||
}
|
||||
if (k == 0)
|
||||
return "";
|
||||
return '';
|
||||
return s1.substr(0, k);
|
||||
}
|
||||
function _hasPrefix(s1, prefix) {
|
||||
@ -214,7 +213,7 @@ RunDialog.prototype = {
|
||||
// hidden then show it in show()
|
||||
this._group = new Clutter.Group({ visible: false,
|
||||
x: 0, y: 0 });
|
||||
global.stage.add_actor(this._group);
|
||||
Main.uiGroup.add_actor(this._group);
|
||||
|
||||
let lightbox = new Lightbox.Lightbox(this._group, true);
|
||||
|
||||
@ -268,8 +267,8 @@ RunDialog.prototype = {
|
||||
this._setCommandFromHistory(this._historyIndex--);
|
||||
return true;
|
||||
}
|
||||
if (symbol == Clutter.Return) {
|
||||
if (e.get_state() & Clutter.ModifierType.CONTROL_MASK)
|
||||
if (symbol == Clutter.Return || symbol == Clutter.KP_Enter) {
|
||||
if (Shell.get_event_state(e) & Clutter.ModifierType.CONTROL_MASK)
|
||||
this._run(o.get_text(), true);
|
||||
else
|
||||
this._run(o.get_text(), false);
|
||||
@ -330,8 +329,10 @@ RunDialog.prototype = {
|
||||
_run : function(input, inTerminal) {
|
||||
let command = input;
|
||||
|
||||
this._history.push(input);
|
||||
this._saveHistory();
|
||||
if (this._history.length > 0 && this._history[this._history.length - 1] != input) {
|
||||
this._history.push(input);
|
||||
this._saveHistory();
|
||||
}
|
||||
|
||||
this._commandError = false;
|
||||
let f;
|
||||
@ -371,7 +372,7 @@ RunDialog.prototype = {
|
||||
// We are only interested in the actual error, so parse
|
||||
//that out.
|
||||
let m = /.+\((.+)\)/.exec(e);
|
||||
let errorStr = _("Execution of '%s' failed:").format(command) + "\n" + m[1];
|
||||
let errorStr = _("Execution of '%s' failed:").format(command) + '\n' + m[1];
|
||||
this._errorMessage.set_text(errorStr);
|
||||
|
||||
this._errorBox.show();
|
||||
|
261
js/ui/scripting.js
Normal file
261
js/ui/scripting.js
Normal file
@ -0,0 +1,261 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
// This module provides functionality for driving the shell user interface
|
||||
// in an automated fashion. The primary current use case for this is
|
||||
// automated performance testing (see runPerfScript()), but it could
|
||||
// be applied to other forms of automation, such as testing for
|
||||
// correctness as well.
|
||||
//
|
||||
// When scripting an automated test we want to make a series of calls
|
||||
// in a linear fashion, but we also want to be able to let the main
|
||||
// loop run so actions can finish. For this reason we write the script
|
||||
// as a generator function that yields when it want to let the main
|
||||
// loop run.
|
||||
//
|
||||
// yield Scripting.sleep(1000);
|
||||
// main.overview.show();
|
||||
// yield Scripting.waitLeisure();
|
||||
//
|
||||
// While it isn't important to the person writing the script, the actual
|
||||
// yielded result is a function that the caller uses to provide the
|
||||
// callback for resuming the script.
|
||||
|
||||
/**
|
||||
* sleep:
|
||||
* @milliseconds: number of milliseconds to wait
|
||||
*
|
||||
* Used within an automation script to pause the the execution of the
|
||||
* current script for the specified amount of time. Use as
|
||||
* 'yield Scripting.sleep(500);'
|
||||
*/
|
||||
function sleep(milliseconds) {
|
||||
let cb;
|
||||
|
||||
Mainloop.timeout_add(milliseconds, function() {
|
||||
if (cb)
|
||||
cb();
|
||||
return false;
|
||||
});
|
||||
|
||||
return function(callback) {
|
||||
cb = callback;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* waitLeisure:
|
||||
*
|
||||
* Used within an automation script to pause the the execution of the
|
||||
* current script until the shell is completely idle. Use as
|
||||
* 'yield Scripting.waitLeisure();'
|
||||
*/
|
||||
function waitLeisure() {
|
||||
let cb;
|
||||
|
||||
global.run_at_leisure(function() {
|
||||
if (cb)
|
||||
cb();
|
||||
});
|
||||
|
||||
return function(callback) {
|
||||
cb = callback;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* defineScriptEvent
|
||||
* @name: The event will be called script.<name>
|
||||
* @description: Short human-readable description of the event
|
||||
*
|
||||
* Convenience function to define a zero-argument performance event
|
||||
* within the 'script' namespace that is reserved for events defined locally
|
||||
* within a performance automation script
|
||||
*/
|
||||
function defineScriptEvent(name, description) {
|
||||
Shell.PerfLog.get_default().define_event("script." + name,
|
||||
description,
|
||||
"");
|
||||
}
|
||||
|
||||
/**
|
||||
* scriptEvent
|
||||
* @name: Name registered with defineScriptEvent()
|
||||
*
|
||||
* Convenience function to record a script-local performance event
|
||||
* previously defined with defineScriptEvent
|
||||
*/
|
||||
function scriptEvent(name) {
|
||||
Shell.PerfLog.get_default().event("script." + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* collectStatistics
|
||||
*
|
||||
* Convenience function to trigger statistics collection
|
||||
*/
|
||||
function collectStatistics() {
|
||||
Shell.PerfLog.get_default().collect_statistics();
|
||||
}
|
||||
|
||||
function _step(g, finish, onError) {
|
||||
try {
|
||||
let waitFunction = g.next();
|
||||
waitFunction(function() {
|
||||
_step(g, finish, onError);
|
||||
});
|
||||
} catch (err if err instanceof StopIteration) {
|
||||
if (finish)
|
||||
finish();
|
||||
} catch (err) {
|
||||
if (onError)
|
||||
onError(err);
|
||||
}
|
||||
}
|
||||
|
||||
function _collect(scriptModule, outputFile) {
|
||||
let eventHandlers = {};
|
||||
|
||||
for (let f in scriptModule) {
|
||||
let m = /([A-Za-z]+)_([A-Za-z]+)/.exec(f);
|
||||
if (m)
|
||||
eventHandlers[m[1] + "." + m[2]] = scriptModule[f];
|
||||
}
|
||||
|
||||
Shell.PerfLog.get_default().replay(
|
||||
function(time, eventName, signature, arg) {
|
||||
if (eventName in eventHandlers)
|
||||
eventHandlers[eventName](time, arg);
|
||||
});
|
||||
|
||||
if ('finish' in scriptModule)
|
||||
scriptModule.finish();
|
||||
|
||||
if (outputFile) {
|
||||
let f = Gio.file_new_for_path(outputFile);
|
||||
let raw = f.replace(null, false,
|
||||
Gio.FileCreateFlags.NONE,
|
||||
null);
|
||||
let out = Gio.BufferedOutputStream.new_sized (raw, 4096);
|
||||
Shell.write_string_to_stream (out, "{\n");
|
||||
|
||||
Shell.write_string_to_stream(out, '"events":\n');
|
||||
Shell.PerfLog.get_default().dump_events(out);
|
||||
|
||||
let monitors = global.get_monitors()
|
||||
let primary = global.get_primary_monitor()
|
||||
Shell.write_string_to_stream(out, ',\n"monitors":\n[');
|
||||
for (let i = 0; i < monitors.length; i++) {
|
||||
let monitor = monitors[i];
|
||||
let is_primary = (monitor.x == primary.x &&
|
||||
monitor.y == primary.y &&
|
||||
monitor.width == primary.width &&
|
||||
monitor.height == primary.height);
|
||||
if (i != 0)
|
||||
Shell.write_string_to_stream(out, ', ');
|
||||
Shell.write_string_to_stream(out, '"%s%dx%d+%d+%d"'.format(is_primary ? "*" : "",
|
||||
monitor.width, monitor.height,
|
||||
monitor.x, monitor.y));
|
||||
}
|
||||
Shell.write_string_to_stream(out, ' ]');
|
||||
|
||||
Shell.write_string_to_stream(out, ',\n"metrics":\n[ ');
|
||||
let first = true;
|
||||
for (let name in scriptModule.METRICS) {
|
||||
let metric = scriptModule.METRICS[name];
|
||||
|
||||
if (!first)
|
||||
Shell.write_string_to_stream(out, ',\n ');
|
||||
first = false;
|
||||
|
||||
Shell.write_string_to_stream(out,
|
||||
'{ "name": ' + JSON.stringify(name) + ',\n' +
|
||||
' "description": ' + JSON.stringify(metric.description) + ',\n' +
|
||||
' "units": ' + JSON.stringify(metric.units) + ',\n' +
|
||||
' "value": ' + JSON.stringify(metric.value) + ' }');
|
||||
}
|
||||
Shell.write_string_to_stream(out, ' ]');
|
||||
|
||||
Shell.write_string_to_stream (out, ',\n"log":\n');
|
||||
Shell.PerfLog.get_default().dump_log(out);
|
||||
|
||||
Shell.write_string_to_stream (out, '\n}\n');
|
||||
out.close(null);
|
||||
} else {
|
||||
let metrics = [];
|
||||
for (let metric in scriptModule.METRICS)
|
||||
metrics.push(metric);
|
||||
|
||||
metrics.sort();
|
||||
|
||||
print ('------------------------------------------------------------');
|
||||
for (let i = 0; i < metrics.length; i++) {
|
||||
let metric = metrics[i];
|
||||
print ('# ' + scriptModule.METRIC_DESCRIPTIONS[metric]);
|
||||
print (metric + ': ' + scriptModule.METRICS[metric]);
|
||||
}
|
||||
print ('------------------------------------------------------------');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* runPerfScript
|
||||
* @scriptModule: module object with run and finish functions
|
||||
* and event handlers
|
||||
*
|
||||
* Runs a script for automated collection of performance data. The
|
||||
* script is defined as a Javascript module with specified contents.
|
||||
*
|
||||
* First the run() function within the module will be called as a
|
||||
* generator to automate a series of actions. These actions will
|
||||
* trigger performance events and the script can also record its
|
||||
* own performance events.
|
||||
*
|
||||
* Then the recorded event log is replayed using handler functions
|
||||
* within the module. The handler for the event 'foo.bar' is called
|
||||
* foo_bar().
|
||||
*
|
||||
* Finally if the module has a function called finish(), that will
|
||||
* be called.
|
||||
*
|
||||
* The event handler and finish functions are expected to fill in
|
||||
* metrics to an object within the module called METRICS. Each
|
||||
* property of this object represents an individual metric. The
|
||||
* name of the property is the name of the metric, the value
|
||||
* of the property is an object with the following properties:
|
||||
*
|
||||
* description: human readable description of the metric
|
||||
* units: a string representing the units of the metric. It has
|
||||
* the form '<unit> <unit> ... / <unit> / <unit> ...'. Certain
|
||||
* unit values are recognized: s, ms, us, B, KiB, MiB. Other
|
||||
* values can appear but are uninterpreted. Examples 's',
|
||||
* '/ s', 'frames', 'frames / s', 'MiB / s / frame'
|
||||
* value: computed value of the metric
|
||||
*
|
||||
* The resulting metrics will be written to @outputFile as JSON, or,
|
||||
* if @outputFile is not provided, logged.
|
||||
*
|
||||
* After running the script and collecting statistics from the
|
||||
* event log, GNOME Shell will exit.
|
||||
**/
|
||||
function runPerfScript(scriptModule, outputFile) {
|
||||
Shell.PerfLog.get_default().set_enabled(true);
|
||||
|
||||
let g = scriptModule.run();
|
||||
|
||||
_step(g,
|
||||
function() {
|
||||
_collect(scriptModule, outputFile);
|
||||
Meta.exit(Meta.ExitCode.SUCCESS);
|
||||
},
|
||||
function(err) {
|
||||
log("Script failed: " + err + "\n" + err.stack);
|
||||
Meta.exit(Meta.ExitCode.ERROR);
|
||||
});
|
||||
}
|
@ -40,7 +40,7 @@ SearchResultDisplay.prototype = {
|
||||
* The terms are useful for search match highlighting.
|
||||
*/
|
||||
renderResults: function(results, terms) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -67,7 +67,7 @@ SearchResultDisplay.prototype = {
|
||||
* Returns: The number of actors visible.
|
||||
*/
|
||||
getVisibleResultCount: function() {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -79,14 +79,14 @@ SearchResultDisplay.prototype = {
|
||||
* available.
|
||||
*/
|
||||
selectIndex: function() {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
* Activate the currently selected search result.
|
||||
*/
|
||||
activateSelected: function() {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
};
|
||||
|
||||
@ -127,7 +127,7 @@ SearchProvider.prototype = {
|
||||
* or network queries.
|
||||
*/
|
||||
getInitialResultSet: function(terms) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -144,7 +144,7 @@ SearchProvider.prototype = {
|
||||
* result set, rather than possibly performing a full re-query.
|
||||
*/
|
||||
getSubsearchResultSet: function(previousResults, newTerms) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -155,7 +155,7 @@ SearchProvider.prototype = {
|
||||
* properties which describe the given search result.
|
||||
*/
|
||||
getResultMeta: function(id) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -194,7 +194,7 @@ SearchProvider.prototype = {
|
||||
* Called when the user chooses a given result.
|
||||
*/
|
||||
activateResult: function(id) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
/**
|
||||
@ -205,7 +205,7 @@ SearchProvider.prototype = {
|
||||
* displaying search results for that item type.
|
||||
*/
|
||||
expandSearch: function(terms) {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SearchProvider.prototype);
|
||||
@ -238,7 +238,7 @@ SearchSystem.prototype = {
|
||||
},
|
||||
|
||||
updateSearch: function(searchString) {
|
||||
searchString = searchString.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
||||
searchString = searchString.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||
if (searchString == '')
|
||||
return null;
|
||||
|
||||
|
@ -8,16 +8,16 @@ const Mainloop = imports.mainloop;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const GnomeShellIface = {
|
||||
name: "org.gnome.Shell",
|
||||
methods: [{ name: "Eval",
|
||||
inSignature: "s",
|
||||
outSignature: "bs"
|
||||
name: 'org.gnome.Shell',
|
||||
methods: [{ name: 'Eval',
|
||||
inSignature: 's',
|
||||
outSignature: 'bs'
|
||||
}
|
||||
],
|
||||
signals: [],
|
||||
properties: [{ name: "OverviewActive",
|
||||
signature: "b",
|
||||
access: "readwrite" }]
|
||||
properties: [{ name: 'OverviewActive',
|
||||
signature: 'b',
|
||||
access: 'readwrite' }]
|
||||
};
|
||||
|
||||
function GnomeShell() {
|
||||
@ -50,7 +50,7 @@ GnomeShell.prototype = {
|
||||
returnValue = JSON.stringify(eval(code));
|
||||
// A hack; DBus doesn't have null/undefined
|
||||
if (returnValue == undefined)
|
||||
returnValue = "";
|
||||
returnValue = '';
|
||||
success = true;
|
||||
} catch (e) {
|
||||
returnValue = JSON.stringify(e);
|
||||
|
264
js/ui/sidebar.js
264
js/ui/sidebar.js
@ -1,264 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Panel = imports.ui.panel;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Widget = imports.ui.widget;
|
||||
const WidgetBox = imports.ui.widgetBox;
|
||||
|
||||
const SIDEBAR_SPACING = 4;
|
||||
const SIDEBAR_PADDING = 4;
|
||||
|
||||
// The total sidebar width is the widget width plus the widget padding
|
||||
// (counted twice for the widget box, and once again for the
|
||||
// out-of-screen padding), plus the empty space between the border of
|
||||
// the bar and of the windows
|
||||
const SIDEBAR_COLLAPSED_WIDTH = Widget.COLLAPSED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
||||
const SIDEBAR_EXPANDED_WIDTH = Widget.EXPANDED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
||||
|
||||
function Sidebar() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Sidebar.prototype = {
|
||||
_init : function() {
|
||||
// The top-left corner of the sidebar is fixed at:
|
||||
// x = -WidgetBox.WIDGETBOX_PADDING, y = Panel.PANEL_HEIGHT.
|
||||
// (The negative X is so that we don't see the rounded
|
||||
// WidgetBox corners on the screen edge side.)
|
||||
this.actor = new Clutter.Group({ x: -WidgetBox.WIDGETBOX_PADDING,
|
||||
y: Panel.PANEL_HEIGHT,
|
||||
width: SIDEBAR_EXPANDED_WIDTH });
|
||||
|
||||
// The actual widgets go into a Big.Box inside this.actor. The
|
||||
// box's width will vary during the expand/collapse animations,
|
||||
// but this.actor's width will remain constant until we adjust
|
||||
// it at the end of the animation, because we don't want the
|
||||
// wm strut to move and cause windows to move multiple times
|
||||
// during the animation.
|
||||
this.box = new Big.Box ({ padding_top: SIDEBAR_PADDING,
|
||||
padding_bottom: SIDEBAR_PADDING,
|
||||
padding_right: 0,
|
||||
padding_left: 0,
|
||||
spacing: SIDEBAR_SPACING });
|
||||
this.actor.add_actor(this.box);
|
||||
|
||||
this._gconf = Shell.GConf.get_default();
|
||||
|
||||
this._expanded = this._gconf.get_boolean ("sidebar/expanded");
|
||||
if (!this._expanded)
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
|
||||
this._visible = this._gconf.get_boolean ("sidebar/visible");
|
||||
if (this._visible)
|
||||
Main.chrome.addActor(this.actor);
|
||||
|
||||
this._hidden = false;
|
||||
this._hideTimeoutId = 0;
|
||||
this._widgets = [];
|
||||
this.addWidget(new ToggleWidget());
|
||||
|
||||
let default_widgets = this._gconf.get_string_list("sidebar/widgets");
|
||||
for (let i = 0; i < default_widgets.length; i++)
|
||||
this.addWidget(default_widgets[i]);
|
||||
|
||||
this._gconf.connect('changed::sidebar/expanded',
|
||||
Lang.bind(this, this._expandedChanged));
|
||||
this._gconf.connect('changed::sidebar/visible',
|
||||
Lang.bind(this, this._visibleChanged));
|
||||
this._gconf.connect('changed::sidebar/autohide',
|
||||
Lang.bind(this, this._autohideChanged));
|
||||
|
||||
this.actor.connect('enter-event',Lang.bind(this,this._restoreHidden));
|
||||
this.actor.connect('leave-event',Lang.bind(this,this._startHideTimeout));
|
||||
|
||||
this._adjustPosition();
|
||||
this._autohideChanged();
|
||||
},
|
||||
|
||||
addWidget: function(widget) {
|
||||
let widgetBox;
|
||||
try {
|
||||
widgetBox = new WidgetBox.WidgetBox(widget, this._expanded);
|
||||
} catch(e) {
|
||||
logError(e, "Failed to add widget '" + widget + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
this.box.append(widgetBox.actor, Big.BoxPackFlags.NONE);
|
||||
this._widgets.push(widgetBox);
|
||||
this._adjustPosition();
|
||||
},
|
||||
|
||||
_adjustPosition: function() {
|
||||
let primary=global.get_primary_monitor();
|
||||
|
||||
this.actor.y = Math.floor(Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2));
|
||||
this.actor.x = primary.x;
|
||||
},
|
||||
|
||||
_visibleChanged: function() {
|
||||
let visible = this._gconf.get_boolean("sidebar/visible");
|
||||
if (visible == this._visible)
|
||||
return;
|
||||
|
||||
this._visible = visible;
|
||||
if (visible)
|
||||
Main.chrome.addActor(this.actor);
|
||||
else
|
||||
Main.chrome.removeActor(this.actor);
|
||||
},
|
||||
|
||||
_expandedChanged: function() {
|
||||
let expanded = this._gconf.get_boolean("sidebar/expanded");
|
||||
if (expanded == this._expanded)
|
||||
return;
|
||||
|
||||
this._expanded = expanded;
|
||||
if (expanded)
|
||||
this._expand();
|
||||
else
|
||||
this._collapse();
|
||||
},
|
||||
|
||||
_autohideChanged: function() {
|
||||
let autohide = this._gconf.get_boolean("sidebar/autohide");
|
||||
if (autohide == this._autohide)
|
||||
return;
|
||||
|
||||
this._autohide = autohide;
|
||||
if (autohide) {
|
||||
this.actor.set_reactive(true);
|
||||
this._hide();
|
||||
} else {
|
||||
this.actor.set_reactive(false);
|
||||
this._restore();
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function() {
|
||||
this._expanded = true;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].expand();
|
||||
|
||||
// Updated the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
||||
onComplete: function () {
|
||||
this.actor.width = SIDEBAR_EXPANDED_WIDTH;
|
||||
} });
|
||||
},
|
||||
|
||||
_collapse: function() {
|
||||
this._expanded = false;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].collapse();
|
||||
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
}) });
|
||||
},
|
||||
|
||||
_hide: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = true;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].hide();
|
||||
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = Math.floor(WidgetBox.WIDGETBOX_PADDING * 2 + SIDEBAR_PADDING);
|
||||
}) });
|
||||
}
|
||||
},
|
||||
|
||||
_restore: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = false;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].restore();
|
||||
|
||||
// Updated the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
} });
|
||||
}
|
||||
},
|
||||
|
||||
_restoreHidden: function(actor, event) {
|
||||
this._cancelHideTimeout();
|
||||
if (this._hidden)
|
||||
this._restore();
|
||||
return false;
|
||||
},
|
||||
|
||||
_startHideTimeout: function(actor, event) {
|
||||
if (!this._expanded) {
|
||||
this._cancelHideTimeout();
|
||||
this._hideTimeoutId = Mainloop.timeout_add_seconds(2, Lang.bind(this,this._hideTimeoutFunc));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_cancelHideTimeout: function() {
|
||||
if (this._hideTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._hideTimeoutId);
|
||||
this._hideTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_hideTimeoutFunc: function() {
|
||||
this._hide();
|
||||
return false;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.hide();
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].destroy();
|
||||
this.actor.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
const LEFT_DOUBLE_ARROW = "\u00AB";
|
||||
const RIGHT_DOUBLE_ARROW = "\u00BB";
|
||||
|
||||
function ToggleWidget() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ToggleWidget.prototype = {
|
||||
__proto__ : Widget.Widget.prototype,
|
||||
|
||||
_init : function() {
|
||||
this._gconf = Shell.GConf.get_default();
|
||||
|
||||
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
||||
text: LEFT_DOUBLE_ARROW,
|
||||
reactive: true });
|
||||
this.actor.connect('button-release-event',
|
||||
Lang.bind(this, this._collapse));
|
||||
this.collapsedActor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
||||
text: RIGHT_DOUBLE_ARROW,
|
||||
reactive: true });
|
||||
this.collapsedActor.connect('button-release-event',
|
||||
Lang.bind(this, this._expand));
|
||||
},
|
||||
|
||||
_collapse : function () {
|
||||
this._gconf.set_boolean ("sidebar/expanded", false);
|
||||
},
|
||||
|
||||
_expand : function () {
|
||||
this._gconf.set_boolean ("sidebar/expanded", true);
|
||||
}
|
||||
};
|
@ -1,16 +1,14 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const DBus = imports.dbus;
|
||||
const Gdm = imports.gi.Gdm;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Panel = imports.ui.panel;
|
||||
|
||||
// Adapted from gdm/gui/user-switch-applet/applet.c
|
||||
@ -18,23 +16,26 @@ const Panel = imports.ui.panel;
|
||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
||||
// Copyright (C) 2008,2009 Red Hat, Inc.
|
||||
|
||||
const SIDEBAR_VISIBLE_KEY = 'sidebar/visible';
|
||||
|
||||
function StatusMenu() {
|
||||
function StatusMenuButton() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
StatusMenu.prototype = {
|
||||
StatusMenuButton.prototype = {
|
||||
__proto__: Panel.PanelMenuButton.prototype,
|
||||
|
||||
_init: function() {
|
||||
Panel.PanelMenuButton.prototype._init.call(this, St.Align.START);
|
||||
let box = new St.BoxLayout({ name: 'panelStatusMenu' });
|
||||
this.actor.set_child(box);
|
||||
|
||||
this._gdm = Gdm.UserManager.ref_default();
|
||||
this._user = this._gdm.get_user(GLib.get_user_name());
|
||||
this._presence = new GnomeSessionPresence();
|
||||
this._presence = new GnomeSession.Presence();
|
||||
|
||||
this.actor = new St.BoxLayout({ name: 'statusMenu' });
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
|
||||
this._iconBox = new St.Bin();
|
||||
this.actor.add(this._iconBox, { y_align: St.Align.MIDDLE });
|
||||
box.add(this._iconBox, { y_align: St.Align.MIDDLE, y_fill: false });
|
||||
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
// FIXME: these icons are all wrong (likewise in createSubMenu)
|
||||
@ -47,7 +48,7 @@ StatusMenu.prototype = {
|
||||
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
|
||||
|
||||
this._name = new St.Label({ text: this._user.get_real_name() });
|
||||
this.actor.add(this._name, { expand: true, y_align: St.Align.MIDDLE });
|
||||
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
|
||||
this._userNameChangedId = this._user.connect('notify::display-name', Lang.bind(this, this._updateUserName));
|
||||
|
||||
this._createSubMenu();
|
||||
@ -67,110 +68,70 @@ StatusMenu.prototype = {
|
||||
_updateSwitchUser: function() {
|
||||
let users = this._gdm.list_users();
|
||||
if (users.length > 1)
|
||||
this._loginScreenItem.show();
|
||||
this._loginScreenItem.actor.show();
|
||||
else
|
||||
this._loginScreenItem.hide();
|
||||
this._loginScreenItem.actor.hide();
|
||||
},
|
||||
|
||||
_updatePresenceIcon: function(presence, status) {
|
||||
if (status == GnomeSessionPresenceStatus.AVAILABLE)
|
||||
if (status == GnomeSession.PresenceStatus.AVAILABLE)
|
||||
this._iconBox.child = this._availableIcon;
|
||||
else if (status == GnomeSessionPresenceStatus.BUSY)
|
||||
else if (status == GnomeSession.PresenceStatus.BUSY)
|
||||
this._iconBox.child = this._busyIcon;
|
||||
else if (status == GnomeSessionPresenceStatus.INVISIBLE)
|
||||
else if (status == GnomeSession.PresenceStatus.INVISIBLE)
|
||||
this._iconBox.child = this._invisibleIcon;
|
||||
else
|
||||
this._iconBox.child = this._idleIcon;
|
||||
},
|
||||
|
||||
// The menu
|
||||
|
||||
_createImageMenuItem: function(label, iconName, forceIcon) {
|
||||
let image = new Gtk.Image();
|
||||
let item = new Gtk.ImageMenuItem({ label: label,
|
||||
image: image,
|
||||
always_show_image: forceIcon == true });
|
||||
item.connect('style-set', Lang.bind(this,
|
||||
function() {
|
||||
image.set_from_icon_name(iconName, Gtk.IconSize.MENU);
|
||||
}));
|
||||
|
||||
return item;
|
||||
},
|
||||
|
||||
_createSubMenu: function() {
|
||||
this._menu = new Gtk.Menu();
|
||||
this._menu.connect('deactivate', Lang.bind(this, function() { this.emit('deactivated'); }));
|
||||
|
||||
let item;
|
||||
|
||||
item = this._createImageMenuItem(_("Available"), 'gtk-yes', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.AVAILABLE));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
item = new Panel.PanelImageMenuItem(_("Available"), 'gtk-yes', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.AVAILABLE));
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Busy"), 'gtk-no', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.BUSY));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
item = new Panel.PanelImageMenuItem(_("Busy"), 'gtk-no', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.BUSY));
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Invisible"), 'gtk-close', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSessionPresenceStatus.INVISIBLE));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
item = new Panel.PanelImageMenuItem(_("Invisible"), 'gtk-close', true);
|
||||
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.INVISIBLE));
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = new Gtk.SeparatorMenuItem();
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
item = new Panel.PanelSeparatorMenuItem();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Account Information..."), 'user-info');
|
||||
item = new Panel.PanelImageMenuItem(_("Account Information..."), 'user-info');
|
||||
item.connect('activate', Lang.bind(this, this._onAccountInformationActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
item = new Gtk.CheckMenuItem({ label: _("Sidebar"),
|
||||
active: gconf.get_boolean(SIDEBAR_VISIBLE_KEY) });
|
||||
item.connect('activate', Lang.bind(this,
|
||||
function() {
|
||||
gconf.set_boolean(SIDEBAR_VISIBLE_KEY, this._sidebarItem.active);
|
||||
}));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this._sidebarItem = item;
|
||||
|
||||
item = this._createImageMenuItem(_("System Preferences..."), 'preferences-desktop');
|
||||
item = new Panel.PanelImageMenuItem(_("System Preferences..."), 'preferences-desktop');
|
||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = new Gtk.SeparatorMenuItem();
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
item = new Panel.PanelSeparatorMenuItem();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Lock Screen"), 'system-lock-screen');
|
||||
item = new Panel.PanelImageMenuItem(_("Lock Screen"), 'system-lock-screen');
|
||||
item.connect('activate', Lang.bind(this, this._onLockScreenActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Switch User"), 'system-users');
|
||||
item = new Panel.PanelImageMenuItem(_("Switch User"), 'system-users');
|
||||
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
this._loginScreenItem = item;
|
||||
|
||||
item = this._createImageMenuItem(_("Log Out..."), 'system-log-out');
|
||||
item = new Panel.PanelImageMenuItem(_("Log Out..."), 'system-log-out');
|
||||
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
|
||||
item = this._createImageMenuItem(_("Shut Down..."), 'system-shutdown');
|
||||
item = new Panel.PanelImageMenuItem(_("Shut Down..."), 'system-shutdown');
|
||||
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this.menu.addMenuItem(item);
|
||||
},
|
||||
|
||||
_setPresenceStatus: function(item, status) {
|
||||
_setPresenceStatus: function(item, event, status) {
|
||||
this._presence.setStatus(status);
|
||||
},
|
||||
|
||||
@ -205,98 +166,5 @@ StatusMenu.prototype = {
|
||||
// on failure
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
},
|
||||
|
||||
// shell_status_menu_toggle:
|
||||
// @event: event causing the toggle
|
||||
//
|
||||
// If the menu is not currently up, pops it up. Otherwise, hides it.
|
||||
// Popping up may fail if another grab is already active; check with
|
||||
// isActive().
|
||||
toggle: function(event) {
|
||||
if (this._menu.visible)
|
||||
this._menu.popdown();
|
||||
else {
|
||||
// We don't want to overgrab a Mutter grab with the grab
|
||||
// that GTK+ uses on menus.
|
||||
if (global.display_is_grabbed())
|
||||
return;
|
||||
|
||||
let [menuWidth, menuHeight] = this._menu.get_size_request ();
|
||||
|
||||
let panel;
|
||||
for (panel = this.actor; panel; panel = panel.get_parent()) {
|
||||
if (panel._delegate instanceof Panel.Panel)
|
||||
break;
|
||||
}
|
||||
|
||||
let [panelX, panelY] = panel.get_transformed_position();
|
||||
let [panelWidth, panelHeight] = panel.get_transformed_size();
|
||||
|
||||
let menuX;
|
||||
if (St.Widget.get_default_direction() == St.TextDirection.RTL) {
|
||||
menuX = panelX;
|
||||
} else {
|
||||
menuX = Math.round(panelX + panelWidth - menuWidth);
|
||||
}
|
||||
let menuY = Math.round(panelY + panelHeight);
|
||||
|
||||
Shell.popup_menu(this._menu, event.get_button(), event.get_time(),
|
||||
menuX, menuY);
|
||||
}
|
||||
},
|
||||
|
||||
// isActive:
|
||||
//
|
||||
// Gets whether the menu is currently popped up
|
||||
//
|
||||
// Return value: %true if the menu is currently popped up
|
||||
isActive: function() {
|
||||
return this._menu.visible;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(StatusMenu.prototype);
|
||||
|
||||
|
||||
const GnomeSessionPresenceIface = {
|
||||
name: 'org.gnome.SessionManager.Presence',
|
||||
methods: [{ name: 'SetStatus',
|
||||
inSignature: 'u' }],
|
||||
properties: [{ name: 'status',
|
||||
signature: 'u',
|
||||
access: 'readwrite' }],
|
||||
signals: [{ name: 'StatusChanged',
|
||||
inSignature: 'u' }]
|
||||
};
|
||||
|
||||
const GnomeSessionPresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
INVISIBLE: 1,
|
||||
BUSY: 2,
|
||||
IDLE: 3
|
||||
};
|
||||
|
||||
function GnomeSessionPresence() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
GnomeSessionPresence.prototype = {
|
||||
_init: function() {
|
||||
DBus.session.proxifyObject(this, 'org.gnome.SessionManager', '/org/gnome/SessionManager/Presence', this);
|
||||
this.connect('StatusChanged', Lang.bind(this, function (proxy, status) { this.status = status; }));
|
||||
},
|
||||
|
||||
getStatus: function(callback) {
|
||||
this.GetRemote('status', Lang.bind(this,
|
||||
function(status, ex) {
|
||||
if (!ex)
|
||||
callback(this, status);
|
||||
}));
|
||||
},
|
||||
|
||||
setStatus: function(status) {
|
||||
this.SetStatusRemote(status);
|
||||
}
|
||||
};
|
||||
DBus.proxifyPrototype(GnomeSessionPresence.prototype, GnomeSessionPresenceIface);
|
||||
|
||||
|
686
js/ui/telepathyClient.js
Normal file
686
js/ui/telepathyClient.js
Normal file
@ -0,0 +1,686 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const DBus = imports.dbus;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Telepathy = imports.misc.telepathy;
|
||||
|
||||
let contactManager;
|
||||
let channelDispatcher;
|
||||
|
||||
// See Notification.appendMessage
|
||||
const SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
const SCROLLBACK_RECENT_LENGTH = 20;
|
||||
const SCROLLBACK_IDLE_LENGTH = 5;
|
||||
|
||||
// A 'Qualified_Property_Value_Map' that represents a single-user
|
||||
// text-based chat.
|
||||
let singleUserTextChannel = {};
|
||||
singleUserTextChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_TEXT_NAME;
|
||||
singleUserTextChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.CONTACT;
|
||||
|
||||
// Some protocols only support 'multi-user' chats, and single-user
|
||||
// chats are just treated as multi-user chats with only one other
|
||||
// participant. Telepathy uses HandleType.NONE for all chats in these
|
||||
// protocols; there's no good way for us to tell if the channel is
|
||||
// single- or multi-user.
|
||||
let oneOrMoreUserTextChannel = {};
|
||||
oneOrMoreUserTextChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_TEXT_NAME;
|
||||
oneOrMoreUserTextChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.NONE;
|
||||
|
||||
// The (non-chat) channel indicating the users whose presence
|
||||
// information we subscribe to
|
||||
let subscribedContactsChannel = {};
|
||||
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.ChannelType'] = Telepathy.CHANNEL_CONTACT_LIST_NAME;
|
||||
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.TargetHandleType'] = Telepathy.HandleType.LIST;
|
||||
subscribedContactsChannel[Telepathy.CHANNEL_NAME + '.TargetID'] = 'subscribe';
|
||||
|
||||
|
||||
// This is GNOME Shell's implementation of the Telepathy 'Client'
|
||||
// interface. Specifically, the shell is a Telepathy 'Observer', which
|
||||
// lets us see messages even if they belong to another app (eg,
|
||||
// Empathy).
|
||||
|
||||
function Client() {
|
||||
this._init();
|
||||
};
|
||||
|
||||
Client.prototype = {
|
||||
_init : function() {
|
||||
let name = Telepathy.CLIENT_NAME + '.GnomeShell';
|
||||
DBus.session.exportObject(Telepathy.nameToPath(name), this);
|
||||
DBus.session.acquire_name(name, DBus.SINGLE_INSTANCE,
|
||||
function (name) { /* FIXME: acquired */ },
|
||||
function (name) { /* FIXME: lost */ });
|
||||
|
||||
this._accounts = {};
|
||||
this._sources = {};
|
||||
|
||||
contactManager = new ContactManager();
|
||||
contactManager.connect('presence-changed', Lang.bind(this, this._presenceChanged));
|
||||
|
||||
channelDispatcher = new Telepathy.ChannelDispatcher(DBus.session,
|
||||
Telepathy.CHANNEL_DISPATCHER_NAME,
|
||||
Telepathy.nameToPath(Telepathy.CHANNEL_DISPATCHER_NAME));
|
||||
|
||||
// Acquire existing connections. (Needed to make things work
|
||||
// through a restart.)
|
||||
let accountManager = new Telepathy.AccountManager(DBus.session,
|
||||
Telepathy.ACCOUNT_MANAGER_NAME,
|
||||
Telepathy.nameToPath(Telepathy.ACCOUNT_MANAGER_NAME));
|
||||
accountManager.GetRemote('ValidAccounts', Lang.bind(this,
|
||||
function (accounts, err) {
|
||||
if (!accounts)
|
||||
return;
|
||||
|
||||
for (let i = 0; i < accounts.length; i++)
|
||||
this._gotAccount(accounts[i]);
|
||||
}));
|
||||
accountManager.connect('AccountValidityChanged', Lang.bind(this, this._accountValidityChanged));
|
||||
},
|
||||
|
||||
_accountValidityChanged: function(accountManager, accountPath, valid) {
|
||||
if (!valid) {
|
||||
delete this._accounts[accountPath];
|
||||
// We don't need to clean up connections, sources, etc; they'll
|
||||
// get Closed and cleaned up independently.
|
||||
} else
|
||||
this._gotAccount(accountPath);
|
||||
},
|
||||
|
||||
_gotAccount: function(accountPath) {
|
||||
let account = new Telepathy.Account(DBus.session,
|
||||
Telepathy.ACCOUNT_MANAGER_NAME,
|
||||
accountPath);
|
||||
this._accounts[accountPath] = account;
|
||||
account.GetRemote('Connection', Lang.bind(this,
|
||||
function (connPath, err) {
|
||||
if (!connPath || connPath == '/')
|
||||
return;
|
||||
|
||||
let connReq = new Telepathy.ConnectionRequests(DBus.session,
|
||||
Telepathy.pathToName(connPath),
|
||||
connPath);
|
||||
connReq.GetRemote('Channels', Lang.bind(this,
|
||||
function(channels, err) {
|
||||
if (!channels)
|
||||
return;
|
||||
|
||||
this._addChannels(accountPath, connPath, channels);
|
||||
}));
|
||||
|
||||
contactManager.addConnection(connPath);
|
||||
}));
|
||||
},
|
||||
|
||||
get Interfaces() {
|
||||
return [ Telepathy.CLIENT_OBSERVER_NAME ];
|
||||
},
|
||||
|
||||
get ObserverChannelFilter() {
|
||||
return [ singleUserTextChannel, oneOrMoreUserTextChannel ];
|
||||
},
|
||||
|
||||
ObserveChannels: function(accountPath, connPath, channels,
|
||||
dispatchOperation, requestsSatisfied,
|
||||
observerInfo) {
|
||||
this._addChannels(accountPath, connPath, channels);
|
||||
},
|
||||
|
||||
_addChannels: function(accountPath, connPath, channelDetailsList) {
|
||||
for (let i = 0; i < channelDetailsList.length; i++) {
|
||||
let [channelPath, props] = channelDetailsList[i];
|
||||
|
||||
// If this is being called from the startup code then it
|
||||
// won't have passed through our filters, so we need to
|
||||
// check the channel/targetHandle type ourselves.
|
||||
|
||||
let channelType = props[Telepathy.CHANNEL_NAME + '.ChannelType'];
|
||||
if (channelType != Telepathy.CHANNEL_TEXT_NAME)
|
||||
continue;
|
||||
|
||||
let targetHandleType = props[Telepathy.CHANNEL_NAME + '.TargetHandleType'];
|
||||
if (targetHandleType != Telepathy.HandleType.CONTACT &&
|
||||
targetHandleType != Telepathy.HandleType.NONE)
|
||||
continue;
|
||||
|
||||
let targetHandle = props[Telepathy.CHANNEL_NAME + '.TargetHandle'];
|
||||
let targetId = props[Telepathy.CHANNEL_NAME + '.TargetID'];
|
||||
|
||||
if (this._sources[connPath + ':' + targetHandle])
|
||||
continue;
|
||||
|
||||
let source = new Source(accountPath, connPath, channelPath,
|
||||
targetHandle, targetHandleType, targetId);
|
||||
this._sources[connPath + ':' + targetHandle] = source;
|
||||
source.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
delete this._sources[connPath + ':' + targetHandle];
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
_presenceChanged: function(contactManager, connPath, handle,
|
||||
type, message) {
|
||||
let source = this._sources[connPath + ':' + handle];
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
source.setPresence(type, message);
|
||||
}
|
||||
};
|
||||
DBus.conformExport(Client.prototype, Telepathy.ClientIface);
|
||||
DBus.conformExport(Client.prototype, Telepathy.ClientObserverIface);
|
||||
|
||||
|
||||
function ContactManager() {
|
||||
this._init();
|
||||
};
|
||||
|
||||
ContactManager.prototype = {
|
||||
_init: function() {
|
||||
this._connections = {};
|
||||
// Note that if we changed this to '/telepathy/avatars' then
|
||||
// we would share cache files with empathy. But since this is
|
||||
// not documented/guaranteed, it seems a little sketchy
|
||||
this._cacheDir = GLib.get_user_cache_dir() + '/gnome-shell/avatars';
|
||||
},
|
||||
|
||||
addConnection: function(connPath) {
|
||||
let info = this._connections[connPath];
|
||||
if (info)
|
||||
return info;
|
||||
|
||||
info = {};
|
||||
|
||||
// Figure out the cache subdirectory for this connection by
|
||||
// parsing the connection manager name (eg, 'gabble') and
|
||||
// protocol name (eg, 'jabber') from the Connection's path.
|
||||
// Telepathy requires the D-Bus path for a connection to have
|
||||
// a specific form, and explicitly says that clients are
|
||||
// allowed to parse it.
|
||||
let match = connPath.match(/\/org\/freedesktop\/Telepathy\/Connection\/([^\/]*\/[^\/]*)\/.*/);
|
||||
if (!match)
|
||||
throw new Error('Could not parse connection path ' + connPath);
|
||||
|
||||
info.cacheDir = this._cacheDir + '/' + match[1];
|
||||
GLib.mkdir_with_parents(info.cacheDir, 0700);
|
||||
|
||||
// info.names[handle] is @handle's real name
|
||||
// info.tokens[handle] is the token for @handle's avatar
|
||||
info.names = {};
|
||||
info.tokens = {};
|
||||
|
||||
// info.icons[handle] is an array of the icon actors currently
|
||||
// being displayed for @handle. These will be updated
|
||||
// automatically if @handle's avatar changes.
|
||||
info.icons = {};
|
||||
|
||||
let connName = Telepathy.pathToName(connPath);
|
||||
|
||||
info.connectionAvatars = new Telepathy.ConnectionAvatars(DBus.session, connName, connPath);
|
||||
info.updatedId = info.connectionAvatars.connect(
|
||||
'AvatarUpdated', Lang.bind(this, this._avatarUpdated));
|
||||
info.retrievedId = info.connectionAvatars.connect(
|
||||
'AvatarRetrieved', Lang.bind(this, this._avatarRetrieved));
|
||||
|
||||
info.connectionContacts = new Telepathy.ConnectionContacts(DBus.session, connName, connPath);
|
||||
|
||||
info.connectionPresence = new Telepathy.ConnectionSimplePresence(DBus.session, connName, connPath);
|
||||
info.presenceChangedId = info.connectionPresence.connect(
|
||||
'PresencesChanged', Lang.bind(this, this._presencesChanged));
|
||||
|
||||
let conn = new Telepathy.Connection(DBus.session, connName, connPath);
|
||||
info.statusChangedId = conn.connect('StatusChanged', Lang.bind(this,
|
||||
function (status, reason) {
|
||||
if (status == Telepathy.ConnectionStatus.DISCONNECTED)
|
||||
this._removeConnection(conn);
|
||||
}));
|
||||
|
||||
let connReq = new Telepathy.ConnectionRequests(DBus.session,
|
||||
connName, connPath);
|
||||
connReq.EnsureChannelRemote(subscribedContactsChannel, Lang.bind(this,
|
||||
function (result, err) {
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
let [mine, channelPath, props] = result;
|
||||
this._gotContactsChannel(connPath, channelPath, props);
|
||||
}));
|
||||
|
||||
this._connections[connPath] = info;
|
||||
return info;
|
||||
},
|
||||
|
||||
_gotContactsChannel: function(connPath, channelPath, props) {
|
||||
let info = this._connections[connPath];
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
info.contactsGroup = new Telepathy.ChannelGroup(DBus.session,
|
||||
Telepathy.pathToName(connPath),
|
||||
channelPath);
|
||||
info.contactsListChangedId =
|
||||
info.contactsGroup.connect('MembersChanged', Lang.bind(this, this._contactsListChanged, info));
|
||||
|
||||
info.contactsGroup.GetRemote('Members', Lang.bind(this,
|
||||
function(contacts, err) {
|
||||
if (!contacts)
|
||||
return;
|
||||
|
||||
info.connectionContacts.GetContactAttributesRemote(
|
||||
contacts, [Telepathy.CONNECTION_ALIASING_NAME], false,
|
||||
Lang.bind(this, this._gotContactAttributes, info));
|
||||
}));
|
||||
},
|
||||
|
||||
_contactsListChanged: function(group, message, added, removed,
|
||||
local_pending, remote_pending,
|
||||
actor, reason, info) {
|
||||
for (let i = 0; i < removed.length; i++)
|
||||
delete info.names[removed[i]];
|
||||
|
||||
info.connectionContacts.GetContactAttributesRemote(
|
||||
added, [Telepathy.CONNECTION_ALIASING_NAME], false,
|
||||
Lang.bind(this, this._gotContactAttributes, info));
|
||||
},
|
||||
|
||||
_gotContactAttributes: function(attrs, err, info) {
|
||||
if (!attrs)
|
||||
return;
|
||||
|
||||
for (let handle in attrs)
|
||||
info.names[handle] = attrs[handle][Telepathy.CONNECTION_ALIASING_NAME + '/alias'];
|
||||
},
|
||||
|
||||
_presencesChanged: function(conn, presences, err) {
|
||||
if (!presences)
|
||||
return;
|
||||
|
||||
let info = this._connections[conn.getPath()];
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
for (let handle in presences) {
|
||||
let [type, status, message] = presences[handle];
|
||||
this.emit('presence-changed', conn.getPath(), handle, type, message);
|
||||
}
|
||||
},
|
||||
|
||||
_removeConnection: function(conn) {
|
||||
let info = this._connections[conn.getPath()];
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
conn.disconnect(info.statusChangedId);
|
||||
info.connectionAvatars.disconnect(info.updatedId);
|
||||
info.connectionAvatars.disconnect(info.retrievedId);
|
||||
info.connectionPresence.disconnect(info.presenceChangedId);
|
||||
info.contactsGroup.disconnect(info.contactsListChangedId);
|
||||
|
||||
delete this._connections[conn.getPath()];
|
||||
},
|
||||
|
||||
_getFileForToken: function(info, token) {
|
||||
return info.cacheDir + '/' + Telepathy.escapeAsIdentifier(token);
|
||||
},
|
||||
|
||||
_setIcon: function(iconBox, info, handle) {
|
||||
let textureCache = St.TextureCache.get_default();
|
||||
let token = info.tokens[handle];
|
||||
let file;
|
||||
|
||||
if (token) {
|
||||
file = this._getFileForToken(info, token);
|
||||
if (!GLib.file_test(file, GLib.FileTest.EXISTS))
|
||||
file = null;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
let uri = GLib.filename_to_uri(file, null);
|
||||
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size);
|
||||
} else {
|
||||
iconBox.child = textureCache.load_icon_name('stock_person', iconBox._size);
|
||||
}
|
||||
},
|
||||
|
||||
_updateIcons: function(info, handle) {
|
||||
if (!info.icons[handle])
|
||||
return;
|
||||
|
||||
for (let i = 0; i < info.icons[handle].length; i++) {
|
||||
let iconBox = info.icons[handle][i];
|
||||
this._setIcon(iconBox, info, handle);
|
||||
}
|
||||
},
|
||||
|
||||
_avatarUpdated: function(conn, handle, token) {
|
||||
let info = this._connections[conn.getPath()];
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
if (info.tokens[handle] == token)
|
||||
return;
|
||||
|
||||
info.tokens[handle] = token;
|
||||
if (token != '') {
|
||||
let file = this._getFileForToken(info, token);
|
||||
if (!GLib.file_test(file, GLib.FileTest.EXISTS)) {
|
||||
info.connectionAvatars.RequestAvatarsRemote([handle]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this._updateIcons(info, handle);
|
||||
},
|
||||
|
||||
_avatarRetrieved: function(conn, handle, token, avatarData, mimeType) {
|
||||
let info = this._connections[conn.getPath()];
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
let file = this._getFileForToken(info, token);
|
||||
let success = false;
|
||||
try {
|
||||
success = GLib.file_set_contents(file, avatarData, avatarData.length);
|
||||
} catch (e) {
|
||||
logError(e, 'Error caching avatar data');
|
||||
}
|
||||
|
||||
if (success)
|
||||
this._updateIcons(info, handle);
|
||||
},
|
||||
|
||||
createAvatar: function(conn, handle, size) {
|
||||
let iconBox = new St.Bin({ style_class: 'avatar-box' });
|
||||
iconBox._size = size;
|
||||
|
||||
let info = this._connections[conn.getPath()];
|
||||
if (!info)
|
||||
info = this.addConnection(conn.getPath());
|
||||
|
||||
if (!info.icons[handle])
|
||||
info.icons[handle] = [];
|
||||
info.icons[handle].push(iconBox);
|
||||
|
||||
iconBox.connect('destroy', Lang.bind(this,
|
||||
function() {
|
||||
let i = info.icons[handle].indexOf(iconBox);
|
||||
if (i != -1)
|
||||
info.icons[handle].splice(i, 1);
|
||||
}));
|
||||
|
||||
// If we already have the icon cached and know its token, this
|
||||
// will fill it in. Otherwise it will fill in the default
|
||||
// icon.
|
||||
this._setIcon(iconBox, info, handle);
|
||||
|
||||
// Asynchronously load the real avatar if we don't have it yet.
|
||||
if (info.tokens[handle] == null) {
|
||||
info.connectionAvatars.GetKnownAvatarTokensRemote([handle], Lang.bind(this,
|
||||
function (tokens, err) {
|
||||
let token = tokens && tokens[handle] ? tokens[handle] : '';
|
||||
this._avatarUpdated(conn, handle, token);
|
||||
}));
|
||||
}
|
||||
|
||||
return iconBox;
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(ContactManager.prototype);
|
||||
|
||||
|
||||
function Source(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
|
||||
this._init(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId);
|
||||
}
|
||||
|
||||
Source.prototype = {
|
||||
__proto__: MessageTray.Source.prototype,
|
||||
|
||||
_init: function(accountPath, connPath, channelPath, targetHandle, targetHandleType, targetId) {
|
||||
MessageTray.Source.prototype._init.call(this, targetId);
|
||||
|
||||
this._accountPath = accountPath;
|
||||
|
||||
let connName = Telepathy.pathToName(connPath);
|
||||
this._conn = new Telepathy.Connection(DBus.session, connName, connPath);
|
||||
this._channel = new Telepathy.Channel(DBus.session, connName, channelPath);
|
||||
this._closedId = this._channel.connect('Closed', Lang.bind(this, this._channelClosed));
|
||||
|
||||
this._targetHandle = targetHandle;
|
||||
this._targetHandleType = targetHandleType;
|
||||
this._targetId = targetId;
|
||||
|
||||
this.name = this._targetId;
|
||||
if (targetHandleType == Telepathy.HandleType.CONTACT) {
|
||||
let aliasing = new Telepathy.ConnectionAliasing(DBus.session, connName, connPath);
|
||||
aliasing.RequestAliasesRemote([this._targetHandle], Lang.bind(this,
|
||||
function (aliases, err) {
|
||||
if (aliases && aliases.length)
|
||||
this.name = aliases[0];
|
||||
}));
|
||||
}
|
||||
|
||||
// Since we only create sources when receiving a message, this
|
||||
// is a plausible default
|
||||
this._presence = Telepathy.ConnectionPresenceType.AVAILABLE;
|
||||
|
||||
this._channelText = new Telepathy.ChannelText(DBus.session, connName, channelPath);
|
||||
this._receivedId = this._channelText.connect('Received', Lang.bind(this, this._messageReceived));
|
||||
|
||||
this._channelText.ListPendingMessagesRemote(false, Lang.bind(this, this._gotPendingMessages));
|
||||
},
|
||||
|
||||
createIcon: function(size) {
|
||||
return contactManager.createAvatar(this._conn, this._targetHandle, size);
|
||||
},
|
||||
|
||||
clicked: function() {
|
||||
channelDispatcher.EnsureChannelRemote(this._accountPath,
|
||||
{ 'org.freedesktop.Telepathy.Channel.ChannelType': Telepathy.CHANNEL_TEXT_NAME,
|
||||
'org.freedesktop.Telepathy.Channel.TargetHandle': this._targetHandle,
|
||||
'org.freedesktop.Telepathy.Channel.TargetHandleType': this._targetHandleType },
|
||||
global.get_current_time(),
|
||||
'',
|
||||
Lang.bind(this, this._gotChannelRequest));
|
||||
|
||||
MessageTray.Source.prototype.clicked.call(this);
|
||||
},
|
||||
|
||||
_gotChannelRequest: function (chanReqPath, ex) {
|
||||
if (ex) {
|
||||
log ('EnsureChannelRemote failed? ' + ex);
|
||||
return;
|
||||
}
|
||||
|
||||
let chanReq = new Telepathy.ChannelRequest(DBus.session, Telepathy.CHANNEL_DISPATCHER_NAME, chanReqPath);
|
||||
chanReq.ProceedRemote();
|
||||
},
|
||||
|
||||
_gotPendingMessages: function(msgs, err) {
|
||||
if (!msgs)
|
||||
return;
|
||||
|
||||
for (let i = 0; i < msgs.length; i++)
|
||||
this._messageReceived.apply(this, [this._channel].concat(msgs[i]));
|
||||
},
|
||||
|
||||
_channelClosed: function() {
|
||||
this._channel.disconnect(this._closedId);
|
||||
this._channelText.disconnect(this._receivedId);
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_ensureNotification: function() {
|
||||
if (!Main.messageTray.contains(this))
|
||||
Main.messageTray.add(this);
|
||||
|
||||
if (!this._notification)
|
||||
this._notification = new Notification(this._targetId, this);
|
||||
},
|
||||
|
||||
_messageReceived: function(channel, id, timestamp, sender,
|
||||
type, flags, text) {
|
||||
this._ensureNotification();
|
||||
this._notification.appendMessage(text);
|
||||
this.notify(this._notification);
|
||||
},
|
||||
|
||||
respond: function(text) {
|
||||
this._channelText.SendRemote(Telepathy.ChannelTextMessageType.NORMAL, text);
|
||||
},
|
||||
|
||||
setPresence: function(presence, message) {
|
||||
let msg, notify;
|
||||
|
||||
if (presence == Telepathy.ConnectionPresenceType.AVAILABLE) {
|
||||
msg = _("%s is online.").format(this.name);
|
||||
notify = (this._presence == Telepathy.ConnectionPresenceType.OFFLINE);
|
||||
} else if (presence == Telepathy.ConnectionPresenceType.OFFLINE ||
|
||||
presence == Telepathy.ConnectionPresenceType.EXTENDED_AWAY) {
|
||||
presence = Telepathy.ConnectionPresenceType.OFFLINE;
|
||||
msg = _("%s is offline.").format(this.name);
|
||||
notify = (this._presence != Telepathy.ConnectionPresenceType.OFFLINE);
|
||||
} else if (presence == Telepathy.ConnectionPresenceType.AWAY) {
|
||||
msg = _("%s is away.").format(this.name);
|
||||
notify = false;
|
||||
} else if (presence == Telepathy.ConnectionPresenceType.BUSY) {
|
||||
msg = _("%s is busy.").format(this.name);
|
||||
notify = false;
|
||||
} else
|
||||
return;
|
||||
|
||||
this._presence = presence;
|
||||
|
||||
if (message)
|
||||
msg += ' <i>(' + GLib.markup_escape_text(message, -1) + ')</i>';
|
||||
|
||||
this._ensureNotification();
|
||||
this._notification.appendMessage(msg, true);
|
||||
if (notify)
|
||||
this.notify(this._notification);
|
||||
}
|
||||
};
|
||||
|
||||
function Notification(id, source) {
|
||||
this._init(id, source);
|
||||
}
|
||||
|
||||
Notification.prototype = {
|
||||
__proto__: MessageTray.Notification.prototype,
|
||||
|
||||
_init: function(id, source) {
|
||||
MessageTray.Notification.prototype._init.call(this, id, source, source.name);
|
||||
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
|
||||
|
||||
this._responseEntry = new St.Entry({ style_class: 'chat-response' });
|
||||
this._responseEntry.clutter_text.connect('key-focus-in', Lang.bind(this, this._onEntryFocused));
|
||||
this._responseEntry.clutter_text.connect('activate', Lang.bind(this, this._onEntryActivated));
|
||||
this.setActionArea(this._responseEntry);
|
||||
|
||||
this._history = [];
|
||||
},
|
||||
|
||||
appendMessage: function(text, asTitle) {
|
||||
if (asTitle)
|
||||
this.update(text);
|
||||
else
|
||||
this.update(this.source.name, text);
|
||||
this._append(text, 'chat-received');
|
||||
},
|
||||
|
||||
_append: function(text, style) {
|
||||
let body = this.addBody(text);
|
||||
body.add_style_class_name(style);
|
||||
this.scrollTo(St.Side.BOTTOM);
|
||||
|
||||
let now = new Date().getTime() / 1000;
|
||||
this._history.unshift({ actor: body, time: now });
|
||||
|
||||
if (this._history.length > 1) {
|
||||
// Keep the scrollback from growing too long. If the most
|
||||
// recent message (before the one we just added) is within
|
||||
// SCROLLBACK_RECENT_TIME, we will keep
|
||||
// SCROLLBACK_RECENT_LENGTH previous messages. Otherwise
|
||||
// we'll keep SCROLLBACK_IDLE_LENGTH messages.
|
||||
|
||||
let lastMessageTime = this._history[1].time;
|
||||
let maxLength = (lastMessageTime < now - SCROLLBACK_RECENT_TIME) ?
|
||||
SCROLLBACK_IDLE_LENGTH : SCROLLBACK_RECENT_LENGTH;
|
||||
if (this._history.length > maxLength) {
|
||||
let expired = this._history.splice(maxLength);
|
||||
for (let i = 0; i < expired.length; i++)
|
||||
expired[i].actor.destroy();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onButtonPress: function(notification, event) {
|
||||
if (!this._active)
|
||||
return false;
|
||||
|
||||
let source = event.get_source ();
|
||||
while (source) {
|
||||
if (source == notification)
|
||||
return false;
|
||||
source = source.get_parent();
|
||||
}
|
||||
|
||||
// @source is outside @notification, which has to mean that
|
||||
// we have a pointer grab, and the user clicked outside the
|
||||
// notification, so we should deactivate.
|
||||
this._deactivate();
|
||||
return true;
|
||||
},
|
||||
|
||||
_onEntryFocused: function() {
|
||||
if (this._active)
|
||||
return;
|
||||
|
||||
if (!Main.pushModal(this.actor))
|
||||
return;
|
||||
Clutter.grab_pointer(this.actor);
|
||||
|
||||
this._active = true;
|
||||
Main.messageTray.lock();
|
||||
},
|
||||
|
||||
_onEntryActivated: function() {
|
||||
let text = this._responseEntry.get_text();
|
||||
if (text == '') {
|
||||
this._deactivate();
|
||||
return;
|
||||
}
|
||||
|
||||
this._responseEntry.set_text('');
|
||||
this._append(text, 'chat-sent');
|
||||
this.source.respond(text);
|
||||
},
|
||||
|
||||
_deactivate: function() {
|
||||
if (this._active) {
|
||||
Clutter.ungrab_pointer(this.actor);
|
||||
Main.popModal(this.actor);
|
||||
global.stage.set_key_focus(null);
|
||||
|
||||
// We have to do this after calling popModal(), because
|
||||
// that will return the keyboard focus to
|
||||
// this._responseEntry (because that's where it was when
|
||||
// pushModal() was called), which will cause
|
||||
// _onEntryFocused() to be called again, but we don't want
|
||||
// it to do anything.
|
||||
this._active = false;
|
||||
|
||||
Main.messageTray.unlock();
|
||||
}
|
||||
}
|
||||
};
|
@ -46,7 +46,7 @@ let slowDownFactor = 1.0;
|
||||
|
||||
// Called from Main.start
|
||||
function init() {
|
||||
let slowdownEnv = GLib.getenv("GNOME_SHELL_SLOWDOWN_FACTOR");
|
||||
let slowdownEnv = GLib.getenv('GNOME_SHELL_SLOWDOWN_FACTOR');
|
||||
if (slowdownEnv) {
|
||||
let factor = parseFloat(slowdownEnv);
|
||||
if (!isNaN(factor) && factor > 0.0)
|
||||
@ -190,7 +190,7 @@ function registerSpecialPropertySplitter(name, splitFunction, parameters) {
|
||||
}
|
||||
|
||||
|
||||
// The "FrameTicker" object is an object used to feed new frames to
|
||||
// The 'FrameTicker' object is an object used to feed new frames to
|
||||
// Tweener so it can update values and redraw. The default frame
|
||||
// ticker for Tweener just uses a simple timeout at a fixed frame rate
|
||||
// and has no idea of "catching up" by dropping frames.
|
||||
@ -243,12 +243,14 @@ ClutterFrameTicker.prototype = {
|
||||
|
||||
start : function() {
|
||||
this._timeline.start();
|
||||
global.begin_work();
|
||||
},
|
||||
|
||||
stop : function() {
|
||||
this._timeline.stop();
|
||||
this._startTime = -1;
|
||||
this._currentTime = -1;
|
||||
global.end_work();
|
||||
}
|
||||
};
|
||||
|
||||
|
364
js/ui/widget.js
364
js/ui/widget.js
@ -1,364 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
|
||||
const COLLAPSED_WIDTH = 24;
|
||||
const EXPANDED_WIDTH = 200;
|
||||
|
||||
const STATE_EXPANDED = 0;
|
||||
const STATE_COLLAPSING = 1;
|
||||
const STATE_COLLAPSED = 2;
|
||||
const STATE_EXPANDING = 3;
|
||||
const STATE_POPPING_OUT = 4;
|
||||
const STATE_POPPED_OUT = 5;
|
||||
const STATE_POPPING_IN = 6;
|
||||
|
||||
function Widget() {
|
||||
}
|
||||
|
||||
Widget.prototype = {
|
||||
// _init():
|
||||
//
|
||||
// Your widget constructor. Your constructor function should look
|
||||
// like:
|
||||
//
|
||||
// function MyWidgetType() {
|
||||
// this._init.apply(this, arguments);
|
||||
// }
|
||||
//
|
||||
// and your _init method should start by doing:
|
||||
//
|
||||
// Widget.Widget.prototype._init.apply(this, arguments);
|
||||
//
|
||||
// The _init method must define a field named "actor" containing
|
||||
// the Clutter.Actor to show in expanded mode. This actor will be
|
||||
// clipped to Widget.EXPANDED_WIDTH. Most widgets will also define
|
||||
// a field named "title" containing the title string to show above
|
||||
// the widget in the sidebar.
|
||||
//
|
||||
// If you want to have a separate collapsed view, you can define a
|
||||
// field "collapsedActor" containing the Clutter.Actor to show in
|
||||
// that mode. (It may be the same actor.) This actor will be
|
||||
// clipped to Widget.COLLAPSED_WIDTH, and will normally end up
|
||||
// having the same height as the main actor.
|
||||
//
|
||||
// If you do not set a collapsedActor, then you must set a title,
|
||||
// since that is what will be displayed in collapsed mode, and
|
||||
// in this case (and only in this case), the widget will support
|
||||
// pop-out, meaning that if the user hovers over its title while
|
||||
// the sidebar is collapsed, the widget's expanded view will pop
|
||||
// out of the sidebar until either the cursor moves out of it,
|
||||
// or else the widget calls this.activated() on itself.
|
||||
_init: function (initialState) {
|
||||
this.state = initialState;
|
||||
},
|
||||
|
||||
// destroy():
|
||||
//
|
||||
// Optional. Will be called when the widget is removed from the
|
||||
// sidebar. (Note that you don't need to destroy the actors,
|
||||
// since they will be destroyed for you.)
|
||||
|
||||
// collapse():
|
||||
//
|
||||
// Optional. Called during the sidebar collapse process, at the
|
||||
// point when the expanded sidebar has slid offscreen, but the
|
||||
// collapsed sidebar has not yet slid onscreen.
|
||||
|
||||
// expand():
|
||||
//
|
||||
// Optional. Called during the sidebar expand process, at the
|
||||
// point when the collapsed sidebar has slid offscreen, but the
|
||||
// expanded sidebar has not yet slid onscreen.
|
||||
|
||||
// activated():
|
||||
//
|
||||
// Emits the "activated" signal for you, which will cause pop-out
|
||||
// to end.
|
||||
activated: function() {
|
||||
this.emit('activated');
|
||||
}
|
||||
|
||||
// state:
|
||||
//
|
||||
// A field set on your widget by the sidebar. Will contain one of
|
||||
// the Widget.STATE_* values. (Eg, Widget.STATE_EXPANDED).
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Widget.prototype);
|
||||
|
||||
|
||||
function ClockWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
ClockWidget.prototype = {
|
||||
__proto__ : Widget.prototype,
|
||||
|
||||
_init: function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
||||
text: "",
|
||||
// Give an explicit height to ensure
|
||||
// it's the same in both modes
|
||||
height: COLLAPSED_WIDTH });
|
||||
|
||||
this.collapsedActor = new St.DrawingArea({ width: COLLAPSED_WIDTH,
|
||||
height: COLLAPSED_WIDTH });
|
||||
this.collapsedActor.connect('repaint', Lang.bind(this, this._repaintClock));
|
||||
|
||||
this._update();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this.timer)
|
||||
Mainloop.source_remove(this.timer);
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
this._update();
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
this._update();
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
this.currentTime = new Date();
|
||||
let msec_remaining = 60000 - (1000 * this.currentTime.getSeconds() +
|
||||
this.currentTime.getMilliseconds());
|
||||
if (msec_remaining < 500) {
|
||||
this.currentTime.setMinutes(this.currentTime.getMinutes() + 1);
|
||||
msec_remaining += 60000;
|
||||
}
|
||||
|
||||
if (this.state == STATE_COLLAPSED || this.state == STATE_COLLAPSING)
|
||||
this.collapsedActor.queue_repaint();
|
||||
else
|
||||
this._updateText();
|
||||
|
||||
if (this.timer)
|
||||
Mainloop.source_remove(this.timer);
|
||||
this.timer = Mainloop.timeout_add(msec_remaining, Lang.bind(this, this._update));
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateText: function(time) {
|
||||
// Translators: This is a time format.
|
||||
this.actor.set_text(this.currentTime.toLocaleFormat(_("%H:%M")));
|
||||
},
|
||||
|
||||
_repaintClock: function(area) {
|
||||
Shell.draw_clock(area,
|
||||
this.currentTime.getHours() % 12,
|
||||
this.currentTime.getMinutes());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const ITEM_ICON_SIZE = 48;
|
||||
const ITEM_PADDING = 1;
|
||||
const ITEM_SPACING = 4;
|
||||
|
||||
const ITEM_BG_COLOR = new Clutter.Color();
|
||||
ITEM_BG_COLOR.from_pixel(0x00000000);
|
||||
const ITEM_NAME_COLOR = new Clutter.Color();
|
||||
ITEM_NAME_COLOR.from_pixel(0x000000ff);
|
||||
|
||||
function LauncherWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
LauncherWidget.prototype = {
|
||||
__proto__ : Widget.prototype,
|
||||
|
||||
addItem : function(info) {
|
||||
let item = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
width: EXPANDED_WIDTH,
|
||||
height: ITEM_ICON_SIZE,
|
||||
padding: ITEM_PADDING,
|
||||
spacing: ITEM_SPACING,
|
||||
reactive: true });
|
||||
item._info = info;
|
||||
item.append(info.createIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
|
||||
item.append(new Clutter.Text({ color: ITEM_NAME_COLOR,
|
||||
font_name: "Sans 14px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: info.name }),
|
||||
Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.append(item, Big.BoxPackFlags.NONE);
|
||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
||||
|
||||
if (!this.collapsedActor)
|
||||
return;
|
||||
|
||||
item = new Big.Box({ width: COLLAPSED_WIDTH,
|
||||
height: COLLAPSED_WIDTH,
|
||||
padding: ITEM_PADDING,
|
||||
reactive: true });
|
||||
item._info = info;
|
||||
item.append(info.createIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
|
||||
Big.BoxPackFlags.NONE);
|
||||
|
||||
this.collapsedActor.append(item, Big.BoxPackFlags.NONE);
|
||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
||||
},
|
||||
|
||||
clear : function() {
|
||||
let children, i;
|
||||
|
||||
children = this.actor.get_children();
|
||||
for (i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
|
||||
if (this.collapsedActor) {
|
||||
children = this.collapsedActor.get_children();
|
||||
for (i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_buttonPress : function(item) {
|
||||
Clutter.grab_pointer(item);
|
||||
item._buttonDown = true;
|
||||
item._inItem = true;
|
||||
this._updateItemState(item);
|
||||
return true;
|
||||
},
|
||||
|
||||
_leave : function(item, evt) {
|
||||
if (evt.get_source() == item && item._buttonDown) {
|
||||
item._inItem = false;
|
||||
this._updateItemState(item);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_enter : function(item, evt) {
|
||||
if (evt.get_source() == item && item._buttonDown) {
|
||||
item._inItem = true;
|
||||
this._updateItemState(item);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_buttonRelease : function(item) {
|
||||
Clutter.ungrab_pointer(item);
|
||||
item._buttonDown = false;
|
||||
this._updateItemState(item);
|
||||
|
||||
if (item._inItem) {
|
||||
item._info.launch();
|
||||
this.activated();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_updateItemState : function(item) {
|
||||
if (item._buttonDown && item._inItem) {
|
||||
item.padding_top = item.padding_left = 2 * ITEM_PADDING;
|
||||
item.padding_bottom = item.padding_right = 0;
|
||||
} else
|
||||
item.padding = ITEM_PADDING;
|
||||
}
|
||||
};
|
||||
|
||||
function AppsWidgetInfo(appInfo) {
|
||||
this._init(appInfo);
|
||||
}
|
||||
|
||||
AppsWidgetInfo.prototype = {
|
||||
_init : function(appInfo) {
|
||||
this._info = appInfo;
|
||||
this.name = appInfo.get_name();
|
||||
},
|
||||
|
||||
createIcon : function(size) {
|
||||
return this._info.create_icon_texture(size);
|
||||
},
|
||||
|
||||
launch : function() {
|
||||
this._info.launch();
|
||||
}
|
||||
};
|
||||
|
||||
function AppsWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
AppsWidget.prototype = {
|
||||
__proto__ : LauncherWidget.prototype,
|
||||
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = _("Applications");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
this.collapsedActor = new Big.Box({ spacing: 2});
|
||||
|
||||
let appSystem = Shell.AppSystem.get_default();
|
||||
let apps = AppFavorites.getAppFavorites().getFavorites();
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
this.addItem(new AppsWidgetInfo(apps[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function RecentDocsWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
RecentDocsWidget.prototype = {
|
||||
__proto__ : LauncherWidget.prototype,
|
||||
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = _("Recent Documents");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
|
||||
this._recentManager = Gtk.RecentManager.get_default();
|
||||
this._recentManager.connect('changed', Lang.bind(this, this._recentChanged));
|
||||
this._recentChanged();
|
||||
},
|
||||
|
||||
_recentChanged: function() {
|
||||
let i;
|
||||
|
||||
this.clear();
|
||||
|
||||
let items = [];
|
||||
let docs = this._recentManager.get_items();
|
||||
for (i = 0; i < docs.length; i++) {
|
||||
let docInfo = new DocInfo.DocInfo (docs[i]);
|
||||
|
||||
items.push(docInfo);
|
||||
}
|
||||
|
||||
items.sort(function (a,b) { return b.timestamp - a.timestamp; });
|
||||
for (i = 0; i < Math.min(items.length, 5); i++)
|
||||
this.addItem(items[i]);
|
||||
}
|
||||
};
|
@ -1,395 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Widget = imports.ui.widget;
|
||||
|
||||
const WIDGETBOX_BG_COLOR = new Clutter.Color();
|
||||
WIDGETBOX_BG_COLOR.from_pixel(0xf0f0f0ff);
|
||||
const BLACK = new Clutter.Color();
|
||||
BLACK.from_pixel(0x000000ff);
|
||||
|
||||
const WIDGETBOX_PADDING = 2;
|
||||
const ANIMATION_TIME = 0.5;
|
||||
const POP_IN_LAG = 250; /* milliseconds */
|
||||
|
||||
function WidgetBox(widget, expanded) {
|
||||
this._init(widget, expanded);
|
||||
}
|
||||
|
||||
WidgetBox.prototype = {
|
||||
_init: function(widget, expanded) {
|
||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
||||
|
||||
if (widget instanceof Widget.Widget) {
|
||||
this._widget = widget;
|
||||
this._widget.state = this.state;
|
||||
} else {
|
||||
let ctor = this._ctorFromName(widget);
|
||||
this._widget = new ctor(this.state);
|
||||
}
|
||||
|
||||
if (!this._widget.actor)
|
||||
throw new Error("widget has no actor");
|
||||
else if (!this._widget.title && !this._widget.collapsedActor)
|
||||
throw new Error("widget has neither title nor collapsedActor");
|
||||
|
||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
||||
|
||||
// The structure of a WidgetBox:
|
||||
//
|
||||
// The top level is a Clutter.Group, which exists to make
|
||||
// pop-out work correctly; when another widget pops out, its
|
||||
// width will increase, which will in turn cause the sidebar's
|
||||
// width to increase, which will cause the sidebar to increase
|
||||
// the width of each of its children (the WidgetBoxes). But we
|
||||
// don't want the non-popped-out widgets to expand, so we make
|
||||
// the top-level actor be a Clutter.Group, which will accept
|
||||
// the new width from the Sidebar, but not impose it on its
|
||||
// own child.
|
||||
//
|
||||
// Inside the toplevel group is a horizontal Big.Box
|
||||
// containing 2 Clutter.Groups; one for the collapsed state
|
||||
// (cgroup) and one for the expanded state (egroup). Each
|
||||
// group contains a single vertical Big.Box (cbox and ebox
|
||||
// respectively), which have the appropriate fixed width. The
|
||||
// cbox contains either the collapsed widget actor or else the
|
||||
// rotated title. The ebox contains the horizontal title (if
|
||||
// any), separator line, and the expanded widget actor. (If
|
||||
// the widget doesn't have a collapsed actor, and therefore
|
||||
// supports pop-out, then it will also have a vertical line
|
||||
// between the two groups, which will only be shown during
|
||||
// pop-out.)
|
||||
//
|
||||
// In the expanded view, cgroup is hidden and egroup is shown.
|
||||
// When animating to the collapsed view, first the ebox is
|
||||
// slid offscreen by giving it increasingly negative x
|
||||
// coordinates within egroup. Then once it's fully offscreen,
|
||||
// we hide egroup, show cgroup, and slide cbox back in in the
|
||||
// same way.
|
||||
//
|
||||
// The pop-out view works similarly to the second half of the
|
||||
// collapsed-to-expanded transition, except that the
|
||||
// horizontal title gets hidden to avoid duplication.
|
||||
|
||||
this.actor = new Clutter.Group();
|
||||
this._hbox = new Big.Box({ background_color: WIDGETBOX_BG_COLOR,
|
||||
padding_top: WIDGETBOX_PADDING,
|
||||
padding_bottom: WIDGETBOX_PADDING,
|
||||
padding_right: WIDGETBOX_PADDING,
|
||||
// Left padding is here to make up for
|
||||
// the X offset used for the sidebar
|
||||
// to hide its rounded corners
|
||||
padding_left: 2 * WIDGETBOX_PADDING,
|
||||
spacing: WIDGETBOX_PADDING,
|
||||
corner_radius: WIDGETBOX_PADDING,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
reactive: true });
|
||||
this.actor.add_actor(this._hbox);
|
||||
|
||||
this._cgroup = new Clutter.Group({ clip_to_allocation: true });
|
||||
this._hbox.append(this._cgroup, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._cbox = new Big.Box({ width: Widget.COLLAPSED_WIDTH,
|
||||
clip_to_allocation: true });
|
||||
this._cgroup.add_actor(this._cbox);
|
||||
|
||||
if (this._widget.collapsedActor) {
|
||||
if (this._widget.collapsedActor == this._widget.actor)
|
||||
this._singleActor = true;
|
||||
else {
|
||||
this._cbox.append(this._widget.collapsedActor,
|
||||
Big.BoxPackFlags.NONE);
|
||||
}
|
||||
} else {
|
||||
let vtitle = new Clutter.Text({ font_name: "Sans 16px",
|
||||
text: this._widget.title,
|
||||
rotation_angle_z: -90.0 });
|
||||
let signalId = vtitle.connect('notify::allocation',
|
||||
function () {
|
||||
vtitle.disconnect(signalId);
|
||||
vtitle.set_anchor_point(vtitle.natural_width, 0);
|
||||
vtitle.set_size(vtitle.natural_height,
|
||||
vtitle.natural_width);
|
||||
});
|
||||
this._vtitle = vtitle;
|
||||
this._cbox.append(this._vtitle, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._vline = new Clutter.Rectangle({ color: BLACK, width: 1 });
|
||||
this._hbox.append(this._vline, Big.BoxPackFlags.NONE);
|
||||
this._vline.hide();
|
||||
|
||||
// Set up pop-out
|
||||
this._eventHandler = this._hbox.connect('captured-event',
|
||||
Lang.bind(this, this._popEventHandler));
|
||||
this._activationHandler = this._widget.connect('activated',
|
||||
Lang.bind(this, this._activationHandler));
|
||||
}
|
||||
|
||||
this._egroup = new Clutter.Group({ clip_to_allocation: true });
|
||||
this._hbox.append(this._egroup, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._ebox = new Big.Box({ spacing: WIDGETBOX_PADDING,
|
||||
width: Widget.EXPANDED_WIDTH,
|
||||
clip_to_allocation: true });
|
||||
this._egroup.add_actor(this._ebox);
|
||||
|
||||
if (this._widget.title) {
|
||||
this._htitle = new Clutter.Text({ font_name: "Sans 16px",
|
||||
text: this._widget.title });
|
||||
this._ebox.append(this._htitle, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._hline = new Clutter.Rectangle({ color: BLACK, height: 1 });
|
||||
this._ebox.append(this._hline, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
if (expanded)
|
||||
this._setWidgetExpanded();
|
||||
else
|
||||
this._setWidgetCollapsed();
|
||||
},
|
||||
|
||||
// Given a name like "imports.ui.widget.ClockWidget", turn that
|
||||
// into a constructor function
|
||||
_ctorFromName: function(name) {
|
||||
// Make sure it's a valid import
|
||||
if (!name.match(/^imports(\.[a-zA-Z0-9_]+)+$/))
|
||||
throw new Error("widget name must start with 'imports.'");
|
||||
if (name.match(/^imports\.gi\./))
|
||||
throw new Error("cannot import widget from GIR");
|
||||
|
||||
let ctor = eval(name);
|
||||
|
||||
// Make sure it's really a constructor
|
||||
if (!ctor || typeof(ctor) != "function")
|
||||
throw new Error("widget name is not a constructor");
|
||||
|
||||
// Make sure it's a widget
|
||||
let proto = ctor.prototype;
|
||||
while (proto && proto != Widget.Widget.prototype)
|
||||
proto = proto.__proto__;
|
||||
if (!proto)
|
||||
throw new Error("widget does not inherit from Widget prototype");
|
||||
|
||||
return ctor;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._expandPart1Complete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_EXPANDING;
|
||||
},
|
||||
|
||||
_setWidgetExpanded: function() {
|
||||
this._cgroup.hide();
|
||||
this._egroup.show();
|
||||
|
||||
if (this._singleActor) {
|
||||
this._widget.actor.get_parent().remove_actor(this._widget.actor);
|
||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
if (this._htitle) {
|
||||
this._htitle.show();
|
||||
this._hline.show();
|
||||
}
|
||||
},
|
||||
|
||||
_expandPart1Complete: function() {
|
||||
this._cbox.x = 0;
|
||||
this._setWidgetExpanded();
|
||||
|
||||
if (this._widget.expand) {
|
||||
try {
|
||||
this._widget.expand();
|
||||
} catch (e) {
|
||||
logError(e, 'Widget failed to expand');
|
||||
}
|
||||
}
|
||||
|
||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
||||
Tweener.addTween(this._ebox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._expandComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_expandComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_EXPANDED;
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._collapsePart1Complete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSING;
|
||||
},
|
||||
|
||||
_setWidgetCollapsed: function() {
|
||||
this._egroup.hide();
|
||||
this._cgroup.show();
|
||||
|
||||
if (this._singleActor) {
|
||||
this._widget.actor.get_parent().remove_actor(this._widget.actor);
|
||||
this._cbox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
if (this._htitle) {
|
||||
this._htitle.hide();
|
||||
this._hline.hide();
|
||||
}
|
||||
|
||||
if (this._vtitle)
|
||||
this._cbox.height = this._ebox.height;
|
||||
},
|
||||
|
||||
_collapsePart1Complete: function() {
|
||||
this._ebox.x = 0;
|
||||
this._setWidgetCollapsed();
|
||||
|
||||
if (this._widget.collapse) {
|
||||
try {
|
||||
this._widget.collapse();
|
||||
} catch (e) {
|
||||
logError(e, 'Widget failed to collapse');
|
||||
}
|
||||
}
|
||||
|
||||
this._cbox.x = -Widget.COLLAPSED_WIDTH;
|
||||
Tweener.addTween(this._cbox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._collapseComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_collapseComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
||||
},
|
||||
|
||||
_popEventHandler: function(actor, event) {
|
||||
let type = event.type();
|
||||
|
||||
if (type == Clutter.EventType.ENTER) {
|
||||
this._clearPopInTimeout();
|
||||
if (this.state == Widget.STATE_COLLAPSED ||
|
||||
this.state == Widget.STATE_COLLAPSING) {
|
||||
this._popOut();
|
||||
return false;
|
||||
}
|
||||
} else if (type == Clutter.EventType.LEAVE &&
|
||||
(this.state == Widget.STATE_POPPED_OUT ||
|
||||
this.state == Widget.STATE_POPPING_OUT)) {
|
||||
// If moving into another actor within this._hbox, let the
|
||||
// event be propagated
|
||||
let into = event.get_related();
|
||||
while (into) {
|
||||
if (into == this._hbox)
|
||||
return false;
|
||||
into = into.get_parent();
|
||||
}
|
||||
|
||||
// Else, moving out of this._hbox
|
||||
this._setPopInTimeout();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_activationHandler: function() {
|
||||
if (this.state == Widget.STATE_POPPED_OUT)
|
||||
this._popIn();
|
||||
},
|
||||
|
||||
_popOut: function() {
|
||||
if (this.state != Widget.STATE_COLLAPSED &&
|
||||
this.state != Widget.STATE_COLLAPSING)
|
||||
return;
|
||||
|
||||
this._vline.show();
|
||||
this._egroup.show();
|
||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
||||
Tweener.addTween(this._ebox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._popOutComplete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_POPPING_OUT;
|
||||
|
||||
Main.chrome.trackActor(this._hbox, { affectsStruts: false });
|
||||
},
|
||||
|
||||
_popOutComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_POPPED_OUT;
|
||||
},
|
||||
|
||||
_setPopInTimeout: function() {
|
||||
this._clearPopInTimeout();
|
||||
this._popInTimeout = Mainloop.timeout_add(POP_IN_LAG, Lang.bind(this, function () { this._popIn(); return false; }));
|
||||
},
|
||||
|
||||
_clearPopInTimeout: function() {
|
||||
if (this._popInTimeout) {
|
||||
Mainloop.source_remove(this._popInTimeout);
|
||||
delete this._popInTimeout;
|
||||
}
|
||||
},
|
||||
|
||||
_popIn: function() {
|
||||
this._clearPopInTimeout();
|
||||
|
||||
if (this.state != Widget.STATE_POPPED_OUT &&
|
||||
this.state != Widget.STATE_POPPING_OUT)
|
||||
return;
|
||||
|
||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._popInComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_popInComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
||||
this._vline.hide();
|
||||
this._egroup.hide();
|
||||
this._ebox.x = 0;
|
||||
|
||||
Main.chrome.untrackActor(this._hbox);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
restore: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._widget.destroy)
|
||||
this._widget.destroy();
|
||||
}
|
||||
};
|
||||
|
@ -103,7 +103,7 @@ WindowManager.prototype = {
|
||||
x: xDest,
|
||||
y: 0,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._minimizeWindowDone,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [shellwm, actor],
|
||||
@ -152,17 +152,15 @@ WindowManager.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.CENTER);
|
||||
actor.set_scale(0.0, 0.0);
|
||||
actor.opacity = 0;
|
||||
actor.show();
|
||||
|
||||
/* scale window up from 0x0 to normal size */
|
||||
|
||||
/* Fade window in */
|
||||
this._mapping.push(actor);
|
||||
Tweener.addTween(actor,
|
||||
{ scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
{ opacity: 255,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._mapWindowDone,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [shellwm, actor],
|
||||
@ -175,8 +173,7 @@ WindowManager.prototype = {
|
||||
_mapWindowDone : function(shellwm, actor) {
|
||||
if (this._removeEffect(this._mapping, actor)) {
|
||||
Tweener.removeTweens(actor);
|
||||
actor.set_scale(1.0, 1.0);
|
||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.NORTH_WEST);
|
||||
actor.opacity = 255;
|
||||
shellwm.completed_map(actor);
|
||||
}
|
||||
},
|
||||
@ -261,7 +258,7 @@ WindowManager.prototype = {
|
||||
{ x: xDest,
|
||||
y: yDest,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: this._switchWorkspaceDone,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [shellwm]
|
||||
@ -270,7 +267,7 @@ WindowManager.prototype = {
|
||||
{ x: 0,
|
||||
y: 0,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
},
|
||||
|
||||
@ -309,7 +306,7 @@ WindowManager.prototype = {
|
||||
|
||||
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
|
||||
/* We don't support this kind of layout */
|
||||
if (binding == "switch_to_workspace_up" || binding == "switch_to_workspace_down")
|
||||
if (binding == 'switch_to_workspace_up' || binding == 'switch_to_workspace_down')
|
||||
return;
|
||||
|
||||
if (global.screen.n_workspaces == 1)
|
||||
@ -318,11 +315,11 @@ WindowManager.prototype = {
|
||||
if (this._workspaceSwitcherPopup == null)
|
||||
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
||||
|
||||
if (binding == "switch_to_workspace_left") {
|
||||
if (binding == 'switch_to_workspace_left') {
|
||||
this.actionMoveWorkspaceLeft();
|
||||
}
|
||||
|
||||
if (binding == "switch_to_workspace_right") {
|
||||
if (binding == 'switch_to_workspace_right') {
|
||||
this.actionMoveWorkspaceRight();
|
||||
}
|
||||
},
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GdkPixbuf = imports.gi.GdkPixbuf;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
@ -122,11 +121,8 @@ WindowClone.prototype = {
|
||||
Lang.bind(this, this._onScroll));
|
||||
|
||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||
this.actor.connect('enter-event',
|
||||
Lang.bind(this, this._onEnter));
|
||||
this.actor.connect('leave-event',
|
||||
Lang.bind(this, this._onLeave));
|
||||
this._havePointer = false;
|
||||
|
||||
this._draggable = DND.makeDraggable(this.actor,
|
||||
{ dragActorMaxSize: WINDOW_DND_SIZE,
|
||||
@ -135,6 +131,7 @@ WindowClone.prototype = {
|
||||
this._draggable.connect('drag-end', Lang.bind(this, this._onDragEnd));
|
||||
this.inDrag = false;
|
||||
|
||||
this._windowIsZooming = false;
|
||||
this._zooming = false;
|
||||
this._selected = false;
|
||||
},
|
||||
@ -179,23 +176,7 @@ WindowClone.prototype = {
|
||||
this.disconnectAll();
|
||||
},
|
||||
|
||||
_onEnter: function (actor, event) {
|
||||
// If the user drags faster than we can follow, he'll end up
|
||||
// leaving the window temporarily and then re-entering it
|
||||
if (this.inDrag)
|
||||
return;
|
||||
|
||||
this._havePointer = true;
|
||||
},
|
||||
|
||||
_onLeave: function (actor, event) {
|
||||
// If the user drags faster than we can follow, he'll end up
|
||||
// leaving the window temporarily and then re-entering it
|
||||
if (this.inDrag)
|
||||
return;
|
||||
|
||||
this._havePointer = false;
|
||||
|
||||
if (this._zoomStep)
|
||||
this._zoomEnd();
|
||||
},
|
||||
@ -298,14 +279,6 @@ WindowClone.prototype = {
|
||||
_onDragEnd : function (draggable, time, snapback) {
|
||||
this.inDrag = false;
|
||||
|
||||
// Most likely, the clone is going to move away from the
|
||||
// pointer now. But that won't cause a leave-event, so
|
||||
// do this by hand. Of course, if the window only snaps
|
||||
// back a short distance, this might be wrong, but it's
|
||||
// better to have the label mysteriously missing than
|
||||
// mysteriously present
|
||||
this._havePointer = false;
|
||||
|
||||
// We may not have a parent if DnD completed successfully, in
|
||||
// which case our clone will shortly be destroyed and replaced
|
||||
// with a new one on the target workspace.
|
||||
@ -352,7 +325,7 @@ DesktopClone.prototype = {
|
||||
Tweener.addTween(this._desktop,
|
||||
{ opacity: 255,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
transition: 'easeOutQuad' });
|
||||
}
|
||||
},
|
||||
|
||||
@ -366,7 +339,7 @@ DesktopClone.prototype = {
|
||||
Tweener.addTween(this._desktop,
|
||||
{ opacity: 0,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this,
|
||||
function() {
|
||||
this._desktop.hide();
|
||||
@ -401,7 +374,7 @@ WindowOverlay.prototype = {
|
||||
this._windowClone = windowClone;
|
||||
this._parentActor = parentActor;
|
||||
|
||||
let title = new St.Label({ style_class: "window-caption",
|
||||
let title = new St.Label({ style_class: 'window-caption',
|
||||
text: metaWindow.title });
|
||||
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
||||
title._spacing = 0;
|
||||
@ -411,7 +384,7 @@ WindowOverlay.prototype = {
|
||||
this.title.text = w.title;
|
||||
}));
|
||||
|
||||
let button = new St.Button({ style_class: "window-close" });
|
||||
let button = new St.Button({ style_class: 'window-close' });
|
||||
button._overlap = 0;
|
||||
|
||||
this._idleToggleCloseId = 0;
|
||||
@ -450,7 +423,7 @@ WindowOverlay.prototype = {
|
||||
},
|
||||
|
||||
show: function() {
|
||||
let [child, x, y, mask] = Gdk.Screen.get_default().get_root_window().get_pointer();
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
|
||||
x, y);
|
||||
if (actor == this._windowClone.actor) {
|
||||
@ -466,7 +439,7 @@ WindowOverlay.prototype = {
|
||||
Tweener.addTween(this.title,
|
||||
{ opacity: 255,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
transition: 'easeOutQuad' });
|
||||
},
|
||||
|
||||
chromeWidth: function () {
|
||||
@ -560,7 +533,7 @@ WindowOverlay.prototype = {
|
||||
|
||||
_idleToggleCloseButton: function() {
|
||||
this._idleToggleCloseId = 0;
|
||||
let [child, x, y, mask] = Gdk.Screen.get_default().get_root_window().get_pointer();
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
let actor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE,
|
||||
x, y);
|
||||
if (actor != this._windowClone.actor && actor != this.closeButton) {
|
||||
@ -652,10 +625,11 @@ Workspace.prototype = {
|
||||
this._desktop.connect('selected',
|
||||
Lang.bind(this,
|
||||
function(clone, time) {
|
||||
// Only switch to the workspace when one window is open
|
||||
// We check for "2" here because the Desktop does not really count
|
||||
// as a window in this context.
|
||||
if (this._windows.length <= 2) {
|
||||
// Only switch to the workspace when there's no application windows
|
||||
// open (we always have one window for the desktop). The problem
|
||||
// is that it's too easy to miss an app window and get the wrong
|
||||
// one focused.
|
||||
if (this._windows.length == 1) {
|
||||
this.metaWorkspace.activate(time);
|
||||
Main.overview.hide();
|
||||
}
|
||||
@ -1049,8 +1023,13 @@ Workspace.prototype = {
|
||||
(desiredHeight - buttonOuterHeight - captionHeight) / rect.height,
|
||||
1.0 / this.scale);
|
||||
|
||||
x = xCenter - 0.5 * scale * rect.width;
|
||||
y = y + height - rect.height * scale - captionHeight;
|
||||
x = Math.floor(xCenter - 0.5 * scale * rect.width);
|
||||
|
||||
// We want to center the window in case we have just one
|
||||
if (metaWindow.get_workspace().n_windows == 1)
|
||||
y = Math.floor(yCenter * global.screen_height - 0.5 * scale * rect.height);
|
||||
else
|
||||
y = Math.floor(y + height - rect.height * scale - captionHeight);
|
||||
|
||||
return [x, y, scale];
|
||||
},
|
||||
@ -1126,7 +1105,7 @@ Workspace.prototype = {
|
||||
Tweener.addTween(clone.actor,
|
||||
{ opacity: 255,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeInQuad"
|
||||
transition: 'easeInQuad'
|
||||
});
|
||||
}
|
||||
|
||||
@ -1137,7 +1116,7 @@ Workspace.prototype = {
|
||||
scale_y: scale,
|
||||
workspace_relative: workspaceZooming ? this : null,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, function() {
|
||||
this._fadeInWindowOverlay(clone, overlay);
|
||||
})
|
||||
@ -1169,6 +1148,9 @@ Workspace.prototype = {
|
||||
},
|
||||
|
||||
_fadeInWindowOverlay: function(clone, overlay) {
|
||||
if (clone.inDrag)
|
||||
return;
|
||||
|
||||
// This is a little messy and complicated because when we
|
||||
// start the fade-in we may not have done the final positioning
|
||||
// of the workspaces. (Tweener doesn't necessarily finish
|
||||
@ -1209,8 +1191,10 @@ Workspace.prototype = {
|
||||
},
|
||||
|
||||
_delayedWindowRepositioning: function() {
|
||||
let [child, x, y, mask] =
|
||||
Gdk.Screen.get_default().get_root_window().get_pointer();
|
||||
if (this._windowIsZooming)
|
||||
return true;
|
||||
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
let wsWidth = this.actor.width * this.scale;
|
||||
let wsHeight = this.actor.height * this.scale;
|
||||
|
||||
@ -1282,8 +1266,7 @@ Workspace.prototype = {
|
||||
}
|
||||
|
||||
// setup new handler
|
||||
let [child, x, y, mask] =
|
||||
Gdk.Screen.get_default().get_root_window().get_pointer();
|
||||
let [x, y, mask] = global.get_pointer();
|
||||
this._cursorX = x;
|
||||
this._cursorY = y;
|
||||
|
||||
@ -1387,7 +1370,7 @@ Workspace.prototype = {
|
||||
workspace_relative: this,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
opacity: 255,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
} else {
|
||||
// The window is hidden, make it shrink and fade it out
|
||||
@ -1397,7 +1380,7 @@ Workspace.prototype = {
|
||||
opacity: 0,
|
||||
workspace_relative: this,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1420,7 +1403,7 @@ Workspace.prototype = {
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: Lang.bind(this, this._fadeInAllOverlays)
|
||||
});
|
||||
},
|
||||
@ -1440,7 +1423,7 @@ Workspace.prototype = {
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
|
||||
this._visible = true;
|
||||
@ -1462,7 +1445,7 @@ Workspace.prototype = {
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: onComplete
|
||||
});
|
||||
|
||||
@ -1533,6 +1516,14 @@ Workspace.prototype = {
|
||||
this.emit('window-drag-end', clone.actor);
|
||||
overlay.show();
|
||||
}));
|
||||
clone.connect('zoom-start',
|
||||
Lang.bind(this, function() {
|
||||
this._windowIsZooming = true;
|
||||
}));
|
||||
clone.connect('zoom-end',
|
||||
Lang.bind(this, function() {
|
||||
this._windowIsZooming = false;
|
||||
}));
|
||||
|
||||
this.actor.add_actor(clone.actor);
|
||||
|
||||
|
@ -5,6 +5,7 @@ const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
@ -25,12 +26,12 @@ WorkspaceSwitcherPopup.prototype = {
|
||||
y: 0,
|
||||
width: global.screen_width,
|
||||
height: global.screen_height });
|
||||
global.stage.add_actor(this.actor);
|
||||
Main.uiGroup.add_actor(this.actor);
|
||||
|
||||
this._scaleWidth = global.screen_width / global.screen_height;
|
||||
|
||||
this._container = new St.BoxLayout({ style_class: "workspace-switcher-container" });
|
||||
this._list = new St.BoxLayout({ style_class: "workspace-switcher" });
|
||||
this._container = new St.BoxLayout({ style_class: 'workspace-switcher-container' });
|
||||
this._list = new St.BoxLayout({ style_class: 'workspace-switcher' });
|
||||
|
||||
this._container.add(this._list);
|
||||
|
||||
@ -72,7 +73,7 @@ WorkspaceSwitcherPopup.prototype = {
|
||||
_show : function() {
|
||||
Tweener.addTween(this._container, { opacity: 255,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
this._position();
|
||||
this.actor.show();
|
||||
@ -91,7 +92,7 @@ WorkspaceSwitcherPopup.prototype = {
|
||||
this._timeoutId = 0;
|
||||
Tweener.addTween(this._container, { opacity: 0.0,
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
transition: 'easeOutQuad',
|
||||
onComplete: function() { this.actor.hide(); },
|
||||
onCompleteScope: this
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -27,5 +27,6 @@ sr
|
||||
sr@latin
|
||||
sv
|
||||
tr
|
||||
uk
|
||||
vi
|
||||
zh_CN
|
||||
|
@ -1,4 +1,6 @@
|
||||
data/gnome-shell.desktop.in.in
|
||||
data/gnome-shell-clock-preferences.desktop.in.in
|
||||
[type: gettext/glade]data/clock-preferences.ui
|
||||
js/ui/appDisplay.js
|
||||
js/ui/appFavorites.js
|
||||
js/ui/dash.js
|
||||
@ -9,8 +11,8 @@ js/ui/panel.js
|
||||
js/ui/placeDisplay.js
|
||||
js/ui/runDialog.js
|
||||
js/ui/statusMenu.js
|
||||
js/ui/widget.js
|
||||
js/ui/windowAttentionHandler.js
|
||||
js/ui/workspacesView.js
|
||||
src/gdmuser/gdm-user.c
|
||||
src/shell-global.c
|
||||
src/shell-uri-util.c
|
||||
|
@ -1 +1,2 @@
|
||||
data/gnome-shell.desktop.in
|
||||
data/gnome-shell-clock-preferences.desktop.in
|
||||
|
243
po/ar.po
243
po/ar.po
@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-01-17 11:29+0200\n"
|
||||
"PO-Revision-Date: 2010-01-17 11:29+0300\n"
|
||||
"POT-Creation-Date: 2010-05-15 23:40+0300\n"
|
||||
"PO-Revision-Date: 2010-05-15 23:40+0300\n"
|
||||
"Last-Translator: Khaled Hosny <khaledhosny@eglug.org>\n"
|
||||
"Language-Team: Arabic <doc@arabeyes.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -15,8 +15,8 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ar\n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
"X-Generator: Virtaal 0.5.1\n"
|
||||
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
|
||||
"X-Generator: Virtaal 0.6.0\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
@ -26,97 +26,237 @@ msgstr "صدفة جنوم"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "إدارة النوافذ وإطلاق التطبيقات"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "الساعة"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "طوّع ساعة اللوحة"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "التطبيقات"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "التفضيلات"
|
||||
|
||||
#: ../js/ui/appDisplay.js:644
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "نافذة جديدة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:648
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "أزِل من المفضّلة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "أضِف إلى المفضّلة"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1001
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "اسحب إلى هنا ليضاف إلى المفضّلة"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "ابحث..."
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "أضيف %s إلى مفضلتك."
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "أزيل %s من مفضّلتك."
|
||||
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "ابحث"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "يبحث..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "لا نتائج مطابقة."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "الأماكن والأجهزة"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "العناصر الحديثة"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:354
|
||||
msgid "No extensions installed"
|
||||
msgstr "لم تثبّت أية امتدادات"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:391
|
||||
msgid "Enabled"
|
||||
msgstr "مفعّل"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Disabled"
|
||||
msgstr "معطّل"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Error"
|
||||
msgstr "خطأ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Out of date"
|
||||
msgstr "غير محدث"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:422
|
||||
msgid "View Source"
|
||||
msgstr "اعرض المصدر"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:428
|
||||
msgid "Web Page"
|
||||
msgstr "صفحة الوب"
|
||||
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "تراجع"
|
||||
|
||||
#: ../js/ui/panel.js:535
|
||||
msgid "Quit"
|
||||
msgstr "أنهِ"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
#: ../js/ui/panel.js:740
|
||||
msgid "Activities"
|
||||
msgstr "الأنشطة"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:955
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%A %e %B، %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:956
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%A %e %B، %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:960
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%A %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:961
|
||||
msgid "%a %R"
|
||||
msgstr "%A %R"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:968
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%A %e %B، %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:969
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%A %e %B، %l:%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:973
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%A %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:974
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A %Ol:%OM %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "فشل فصْل '%s'"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "أعد المحاولة"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "اتّصل ب..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "من فضلك اكتب أمرا:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "فشل تنفيذ '%s':"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%OH:%OM"
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "متاح"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "التطبيقات"
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "مشغول"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "المستندات الحديثة"
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "خفي"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "معلومات الحساب..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "تفضيلات النظام..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "أوصد الشاشة"
|
||||
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "بدّل المستخدم"
|
||||
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "اخرج..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "أطفئ..."
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "انتهى %s من البدء"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' جاهز"
|
||||
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr "تعذّر إضافة مساحة عمل جديدة، لتجاوز أقصى عدد من مساحات العمل."
|
||||
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "لا يمكن حذف مساحة العمل الأولى."
|
||||
|
||||
#: ../src/shell-global.c:979
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "منذ أقل من دقيقة"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#: ../src/shell-global.c:983
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -127,7 +267,7 @@ msgstr[3] "منذ %d دقائق"
|
||||
msgstr[4] "منذ %d دقيقة"
|
||||
msgstr[5] "منذ %d دقيقة"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#: ../src/shell-global.c:988
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -138,7 +278,7 @@ msgstr[3] "منذ %d ساعات"
|
||||
msgstr[4] "منذ %d ساعة"
|
||||
msgstr[5] "منذ %d ساعة"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#: ../src/shell-global.c:993
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -149,7 +289,7 @@ msgstr[3] "منذ %d أيام"
|
||||
msgstr[4] "منذ %d يوما"
|
||||
msgstr[5] "منذ %d يوم"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#: ../src/shell-global.c:998
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -184,6 +324,15 @@ msgstr "ابحث"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%OH:%OM"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "التطبيقات"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "المستندات الحديثة"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "متكرر"
|
||||
|
||||
@ -211,26 +360,8 @@ msgstr "%1$s: %2$s"
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "تعذّر الخروج: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "معلومات الحساب..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "الشريط الجانبي"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "تفضيلات النظام..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "أوصد الشاشة"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "بدّل المستخدم"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "اخرج..."
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "أطفئ..."
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "استعرض"
|
||||
|
42
po/cs.po
42
po/cs.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-20 03:11+0100\n"
|
||||
"PO-Revision-Date: 2010-03-20 03:11+0100\n"
|
||||
"POT-Creation-Date: 2010-03-29 00:49+0200\n"
|
||||
"PO-Revision-Date: 2010-03-29 00:49+0200\n"
|
||||
"Last-Translator: Petr Kovar <pknbe@volny.cz>\n"
|
||||
"Language-Team: Czech <gnome-cs-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -26,27 +26,27 @@ msgid "Window management and application launching"
|
||||
msgstr "Správa oken a spouštění aplikací"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
#: ../js/ui/appDisplay.js:312 ../js/ui/dash.js:855
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLIKACE"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:344
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PŘEDVOLBY"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:756
|
||||
msgid "New Window"
|
||||
msgstr "Nové okno"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:760
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Odstranit z oblíbených"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:761
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Přidat mezi oblíbené"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1113
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Oblíbené přidáte přetažením sem"
|
||||
|
||||
@ -64,23 +64,23 @@ msgstr "%s byl odstraněn z oblíbených."
|
||||
msgid "Find"
|
||||
msgstr "Najít"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:510
|
||||
msgid "Searching..."
|
||||
msgstr "Hledá se..."
|
||||
|
||||
#: ../js/ui/dash.js:521
|
||||
#: ../js/ui/dash.js:524
|
||||
msgid "No matching results."
|
||||
msgstr "Neodpovídá ani jeden z výsledků."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||
#: ../js/ui/dash.js:874 ../js/ui/placeDisplay.js:582
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "MÍSTA A ZAŘÍZENÍ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:881 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "NEDÁVNÉ POLOŽKY"
|
||||
|
||||
@ -134,16 +134,16 @@ msgstr "%A, %R"
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A, %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Nelze odpojit \"%s\""
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Opakovat"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Připojit se k..."
|
||||
|
||||
@ -151,7 +151,7 @@ msgstr "Připojit se k..."
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Zadejte prosím příkaz:"
|
||||
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#: ../js/ui/runDialog.js:376
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Vykonání \"%s\" selhalo:"
|
||||
@ -209,6 +209,16 @@ msgstr "Aplikace"
|
||||
msgid "Recent Documents"
|
||||
msgstr "Nedávné dokumenty"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "Spouštění %s dokončeno"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "Připraveno \"%s\""
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Před méně než minutou"
|
||||
|
208
po/de.po
208
po/de.po
@ -2,20 +2,22 @@
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# workspace - Arbeitsfläche
|
||||
#
|
||||
# Hendrik Brandt <heb@gnome-de.org>, 2009.
|
||||
# Hendrik Richter <hendrikr@gnome.org>, 2009.
|
||||
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009.
|
||||
# Mario Blättermann <mariobl@gnome.org>, 2009, 2010.
|
||||
# Christian Kirbach <Christian.Kirbach@googlemail.com>, 2009, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-03-20 22:48+0000\n"
|
||||
"PO-Revision-Date: 2010-03-21 16:27+0100\n"
|
||||
"POT-Creation-Date: 2010-05-17 18:24+0000\n"
|
||||
"PO-Revision-Date: 2010-05-18 22:06+0100\n"
|
||||
"Last-Translator: Mario Blättermann <mariobl@gnome.org>\n"
|
||||
"Language-Team: German <gnome-de@gnome.org>\n"
|
||||
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@ -31,28 +33,66 @@ msgstr "GNOME-Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Fenster verwalten und Anwendungen starten"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "Uhr"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "Die Uhr im Panel anpassen"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
#| msgid "<b>Clock Format</b>"
|
||||
msgid "Clock Format"
|
||||
msgstr "Uhr-Format"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
msgid "Clock Preferences"
|
||||
msgstr "Uhr-Einstellungen"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
#| msgid "<b>Panel Display</b>"
|
||||
msgid "Panel Display"
|
||||
msgstr "Panel-Anzeige"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "_Sekunden anzeigen"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "_Datum anzeigen"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "_12-Stunden-Format"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "_24-Stunden-Format"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ANWENDUNGEN"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "EINSTELLUNGEN"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "Neues Fenster"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Aus Favoriten entfernen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Zu Favoriten hinzufügen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Hier ablegen, um zu Favoriten hinzuzufügen"
|
||||
|
||||
@ -66,153 +106,170 @@ msgstr "%s wurde zu Ihren Favoriten hinzugefügt"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s wurde aus Ihren Favoriten entfernt"
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Suchen"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Suche läuft …"
|
||||
|
||||
#: ../js/ui/dash.js:521
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Keine passenden Ergebnisse."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ORTE UND GERÄTE"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
#: ../js/ui/lookingGlass.js:466
|
||||
msgid "No extensions installed"
|
||||
msgstr "Keine Erweiterungen installiert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
#: ../js/ui/lookingGlass.js:503
|
||||
msgid "Enabled"
|
||||
msgstr "Aktiviert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
#: ../js/ui/lookingGlass.js:505
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
#: ../js/ui/lookingGlass.js:507
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
#: ../js/ui/lookingGlass.js:509
|
||||
msgid "Out of date"
|
||||
msgstr "Veraltet"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
#: ../js/ui/lookingGlass.js:534
|
||||
msgid "View Source"
|
||||
msgstr "Quelle zeigen"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
#: ../js/ui/lookingGlass.js:540
|
||||
msgid "Web Page"
|
||||
msgstr "Webseite"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "Rückgängig"
|
||||
|
||||
#: ../js/ui/panel.js:535
|
||||
msgid "Quit"
|
||||
msgstr "Beenden"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:385
|
||||
#: ../js/ui/panel.js:740
|
||||
msgid "Activities"
|
||||
msgstr "Aktivitäten"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:955
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a, %e. %b, %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:956
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a, %e. %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:960
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:961
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:968
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a, %e. %b, %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:969
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a, %e. %b, %H:%M"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:973
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:974
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "»%s« konnte nicht ausgehängt werden"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Erneut versuchen"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Verbinden mit …"
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Bitte geben Sie einen Befehl ein:"
|
||||
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Ausführung von »%s« ist gescheitert:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "Verfügbar"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "Beschäftigt"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "Unsichtbar"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "Benutzerinformationen …"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Seitenleiste"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systemeinstellungen …"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bildschirm sperren"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "Benutzer wechseln"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "Abmelden …"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "Ausschalten …"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Anwendungen"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Zuletzt geöffnete Dokumente"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
@ -223,32 +280,43 @@ msgstr "Start von %s ist abgeschlossen"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "»%s« ist bereit"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"Es kann keine weitere Arbeitsfläche hinzugefügt werden, weil das Maximum an "
|
||||
"Arbeitsflächen erreicht worden ist."
|
||||
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Die erste Arbeitsfläche kann nicht entfernt werden."
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Vor weniger als einer Minute"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Vor %d Minute"
|
||||
msgstr[1] "Vor %d Minuten"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Vor %d Stunde"
|
||||
msgstr[1] "Vor %d Stunden"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Vor %d Tag"
|
||||
msgstr[1] "Vor %d Tagen"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -279,6 +347,18 @@ msgstr "Suchen"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Seitenleiste"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "Anwendungen"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "Zuletzt geöffnete Dokumente"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Häufig"
|
||||
|
||||
|
312
po/el.po
312
po/el.po
@ -7,10 +7,10 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell.po.master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-10-04 08:03+0000\n"
|
||||
"PO-Revision-Date: 2009-10-04 10:25+0200\n"
|
||||
"Last-Translator: Jennie Petoumenou <epetoumenou@gmail.com>\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-28 10:46+0300\n"
|
||||
"PO-Revision-Date: 2010-03-28 10:53+0200\n"
|
||||
"Last-Translator: Kostas Papadimas <pkst@gnome.org>\n"
|
||||
"Language-Team: Greek <<team AT BLOCKSPAM gnome DOT gr>>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -26,151 +26,244 @@ msgstr "Κέλυφος GNOME"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Διαχείριση παραθύρων και εκκίνηση εφαρμογών"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Δραστηριότητες"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:461
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "Εύρεση..."
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "Περισσότερα"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(εμφάνιση όλων)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
||||
#: ../js/ui/appDisplay.js:312
|
||||
#: ../js/ui/dash.js:855
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ΕΦΑΡΜΟΓΕΣ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:344
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ΠΡΟΤΙΜΗΣΕΙΣ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:756
|
||||
msgid "New Window"
|
||||
msgstr "Νέο παράθυρο"
|
||||
|
||||
#: ../js/ui/appDisplay.js:760
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Αφαίρεση από τα αγαπημένα"
|
||||
|
||||
#: ../js/ui/appDisplay.js:761
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Προσθήκη στα αγαπημένα"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1113
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Σύρετε εδώ για να προσθέσετε αγαπημένα"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s προστέθηκε στα αγαπημένα σας"
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s αφαιρέθηκε από τα αγαπημένα σας"
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
msgid "Find"
|
||||
msgstr "Εύρεση"
|
||||
|
||||
#: ../js/ui/dash.js:510
|
||||
msgid "Searching..."
|
||||
msgstr "Αναζήτηση..."
|
||||
|
||||
#: ../js/ui/dash.js:524
|
||||
msgid "No matching results."
|
||||
msgstr "Δεν βρέθηκαν ταιριάσματα."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "ΤΟΠΟΘΕΣΙΕΣ"
|
||||
#: ../js/ui/dash.js:874
|
||||
#: ../js/ui/placeDisplay.js:582
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ΤΟΠΟΘΕΣΙΕΣ $ ΣΥΣΚΕΥΕΣ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ΠΡΟΣΦΑΤΑ ΕΓΓΡΑΦΑ"
|
||||
#: ../js/ui/dash.js:881
|
||||
#: ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ΠΡΟΣΦΑΤΑ ΑΝΤΙΚΕΙΜΕΝΑ"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ΑΠΟΤΕΛΕΣΜΑΤΑ ΑΝΑΖΗΤΗΣΗΣ"
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Δεν υπάρχουν εγκατεστημένες επεκτάσεις"
|
||||
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ΠΡΟΤΙΜΗΣΕΙΣ"
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Σφάλμα"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Προβολή πηγής"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Ιστοσελίδα"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Αναίρεση"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:385
|
||||
msgid "Activities"
|
||||
msgstr "Δραστηριότητες"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Αποτυχία αποπροσάρτησης '%s'"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Προσπάθεια ξανά"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Σύνδεση σε..."
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Παρακαλώ εισάγετε μία εντολή:"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
#: ../js/ui/runDialog.js:376
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Η εκτέλεση του '%s' απέτυχε:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Διαθέσιμος"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Απασχολημένος"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Αόρατος"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Πληροφορίες λογαριασμού..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Πλευρική στήλη"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Προστιμήσεις συστήματος..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Κλείδωμα οθόνης"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Αλλαγή χρήστη"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Αποσύνδεση..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Τερματισμός..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Εφαρμογές"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Πρόσφατα έγγραφα"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s ολοκλήρωσε την εκκίνηση "
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Λιγότερο από ένα λεπτό πριν"
|
||||
|
||||
#: ../src/shell-global.c:815
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d λεπτό πριν"
|
||||
msgstr[1] "%d λεπτά πριν"
|
||||
|
||||
#: ../src/shell-global.c:818
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ώρα πριν"
|
||||
msgstr[1] "%d ώρες πριν"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ημέρα πριν"
|
||||
msgstr[1] "%d ημέρες πριν"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d εβδομάδα πριν"
|
||||
msgstr[1] "%d εβδομάδες πριν"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Άγνωστο"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Αδύνατο το κλείδωμα της οθόνης: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Δεν είναι δυνατή η προσωρινή ρύθμιση της προστασίας οθόνης σε κενή οθόνη: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Αδύνατη η αποσύνδεση: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Πληροφορίες λογαριασμού..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Πλευρική στήλη"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Προστιμήσεις συστήματος..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Κλείδωμα οθόνης"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Αλλαγή χρήστη"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Αποσύνδεση..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Τερματισμός..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Προσωπικός φάκελος"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Σύστημα αρχείων"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Αναζήτηση"
|
||||
|
||||
@ -179,8 +272,27 @@ msgstr "Αναζήτηση"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Περισσότερα"
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(εμφάνιση όλων)"
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "ΤΟΠΟΘΕΣΙΕΣ"
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "ΑΠΟΤΕΛΕΣΜΑΤΑ ΑΝΑΖΗΤΗΣΗΣ"
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Άγνωστο"
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Αδύνατο το κλείδωμα της οθόνης: %s"
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Δεν είναι δυνατή η προσωρινή ρύθμιση της προστασίας οθόνης σε κενή οθόνη: "
|
||||
#~ "%s"
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Αδύνατη η αποσύνδεση: %s"
|
||||
|
||||
|
202
po/es.po
202
po/es.po
@ -2,13 +2,14 @@
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Jorge González <jorgegonz@svn.gnome.org>, 2009, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-03-20 22:48+0000\n"
|
||||
"PO-Revision-Date: 2010-03-21 16:48+0100\n"
|
||||
"POT-Creation-Date: 2010-05-19 16:31+0000\n"
|
||||
"PO-Revision-Date: 2010-05-25 18:28+0200\n"
|
||||
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
|
||||
"Language-Team: Español <gnome-es-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,28 +25,66 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestión de ventanas e inicio de aplicaciones"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "Reloj"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "Personalizar el reloj del panel"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
#| msgid "<b>Clock Format</b>"
|
||||
msgid "Clock Format"
|
||||
msgstr "Formato del reloj"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
msgid "Clock Preferences"
|
||||
msgstr "Preferencias del reloj"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
#| msgid "<b>Panel Display</b>"
|
||||
msgid "Panel Display"
|
||||
msgstr "Panel de visualización"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "Mostrar los segu_ndos"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "Mostrar la _fecha"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "Formato _12 horas"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "Formato _24 horas"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONES"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "Ventana nueva"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Quitar de los favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Añadir a los favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arrastrar aquí para añadir a los favoritos"
|
||||
|
||||
@ -59,153 +98,166 @@ msgstr "Se ha añadido %s a sus favoritos."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Se ha quitado %s de sus favoritos."
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Buscar"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Buscando…"
|
||||
|
||||
#: ../js/ui/dash.js:521
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "No se encontró ningún resultado coincidente."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "LUGARES Y DISPOSITIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ELEMENTOS RECIENTES"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
#: ../js/ui/lookingGlass.js:466
|
||||
msgid "No extensions installed"
|
||||
msgstr "No hay extensiones instaladas"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
#: ../js/ui/lookingGlass.js:503
|
||||
msgid "Enabled"
|
||||
msgstr "Activado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
#: ../js/ui/lookingGlass.js:505
|
||||
msgid "Disabled"
|
||||
msgstr "Desactivado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
#: ../js/ui/lookingGlass.js:507
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
#: ../js/ui/lookingGlass.js:509
|
||||
msgid "Out of date"
|
||||
msgstr "Caducado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
#: ../js/ui/lookingGlass.js:534
|
||||
msgid "View Source"
|
||||
msgstr "Ver fuente"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
#: ../js/ui/lookingGlass.js:540
|
||||
msgid "Web Page"
|
||||
msgstr "Página web"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "Deshacer"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:385
|
||||
#: ../js/ui/panel.js:774
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:989
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %e de %b, %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:990
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e de %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:994
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:995
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1002
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e de %b, %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1003
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e de %b, %H:%M"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1007
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1008
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Falló al desmontar «%s»"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Reintentar"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar a…"
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduzca un comando:"
|
||||
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Falló la ejecución de «%s»:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "Ocupado"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "Invisible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "Información de la cuenta…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencias del sistema…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear la pantalla"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "Salir…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar…"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicaciones"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos recientes"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
@ -216,32 +268,43 @@ msgstr "%s finalizó su lanzamiento"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "«%s» está preparado"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"No se puede añadir un área de trabajo nueva porque se ha llegado al límite "
|
||||
"de áreas de trabajo."
|
||||
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "No se puede quitar el primer área de trabajo."
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hace menos de un minuto"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Hace %d minuto"
|
||||
msgstr[1] "Hace %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Hace %d hora"
|
||||
msgstr[1] "Hace %d horas"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Hace %d día"
|
||||
msgstr[1] "Hace %d días"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -272,6 +335,21 @@ msgstr "Buscar"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Quit"
|
||||
#~ msgstr "Salir"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra lateral"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "Aplicaciones"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "Documentos recientes"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "LUGARES"
|
||||
|
||||
|
203
po/fr.po
203
po/fr.po
@ -11,7 +11,7 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master fr\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-03-08 23:07+0000\n"
|
||||
"POT-Creation-Date: 2010-05-15 22:41+0000\n"
|
||||
"PO-Revision-Date: 2010-03-09 22:55+0100\n"
|
||||
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
|
||||
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
||||
@ -28,28 +28,64 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gestion des fenêtres et lancement des applications"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "Horloge"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "Personnaliser l'horloge du tableau de bord"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
msgid "Clock Format"
|
||||
msgstr "Format de l'horloge"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
msgid "Panel Display"
|
||||
msgstr "Affichage dans le tableau de bord"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
msgid "Clock Preferences"
|
||||
msgstr "Préférences de l'horloge"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "Afficher les _secondes"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "Afficher la _date"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "Format _12 heures"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "Format _24 heures"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:886
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APPLICATIONS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PRÉFÉRENCES"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "Nouvelle fenêtre"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Enlever des favoris"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Ajouter aux favoris"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Glisser ici pour ajouter aux favoris"
|
||||
|
||||
@ -63,170 +99,217 @@ msgstr "%s a été ajouté à vos favoris."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s a été supprimé de vos favoris."
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find..."
|
||||
msgstr "Rechercher..."
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Rechercher"
|
||||
|
||||
#: ../js/ui/dash.js:511
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Recherche en cours..."
|
||||
|
||||
#: ../js/ui/dash.js:525
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Aucun résultat correspondant."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:905 ../js/ui/placeDisplay.js:529
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "RACCOURCIS et PÉRIPHÉRIQUES"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:912 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ÉLÉMENTS RÉCENTS"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
#: ../js/ui/lookingGlass.js:354
|
||||
msgid "No extensions installed"
|
||||
msgstr "Aucune extension installée"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
#: ../js/ui/lookingGlass.js:391
|
||||
msgid "Enabled"
|
||||
msgstr "Activé"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
msgid "Disabled"
|
||||
msgstr "Désactivé"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
msgid "Out of date"
|
||||
msgstr "Périmé"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
#: ../js/ui/lookingGlass.js:422
|
||||
msgid "View Source"
|
||||
msgstr "Afficher la source"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
#: ../js/ui/lookingGlass.js:428
|
||||
msgid "Web Page"
|
||||
msgstr "Page Web"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: ../js/ui/panel.js:535
|
||||
msgid "Quit"
|
||||
msgstr "Quitter"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:399
|
||||
#: ../js/ui/panel.js:740
|
||||
msgid "Activities"
|
||||
msgstr "Activités"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:630
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:955
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %e %b, %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:956
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:960
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:961
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:633
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:968
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e %b, %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/panel.js:969
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e %b, %l:%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:973
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:974
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Impossible de monter « %s »"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Réessayer"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Connexion à..."
|
||||
|
||||
#: ../js/ui/runDialog.js:221
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Veuillez saisir une commande :"
|
||||
|
||||
#: ../js/ui/runDialog.js:344
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Exécution de « %s » impossible :"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "Disponible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "Occupé"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "Invisible"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "Informations personnelles..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Barre latérale"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "Préférences du système..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "Verrouiller l'écran"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "Changer d'utilisateur"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "Fermer la session..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "Éteindre..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "Lancement de %s terminé"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Applications"
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "« %s » est prêt"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documents récents"
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"Impossible d'ajouter un espace de travail car le nombre maximum d'espaces de "
|
||||
"travail est atteint."
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Impossible de supprimer le premier espace de travail."
|
||||
|
||||
#: ../src/shell-global.c:979
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Il y a moins d'une minute"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#: ../src/shell-global.c:983
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Il y a %d minute"
|
||||
msgstr[1] "Il y a %d minutes"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../src/shell-global.c:988
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Il y a %d heure"
|
||||
msgstr[1] "Il y a %d heures"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#: ../src/shell-global.c:993
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Il y a %d jour"
|
||||
msgstr[1] "Il y a %d jours"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#: ../src/shell-global.c:998
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
223
po/gl.po
223
po/gl.po
@ -1,17 +1,17 @@
|
||||
# Galician translation for gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Fran Diéguez <fran.dieguez@mabishu.com>, 2009.
|
||||
# Anton Meixome <certima@certima.net>, 2009.
|
||||
# Antón Méixome <meixome@certima.net>, 2009.
|
||||
# Fran Diéguez <frandieguez@ubuntu.com>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-28 17:07+0100\n"
|
||||
"PO-Revision-Date: 2009-12-28 08:11+0100\n"
|
||||
"Last-Translator: Antón Méixome <meixome@certima.net>\n"
|
||||
"Language-Team: Galician Proxecto Trasno <proxecto@trasno.net>\n"
|
||||
"POT-Creation-Date: 2010-04-09 19:17+0200\n"
|
||||
"PO-Revision-Date: 2010-04-09 19:40+0200\n"
|
||||
"Last-Translator: Fran Diéguez <frandieguez@ubuntu.com>\n"
|
||||
"Language-Team: Galician <gnome@g11n.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
@ -25,116 +25,209 @@ msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Xestor de xanelas e lanzamento de aplicativos"
|
||||
msgstr "Xestor de xanelas e inicio de aplicativos"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:858
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERENCIAS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:707 ../js/ui/appIcon.js:425
|
||||
#: ../js/ui/appDisplay.js:723
|
||||
msgid "New Window"
|
||||
msgstr "Xanela nova"
|
||||
|
||||
#: ../js/ui/appDisplay.js:711 ../js/ui/appIcon.js:429
|
||||
#: ../js/ui/appDisplay.js:727
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Eliminar de Favoritos"
|
||||
msgstr "Eliminar dos favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:712 ../js/ui/appIcon.js:430
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Engadir a Favoritos"
|
||||
msgstr "Engadir aos favoritos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1064
|
||||
#: ../js/ui/appDisplay.js:1055
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arrastra aquí para engadir favoritos"
|
||||
msgstr "Arrastre aquí para engadir aos favoritos"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Buscar..."
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s foi engadido aos seus favoritos."
|
||||
|
||||
#: ../js/ui/dash.js:437
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s foi eliminado dos seus favoritos."
|
||||
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Buscar"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Buscando..."
|
||||
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Non hai resultados que coincidan."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:878 ../js/ui/placeDisplay.js:519
|
||||
msgid "PLACES"
|
||||
msgstr "LUGARES"
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "LUGARES e DISPOSITIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:885
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ELEMENTOS RECENTES"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:362
|
||||
msgid "No extensions installed"
|
||||
msgstr "Non hai ningunha extensión instalada"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Enabled"
|
||||
msgstr "Activado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:401
|
||||
msgid "Disabled"
|
||||
msgstr "Desactivado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:403
|
||||
msgid "Error"
|
||||
msgstr "Erro"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:405
|
||||
msgid "Out of date"
|
||||
msgstr "Desactualizado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "View Source"
|
||||
msgstr "Ver fonte"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:436
|
||||
msgid "Web Page"
|
||||
msgstr "Páxina web"
|
||||
|
||||
#: ../js/ui/overview.js:181
|
||||
msgid "Undo"
|
||||
msgstr "Desfacer"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:227
|
||||
#: ../js/ui/panel.js:374
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:440
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:594
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:597
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Produciuse un fallo ao montar '%s'"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Reintentar"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar con..."
|
||||
|
||||
#: ../js/ui/runDialog.js:235
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Insira unha orde:"
|
||||
|
||||
#: ../js/ui/runDialog.js:351
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Fallou a execución de %s"
|
||||
msgstr "Produciuse un fallo na execución de %s"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Available"
|
||||
msgstr "Dispoñíbel"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicativos"
|
||||
#: ../js/ui/statusMenu.js:110
|
||||
msgid "Busy"
|
||||
msgstr "Ocupado"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos recentes"
|
||||
#: ../js/ui/statusMenu.js:115
|
||||
msgid "Invisible"
|
||||
msgstr "Invisíbel"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
#: ../js/ui/statusMenu.js:124
|
||||
msgid "Account Information..."
|
||||
msgstr "Información da conta..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencias do sistema..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:138
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear pantalla"
|
||||
|
||||
#: ../js/ui/statusMenu.js:143
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#: ../js/ui/statusMenu.js:149
|
||||
msgid "Log Out..."
|
||||
msgstr "Saír da sesión..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:154
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar..."
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s rematou de iniarse"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' está preparado"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hai menos dun minuto"
|
||||
|
||||
#: ../src/shell-global.c:893
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "hai %d minuto"
|
||||
msgstr[1] "hai %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:896
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "hai %d hora"
|
||||
msgstr[1] "hai %d horas"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "hai %d día"
|
||||
msgstr[1] "hai %d días"
|
||||
|
||||
#: ../src/shell-global.c:902
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -165,6 +258,21 @@ msgstr "Buscar"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra lateral"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%M:%H"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "Aplicativos"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "Documentos recentes"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "LUGARES"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "RESULTADOS DA BUSCA"
|
||||
|
||||
@ -182,27 +290,6 @@ msgstr "%1$s: %2$s"
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Non foi posíbel pechar a sesión: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Información da conta..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra lateral"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Preferencias do sistema..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Bloquear pantalla"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Cambiar de usuario"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Saír da sesión..."
|
||||
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Apagar..."
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Explorar"
|
||||
|
||||
|
87
po/hu.po
87
po/hu.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-02-16 10:04+0100\n"
|
||||
"PO-Revision-Date: 2010-02-16 10:10+0100\n"
|
||||
"POT-Creation-Date: 2010-03-24 14:25+0100\n"
|
||||
"PO-Revision-Date: 2010-03-24 14:26+0100\n"
|
||||
"Last-Translator: Gabor Kelemen <kelemeng at gnome dot hu>\n"
|
||||
"Language-Team: Hungarian <gnome at fsf dot hu>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -26,27 +26,27 @@ msgid "Window management and application launching"
|
||||
msgstr "Ablakkezelés és alkalmazásindítás"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ALKALMAZÁSOK"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
msgid "PREFERENCES"
|
||||
msgstr "BEÁLLÍTÁSOK"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
#: ../js/ui/appDisplay.js:729
|
||||
msgid "New Window"
|
||||
msgstr "Új ablak"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Eltávolítás a Kedvencek közül"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
#: ../js/ui/appDisplay.js:734
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Hozzáadás a Kedvencekhez"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
#: ../js/ui/appDisplay.js:1086
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Ide húzással kedvenceket vehet fel"
|
||||
|
||||
@ -60,87 +60,96 @@ msgstr "%s felvéve a Kedvencek közé."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s eltávolítva a Kedvencek közül"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Keresés…"
|
||||
#: ../js/ui/dash.js:194
|
||||
msgid "Find"
|
||||
msgstr "Keresés"
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "Searching..."
|
||||
msgstr "Keresés…"
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
#: ../js/ui/dash.js:521
|
||||
msgid "No matching results."
|
||||
msgstr "Nincs találat."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:580
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "HELYEK ÉS ESZKÖZÖK"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "LEGUTÓBBI ELEMEK"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:356
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Nincsenek kiterjesztések telepítve"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:393
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr "Engedélyezve"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:395
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr "Tiltva"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:397
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Hiba"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr "Elavult"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:424
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Forrás megtekintése"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Weblap"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Visszavonás"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
#: ../js/ui/panel.js:385
|
||||
msgid "Activities"
|
||||
msgstr "Tevékenységek"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:560
|
||||
#: ../js/ui/panel.js:616
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:563
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %p %l.%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "„%s” leválasztása meghiúsult"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
msgid "Retry"
|
||||
msgstr "Újra"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
msgid "Connect to..."
|
||||
msgstr "Kapcsolódás…"
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Adjon meg egy parancsot:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#: ../js/ui/runDialog.js:376
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "„%s” végrehajtása meghiúsult:"
|
||||
@ -198,32 +207,42 @@ msgstr "Alkalmazások"
|
||||
msgid "Recent Documents"
|
||||
msgstr "Legutóbbi dokumentumok"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s indítása befejeződött"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "„%s” kész"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Kevesebb, mint egy perce"
|
||||
|
||||
#: ../src/shell-global.c:980
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d perce"
|
||||
msgstr[1] "%d perce"
|
||||
|
||||
#: ../src/shell-global.c:985
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d órája"
|
||||
msgstr[1] "%d órája"
|
||||
|
||||
#: ../src/shell-global.c:990
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d napja"
|
||||
msgstr[1] "%d napja"
|
||||
|
||||
#: ../src/shell-global.c:995
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
216
po/it.po
216
po/it.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-02-10 22:30+0100\n"
|
||||
"PO-Revision-Date: 2010-02-10 22:31+0100\n"
|
||||
"POT-Creation-Date: 2010-04-06 21:27+0200\n"
|
||||
"PO-Revision-Date: 2010-04-06 22:51+0200\n"
|
||||
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
|
||||
"Language-Team: Italian <tp@lists.linux.it>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -25,118 +25,211 @@ msgid "Window management and application launching"
|
||||
msgstr "Gestione finestre e avvio applicazioni"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:880
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
msgid "PREFERENCES"
|
||||
msgstr "Preferenze"
|
||||
|
||||
#: ../js/ui/appDisplay.js:649
|
||||
#: ../js/ui/appDisplay.js:723
|
||||
msgid "New Window"
|
||||
msgstr "Nuova finestra"
|
||||
|
||||
#: ../js/ui/appDisplay.js:653
|
||||
#: ../js/ui/appDisplay.js:727
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Rimuovi dai preferiti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:654
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Aggiungi ai preferiti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1006
|
||||
#: ../js/ui/appDisplay.js:1055
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Trascinare qui per aggiungere ai preferiti"
|
||||
|
||||
#: ../js/ui/dash.js:241
|
||||
msgid "Find..."
|
||||
msgstr "Trova..."
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s è stato aggiunto ai preferiti."
|
||||
|
||||
#: ../js/ui/dash.js:508
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s è stato rimosso dai preferiti."
|
||||
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Trova"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Ricerca..."
|
||||
|
||||
#: ../js/ui/dash.js:522
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Nessun risultato."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:900 ../js/ui/placeDisplay.js:529
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "Risorse e dispositivi"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:907
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "Elementi recenti"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:362
|
||||
msgid "No extensions installed"
|
||||
msgstr "Nessuna estensione installata"
|
||||
|
||||
# (ndt) o abilitata?
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Enabled"
|
||||
msgstr "Abilitato"
|
||||
|
||||
# (ndt) o disabilitata?
|
||||
#: ../js/ui/lookingGlass.js:401
|
||||
msgid "Disabled"
|
||||
msgstr "Disabilitato"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:403
|
||||
msgid "Error"
|
||||
msgstr "Errore"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:405
|
||||
msgid "Out of date"
|
||||
msgstr "Non aggiornato"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "View Source"
|
||||
msgstr "Visualizza sorgente"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:436
|
||||
msgid "Web Page"
|
||||
msgstr "Pagina web"
|
||||
|
||||
#: ../js/ui/overview.js:181
|
||||
msgid "Undo"
|
||||
msgstr "Annulla"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
#: ../js/ui/panel.js:374
|
||||
msgid "Activities"
|
||||
msgstr "Attività"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:594
|
||||
msgid "%a %R"
|
||||
msgstr "%a %k.%M"
|
||||
|
||||
# (ndt) proviamo col k, se non funge, sappiamo il perché...
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:557
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:597
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k.%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
# (ndt) libera, ma unmount non si può proprio vedere...
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Impossibile scollegare «%s»"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Riprova"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Connetti a..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Inserire un comando:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Esecuzione di «%s» non riuscita:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%k.%M"
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Available"
|
||||
msgstr "Disponibile"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Applicazioni"
|
||||
#: ../js/ui/statusMenu.js:110
|
||||
msgid "Busy"
|
||||
msgstr "Non disponibile"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documenti recenti"
|
||||
#: ../js/ui/statusMenu.js:115
|
||||
msgid "Invisible"
|
||||
msgstr "Invisibile"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../js/ui/statusMenu.js:124
|
||||
msgid "Account Information..."
|
||||
msgstr "Informazioni account..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferenze di sistema..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:138
|
||||
msgid "Lock Screen"
|
||||
msgstr "Blocca schermo"
|
||||
|
||||
#: ../js/ui/statusMenu.js:143
|
||||
msgid "Switch User"
|
||||
msgstr "Cambia utente"
|
||||
|
||||
#: ../js/ui/statusMenu.js:149
|
||||
msgid "Log Out..."
|
||||
msgstr "Termina sessione..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:154
|
||||
msgid "Shut Down..."
|
||||
msgstr "Arresta..."
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "Avvio di %s completato"
|
||||
|
||||
# (ndt) dovrebbe essere il nome dell'applicazione
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "«%s» è pronto"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Meno di un minuto fa"
|
||||
|
||||
#: ../src/shell-global.c:980
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuto fa"
|
||||
msgstr[1] "%d minuti fa"
|
||||
|
||||
#: ../src/shell-global.c:985
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ora fa"
|
||||
msgstr[1] "%d ore fa"
|
||||
|
||||
#: ../src/shell-global.c:990
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d giorno fa"
|
||||
msgstr[1] "%d giorni fa"
|
||||
|
||||
#: ../src/shell-global.c:995
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -167,54 +260,3 @@ msgstr "Cerca"
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "Risorse"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "Frequente"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "Altro"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(vedi tutto)"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "Risultati ricerca"
|
||||
|
||||
# (ndt) valutare se vada al femminile
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Sconosciuto"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Impossibile bloccare lo schermo: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr ""
|
||||
#~ "Impossibile impostare temporaneamente il salva schermo a schermo nero: %s "
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Impossibile terminare la sessione: %s"
|
||||
|
||||
#~ msgid "Account Information..."
|
||||
#~ msgstr "Informazioni account..."
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra laterale"
|
||||
|
||||
#~ msgid "System Preferences..."
|
||||
#~ msgstr "Preferenze di sistema..."
|
||||
|
||||
#~ msgid "Lock Screen"
|
||||
#~ msgstr "Blocca schermo"
|
||||
|
||||
#~ msgid "Switch User"
|
||||
#~ msgstr "Cambia utente"
|
||||
|
||||
#~ msgid "Log Out..."
|
||||
#~ msgstr "Termina sessione..."
|
||||
|
||||
# (ndt) da valutare... pare che ora anche Windows usi 'Arresta...'...
|
||||
#~ msgid "Shut Down..."
|
||||
#~ msgstr "Spegni..."
|
||||
|
199
po/nb.po
199
po/nb.po
@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 2.28.x\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-03-09 17:45+0100\n"
|
||||
"PO-Revision-Date: 2010-03-09 17:47+0100\n"
|
||||
"POT-Creation-Date: 2010-05-24 16:28+0200\n"
|
||||
"PO-Revision-Date: 2010-05-24 16:29+0200\n"
|
||||
"Last-Translator: Kjartan Maraas <kmaraas@broadpark.no>\n"
|
||||
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -24,28 +24,64 @@ msgstr "GNOME Shell"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Vindushåndtering og oppstart av programmer"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "Klokke"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "Tilpass klokken på panelet"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
msgid "Clock Format"
|
||||
msgstr "Klokkeformat"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
msgid "Clock Preferences"
|
||||
msgstr "Brukervalg for klokke"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
msgid "Panel Display"
|
||||
msgstr "Panelvisning"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "Vis seku_nder"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "Vis _dato"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "_12-timers format"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "_24-timers format"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:886
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMMER"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "BRUKERVALG"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "Nytt vindu"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Fjern fra favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Legg til i favoritter"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Dra hit for å legge til favoritter"
|
||||
|
||||
@ -59,170 +95,211 @@ msgstr "%s ble lagt til i dine favoritter."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s ble fjernet fra dine favoritter."
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find..."
|
||||
msgstr "Finn..."
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Finn"
|
||||
|
||||
#: ../js/ui/dash.js:511
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Søker..."
|
||||
|
||||
#: ../js/ui/dash.js:525
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Ingen treff."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:905 ../js/ui/placeDisplay.js:529
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "STEDER & ENHETER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:912 ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "SISTE OPPFØRINGER"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
#: ../js/ui/lookingGlass.js:466
|
||||
msgid "No extensions installed"
|
||||
msgstr "Ingen utvidelser installert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
#: ../js/ui/lookingGlass.js:503
|
||||
msgid "Enabled"
|
||||
msgstr "Aktivert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
#: ../js/ui/lookingGlass.js:505
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktivert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
#: ../js/ui/lookingGlass.js:507
|
||||
msgid "Error"
|
||||
msgstr "Feil"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
#: ../js/ui/lookingGlass.js:509
|
||||
msgid "Out of date"
|
||||
msgstr "Utdatert"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
#: ../js/ui/lookingGlass.js:534
|
||||
msgid "View Source"
|
||||
msgstr "Vis kildekode"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
#: ../js/ui/lookingGlass.js:540
|
||||
msgid "Web Page"
|
||||
msgstr "Nettside"
|
||||
|
||||
#: ../js/ui/overview.js:92
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "Angre"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:399
|
||||
#: ../js/ui/panel.js:887
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:630
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:1102
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a %e %b, %R.%S"
|
||||
|
||||
#: ../js/ui/panel.js:1103
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:1107
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R.%S"
|
||||
|
||||
#: ../js/ui/panel.js:1108
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:633
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1115
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e %b, %l.%M.%S %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/panel.js:1116
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e %b, %l.%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1120
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l.%M.%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:1121
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l.%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Klarte ikke å avmontere «%s»"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Prøv igjen"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Koble til..."
|
||||
|
||||
#: ../js/ui/runDialog.js:221
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Oppgi en kommando:"
|
||||
|
||||
#: ../js/ui/runDialog.js:344
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Kjøring av «%s» feilet:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "Tilgjengelig"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "Opptatt"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "Usynlig"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "Kontoinformasjon..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Sidelinje"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "Brukervalg for systemet..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lås skjerm"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "Bytt bruker"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "Logg ut..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "Avslutt..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s er ferdig startet"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programmer"
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "«%s» er klar"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Siste dokumenter"
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr "Kan ikke legge til nytt arbeidsområde fordi grensen for maksimalt antall arbeidsområder er nådd."
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Kan ikke fjerne første arbeidsområde"
|
||||
|
||||
#: ../src/shell-global.c:1027
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre enn ett minutt siden"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#: ../src/shell-global.c:1031
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minutt siden"
|
||||
msgstr[1] "%d minutter siden"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../src/shell-global.c:1036
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d time siden"
|
||||
msgstr[1] "%d timer siden"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#: ../src/shell-global.c:1041
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag siden"
|
||||
msgstr[1] "%d dager siden"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#: ../src/shell-global.c:1046
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
292
po/nl.po
292
po/nl.po
@ -2,13 +2,13 @@
|
||||
#
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Sander Dijkhuis <sander.dijkhuis@gmail.com>, 2009.
|
||||
# Sander Dijkhuis <sander.dijkhuis@gmail.com>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-29 14:37+0200\n"
|
||||
"PO-Revision-Date: 2009-08-29 15:10+0200\n"
|
||||
"POT-Creation-Date: 2010-03-31 13:34+0200\n"
|
||||
"PO-Revision-Date: 2010-04-02 22:18+0200\n"
|
||||
"Last-Translator: Sander Dijkhuis <sander.dijkhuis@gmail.com>\n"
|
||||
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -18,153 +18,247 @@ msgstr ""
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
msgstr "Gnome Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Vensterbeheer en toepassingen starten"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:271
|
||||
msgid "Activities"
|
||||
msgstr "Activiteiten"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:451
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k:%M"
|
||||
|
||||
#: ../js/ui/dash.js:256
|
||||
msgid "Find..."
|
||||
msgstr "Zoeken…"
|
||||
|
||||
#: ../js/ui/dash.js:374
|
||||
msgid "Browse"
|
||||
msgstr "Bladeren"
|
||||
|
||||
#: ../js/ui/dash.js:451
|
||||
msgid "(see all)"
|
||||
msgstr "(alles tonen)"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:634 ../js/ui/dash.js:682
|
||||
#: ../js/ui/appDisplay.js:312 ../js/ui/dash.js:855
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "TOEPASSINGEN"
|
||||
|
||||
#: ../js/ui/appDisplay.js:344
|
||||
msgid "PREFERENCES"
|
||||
msgstr "VOORKEUREN"
|
||||
|
||||
#: ../js/ui/appDisplay.js:734
|
||||
msgid "New Window"
|
||||
msgstr "Nieuw venster"
|
||||
|
||||
#: ../js/ui/appDisplay.js:738
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Uit favorieten verwijderen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:739
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Aan favorieten toevoegen"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1091
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Hierheen slepen om favorieten toe te voegen"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s is toegevoegd aan uw favorieten."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s is verwijderd uit uw favorieten."
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
msgid "Find"
|
||||
msgstr "Zoeken"
|
||||
|
||||
#: ../js/ui/dash.js:510
|
||||
msgid "Searching..."
|
||||
msgstr "Zoeken…"
|
||||
|
||||
#: ../js/ui/dash.js:524
|
||||
msgid "No matching results."
|
||||
msgstr "Geen overeenkomende resultaten."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:654
|
||||
msgid "PLACES"
|
||||
msgstr "LOCATIES"
|
||||
#: ../js/ui/dash.js:874 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "LOCATIES & APPARATEN"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:661 ../js/ui/dash.js:694
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "RECENTE DOCUMENTEN"
|
||||
#: ../js/ui/dash.js:881 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "RECENTE ITEMS"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:680
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ZOEKRESULTATEN"
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Geen uitbreidingen geïnstalleerd"
|
||||
|
||||
#: ../js/ui/runDialog.js:82
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr "Ingeschakeld"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr "Uitgeschakeld"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Fout"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr "Gedateerd"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Broncode weergeven"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Webpagina"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Ongedaan maken"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:388
|
||||
msgid "Activities"
|
||||
msgstr "Activiteiten"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:622
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Ontkoppelen van ‘%s’ mislukt"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Opnieuw"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Verbinding maken met…"
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Voer een opdracht in:"
|
||||
|
||||
#: ../src/shell-global.c:840
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Korter dan een minuut geleden"
|
||||
#: ../js/ui/runDialog.js:376
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Uitvoeren van ‘%s’ mislukt:"
|
||||
|
||||
#: ../src/shell-global.c:843
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Beschikbaar"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Bezig"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Onzichtbaar"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Accountinformatie…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Zijbalk"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systeemvoorkeuren…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Scherm vergrendelen"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Gebruiker wisselen"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Afmelden…"
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Afsluiten…"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Toepassingen"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Recente documenten"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s is opgestart"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "‘%s’ is klaar"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Minder dan een minuut geleden"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuut geleden"
|
||||
msgstr[1] "%d minuten geleden"
|
||||
|
||||
#: ../src/shell-global.c:846
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d uur geleden"
|
||||
msgstr[1] "%d uur geleden"
|
||||
|
||||
#: ../src/shell-global.c:849
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag geleden"
|
||||
msgstr[1] "%d dagen geleden"
|
||||
|
||||
#: ../src/shell-global.c:852
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d week geleden"
|
||||
msgstr[1] "%d weken geleden"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Onbekend"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Kan het scherm niet vergrendelen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Kan de schermbeveiliging niet tijdelijk als zwart scherm instellen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Kan niet afmelden: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Account-informatie…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Zijbalk"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systeemvoorkeuren…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Scherm vergrendelen"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Gebruiker wisselen"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Afmelden…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Afsluiten…"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Persoonlijke map"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Bestandssysteem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Zoeken"
|
||||
|
||||
@ -173,7 +267,7 @@ msgstr "Zoeken"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
376
po/pa.po
376
po/pa.po
@ -2,14 +2,14 @@
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# A S Alam <aalam@users.sf.net>, 2009.
|
||||
# A S Alam <aalam@users.sf.net>, 2009, 2010.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug."
|
||||
"cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-10-09 22:10+0000\n"
|
||||
"PO-Revision-Date: 2009-10-15 06:18+0530\n"
|
||||
"POT-Creation-Date: 2010-05-19 16:31+0000\n"
|
||||
"PO-Revision-Date: 2010-05-25 19:31+0530\n"
|
||||
"Last-Translator: A S Alam <aalam@users.sf.net>\n"
|
||||
"Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -26,190 +26,307 @@ msgstr "ਗਨੋਮ ਸ਼ੈਲ"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "ਵਿੰਡੋ ਪਰਬੰਧ ਅਤੇ ਐਪਲੀਕੇਸ਼ਨ ਚਲਾਓ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:335
|
||||
msgid "Frequent"
|
||||
msgstr "ਅਕਸਰ"
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "ਘੜੀ"
|
||||
|
||||
#: ../js/ui/appIcon.js:462
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "ਪੈਨਲ ਘੜੀ ਕਸਟਮਾਈਜ਼ ਕਰੋ"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
msgid "Clock Format"
|
||||
msgstr "ਘੜੀ ਫਾਰਮੈਟ"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
#| msgid "System Preferences..."
|
||||
msgid "Clock Preferences"
|
||||
msgstr "ਘੜੀ ਪਸੰਦ"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
msgid "Panel Display"
|
||||
msgstr "ਪੈਨਲ ਦਿੱਖ"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "ਸਕਿੰਟ ਵੇਖੋ(_n)"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "ਮਿਤੀ ਵੇਖੋ(_d)"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "_੧੨ ਘੰਟੇ ਫਾਰਮੈਟ"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "_੨੪ ਘੰਟੇ ਫਾਰਮੈਟ"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ਪਸੰਦ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "ਨਵੀਂ ਵਿੰਡੋ"
|
||||
|
||||
#: ../js/ui/appIcon.js:475
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "ਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"
|
||||
|
||||
#: ../js/ui/appIcon.js:476
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "ਪਸੰਦ 'ਚ ਸ਼ਾਮਲ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/dash.js:283
|
||||
msgid "Find..."
|
||||
msgstr "ਖੋਜ..."
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "ਪਸੰਦ ਵਿੱਚ ਜੋੜਨ ਲਈ ਇੱਥੇ ਸੁੱਟੋ"
|
||||
|
||||
#: ../js/ui/dash.js:400
|
||||
msgid "More"
|
||||
msgstr "ਹੋਰ"
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s ਨੂੰ ਤੁਹਾਡੀ ਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।"
|
||||
|
||||
#: ../js/ui/dash.js:543
|
||||
msgid "(see all)"
|
||||
msgstr "(ਸਭ ਵੇਖੋ)"
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s ਨੂੰ ਤੁਹਾਡੀ ਪਸੰਦ ਤੋਂ ਹਟਾਇਆ ਜਾ ਚੁੱਕਿਆ ਹੈ।"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:763 ../js/ui/dash.js:825
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "ਖੋਜ"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "ਖੋਜ ਜਾਰੀ ਹੈ..."
|
||||
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "ਕੋਈ ਨਤੀਜਾ ਨਹੀਂ ਲੱਭਿਆ।"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:783
|
||||
msgid "PLACES"
|
||||
msgstr "ਥਾਵਾਂ"
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "ਥਾਵਾਂ ਤੇ ਜੰਤਰ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:790 ../js/ui/dash.js:835
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ"
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ਤਾਜ਼ਾ ਆਈਟਮਾਂ"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:815 ../js/ui/dash.js:955
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ਖੋਜ ਨਤੀਜੇ"
|
||||
#: ../js/ui/lookingGlass.js:466
|
||||
msgid "No extensions installed"
|
||||
msgstr "ਕੋਈ ਇਕਸਟੈਨਸ਼ਨ ਇੰਸਟਾਲ ਨਹੀਂ ਹੈ"
|
||||
|
||||
#: ../js/ui/dash.js:830
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ਪਸੰਦ"
|
||||
#: ../js/ui/lookingGlass.js:503
|
||||
msgid "Enabled"
|
||||
msgstr "ਚਾਲੂ ਹੈ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:505
|
||||
msgid "Disabled"
|
||||
msgstr "ਬੰਦ ਹੈ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:507
|
||||
msgid "Error"
|
||||
msgstr "ਗਲਤੀ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:509
|
||||
msgid "Out of date"
|
||||
msgstr "ਪੁਰਾਣਾ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:534
|
||||
msgid "View Source"
|
||||
msgstr "ਸਰੋਤ ਵੇਖੋ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:540
|
||||
msgid "Web Page"
|
||||
msgstr "ਵੈੱਬ ਪੇਜ਼"
|
||||
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "ਵਾਪਸ"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:272
|
||||
#: ../js/ui/panel.js:774
|
||||
msgid "Activities"
|
||||
msgstr "ਸਰਗਰਮੀਆਂ"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:464
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:989
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a, %e %b %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:990
|
||||
#| msgid "%a %l:%M %p"
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a %e %b, %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:994
|
||||
#| msgid "%a %R"
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:995
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1002
|
||||
#| msgid "%a %l:%M %p"
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a %e %b, %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:1003
|
||||
#| msgid "%a %l:%M %p"
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a %e %b, %l:%M %p"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1007
|
||||
#| msgid "%a %l:%M %p"
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a %l:%M:%S %p"
|
||||
|
||||
#: ../js/ui/panel.js:1008
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/places.js:178
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "'%s' ਅਣ-ਮਾਊਂਟ ਕਰਨ ਲਈ ਫੇਲ੍ਹ"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "ਮੁੜ-ਕੋਸ਼ਿਸ਼"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "...ਨਾਲ ਕੁਨੈਕਟ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "ਕਮਾਂਡ ਦਿਓ ਜੀ:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "'%s' ਚਲਾਉਣ ਲਈ ਫੇਲ੍ਹ:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:162
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "ਉਪਲੱਬਧ"
|
||||
|
||||
#: ../js/ui/widget.js:316
|
||||
msgid "Applications"
|
||||
msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "ਰੁਝਿਆ"
|
||||
|
||||
#: ../js/ui/widget.js:341
|
||||
msgid "Recent Documents"
|
||||
msgstr "ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ"
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "ਅਦਿੱਖ"
|
||||
|
||||
#: ../src/shell-global.c:812
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "ਅਕਾਊਂਟ ਜਾਣਕਾਰੀ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "ਸਿਸਟਮ ਪਸੰਦ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "ਸਕਰੀਨ ਲਾਕ ਕਰੋ"
|
||||
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "ਯੂਜ਼ਰ ਬਦਲੋ"
|
||||
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "ਲਾਗਆਉਟ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "ਬੰਦ ਕਰੋ..."
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s ਸ਼ੁਰੂ ਹੋਣਾ ਖਤਮ ਹੋਇਆ"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' ਤਿਆਰ ਹੈ"
|
||||
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid ""
|
||||
"Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr ""
|
||||
"ਨਵਾਂ ਵਰਕਸਪੇਸ ਜੋੜਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ, ਕਿਉਂਕਿ ਵਰਕਸਪੇਸਾਂ ਦੀ ਵੱਧੋ-ਵੱਧ ਗਿਣਤੀ ਪੂਰੀ ਹੋ "
|
||||
"ਚੁੱਕੀ ਹੈ।"
|
||||
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "ਪਹਿਲਾਂ ਵਰਕਸਪੇਸ ਨਹੀਂ ਹਟਾਇਆ ਜਾ ਸਕਦਾ।"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "ਇੱਕ ਮਿੰਟ ਤੋਂ ਘੱਟ ਚਿਰ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:815
|
||||
#: ../src/shell-global.c:980
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:818
|
||||
#: ../src/shell-global.c:985
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
#: ../src/shell-global.c:990
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#: ../src/shell-global.c:995
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d ਹਫ਼ਤਾ ਪਹਿਲਾਂ"
|
||||
msgstr[1] "%d ਹਫ਼ਤੇ ਪਹਿਲਾਂ"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "ਅਣਜਾਣ"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "ਸਕਰੀਨ ਲਾਕ ਨਹੀਂ ਹੋ ਸਕਦੀ: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "ਸਕਰੀਨ ਬੰਦ ਕਰਨ ਲਈ ਆਰਜ਼ੀ ਰੂਪ ਵਿੱਚ ਸਕਰੀਨ-ਸੇਵਰ ਨਹੀਂ ਸੈੱਟ ਕੀਤਾ ਜਾ ਸਕਦਾ: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "ਲਾਗਆਉਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "ਅਕਾਊਂਟ ਜਾਣਕਾਰੀ..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "ਬਾਹੀ"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "ਸਿਸਟਮ ਪਸੰਦ..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "ਸਕਰੀਨ ਲਾਕ ਕਰੋ"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "ਯੂਜ਼ਰ ਬਦਲੋ"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "ਲਾਗਆਉਟ..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "ਬੰਦ ਕਰੋ..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "ਘਰ ਫੋਲਡਰ"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "ਫਾਇਲ ਸਿਸਟਮ"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "ਖੋਜ"
|
||||
|
||||
@ -218,10 +335,49 @@ msgstr "ਖੋਜ"
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "ਬਾਹੀ"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "ਐਪਲੀਕੇਸ਼ਨ"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "ਤਾਜ਼ਾ ਡੌਕੂਮੈਂਟ"
|
||||
|
||||
#~ msgid "Frequent"
|
||||
#~ msgstr "ਅਕਸਰ"
|
||||
|
||||
#~ msgid "More"
|
||||
#~ msgstr "ਹੋਰ"
|
||||
|
||||
#~ msgid "(see all)"
|
||||
#~ msgstr "(ਸਭ ਵੇਖੋ)"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "ਥਾਵਾਂ"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "ਖੋਜ ਨਤੀਜੇ"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "ਅਣਜਾਣ"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "ਸਕਰੀਨ ਲਾਕ ਨਹੀਂ ਹੋ ਸਕਦੀ: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr "ਸਕਰੀਨ ਬੰਦ ਕਰਨ ਲਈ ਆਰਜ਼ੀ ਰੂਪ ਵਿੱਚ ਸਕਰੀਨ-ਸੇਵਰ ਨਹੀਂ ਸੈੱਟ ਕੀਤਾ ਜਾ ਸਕਦਾ: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "ਲਾਗਆਉਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ: %s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "ਝਲਕ"
|
||||
|
288
po/pt_BR.po
288
po/pt_BR.po
@ -3,15 +3,15 @@
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Og Maciel <ogmaciel@gnome.org>, 2009.
|
||||
# Rodrigo Flores <mail@rodrigoflores.org>, 2009.
|
||||
# Felipe Borges <felipe10borges@gmail.com>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2009-11-12 21:33+0000\n"
|
||||
"PO-Revision-Date: 2009-11-14 11:53-0200\n"
|
||||
"Last-Translator: Amanda Magalhães <amandinhakee@gmail.com>\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2010-04-17 14:02-0300\n"
|
||||
"PO-Revision-Date: 2010-03-02 20:59-0300\n"
|
||||
"Last-Translator: Rodrigo Flores <rlmflores@gnome.org>\n"
|
||||
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -24,197 +24,269 @@ msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Gerenciamento de janelas e lançador de aplicações"
|
||||
msgstr "Gerenciamento de janelas e lançador de aplicativos"
|
||||
|
||||
#: ../js/ui/appDisplay.js:696
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arraste até aqui para adicionar aos favoritos"
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:306 ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#: ../js/ui/appIcon.js:425
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERÊNCIAS"
|
||||
|
||||
#: ../js/ui/appDisplay.js:697
|
||||
msgid "New Window"
|
||||
msgstr "Nova janela"
|
||||
|
||||
#: ../js/ui/appIcon.js:429
|
||||
#: ../js/ui/appDisplay.js:701
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Remover dos Favoritos"
|
||||
|
||||
#: ../js/ui/appIcon.js:430
|
||||
#: ../js/ui/appDisplay.js:702
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Adicionar aos Favoritos"
|
||||
|
||||
#: ../js/ui/dash.js:237
|
||||
msgid "Find..."
|
||||
msgstr "Procurar..."
|
||||
#: ../js/ui/appDisplay.js:1029
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Arraste até aqui para adicionar aos favoritos"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:656 ../js/ui/dash.js:718
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s foi adicionado aos seus favoritos."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s foi removido dos seus favoritos."
|
||||
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Localizar"
|
||||
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Pesquisando..."
|
||||
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Nenhum resultado encontrado."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:676 ../js/ui/dash.js:733
|
||||
msgid "PLACES"
|
||||
msgstr "LOCAIS"
|
||||
#: ../js/ui/dash.js:869 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "LOCAIS & DISPOSITIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:683 ../js/ui/dash.js:728
|
||||
msgid "RECENT DOCUMENTS"
|
||||
#: ../js/ui/dash.js:876 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:708 ../js/ui/dash.js:898
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTADOS DA BUSCA"
|
||||
#: ../js/ui/lookingGlass.js:362
|
||||
msgid "No extensions installed"
|
||||
msgstr "Nenhuma extensão instalada"
|
||||
|
||||
#: ../js/ui/dash.js:723
|
||||
msgid "PREFERENCES"
|
||||
msgstr "PREFERÊNCIAS"
|
||||
#: ../js/ui/lookingGlass.js:399
|
||||
msgid "Enabled"
|
||||
msgstr "Habilitado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:401
|
||||
msgid "Disabled"
|
||||
msgstr "Desabilitado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:403
|
||||
msgid "Error"
|
||||
msgstr "Erro"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:405
|
||||
msgid "Out of date"
|
||||
msgstr "Expirado"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:430
|
||||
msgid "View Source"
|
||||
msgstr "Ver fonte"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:436
|
||||
msgid "Web Page"
|
||||
msgstr "Página Web"
|
||||
|
||||
#: ../js/ui/overview.js:181
|
||||
msgid "Undo"
|
||||
msgstr "Desfazer"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:274
|
||||
#: ../js/ui/panel.js:346
|
||||
msgid "Activities"
|
||||
msgstr "Atividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:491
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:566
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:569
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:84
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Erro ao desmontar \"%s\""
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Tentar novamente"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Conectar ao..."
|
||||
|
||||
#: ../js/ui/runDialog.js:96
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Por favor digite um comando:"
|
||||
|
||||
#: ../js/ui/runDialog.js:173
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "A execução de \"%s\" falhou:"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Available"
|
||||
msgstr "Disponível"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Aplicações"
|
||||
#: ../js/ui/statusMenu.js:110
|
||||
msgid "Busy"
|
||||
msgstr "Ocupado"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Documentos Recentes"
|
||||
#: ../js/ui/statusMenu.js:115
|
||||
msgid "Invisible"
|
||||
msgstr "Invisível"
|
||||
|
||||
#: ../src/shell-global.c:821
|
||||
#: ../js/ui/statusMenu.js:124
|
||||
msgid "Account Information..."
|
||||
msgstr "Informação da conta..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferências do sistema..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:138
|
||||
msgid "Lock Screen"
|
||||
msgstr "Travar a tela"
|
||||
|
||||
#: ../js/ui/statusMenu.js:143
|
||||
msgid "Switch User"
|
||||
msgstr "Alternar usuário"
|
||||
|
||||
#: ../js/ui/statusMenu.js:149
|
||||
msgid "Log Out..."
|
||||
msgstr "Encerrar sessão..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:154
|
||||
msgid "Shut Down..."
|
||||
msgstr "Desligar..."
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s terminou sua inicialização"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "\"%s\" está pronto"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Menos de um minuto atrás"
|
||||
|
||||
#: ../src/shell-global.c:824
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuto atrás"
|
||||
msgstr[1] "%d minutos atrás"
|
||||
|
||||
#: ../src/shell-global.c:827
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d hora atrás"
|
||||
msgstr[1] "%d horas atrás"
|
||||
|
||||
#: ../src/shell-global.c:830
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dia atrás"
|
||||
msgstr[1] "%d dias atrás"
|
||||
|
||||
#: ../src/shell-global.c:833
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d semana atrás"
|
||||
msgstr[1] "%d semanas atrás"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Desconhecido"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Não foi possível travar a tela: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Não foi possível definir a proteção de tela para uma tela vazia: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Não foi possível encerrar a sessão: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informação da conta..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferências do sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Travar a tela"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Alternar usuário"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Encerrar sessão..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Desligar..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Pasta home"
|
||||
msgstr "Pasta pessoal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Sistema de arquivos"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Procurar"
|
||||
msgstr "Pesquisar"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:298
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Barra lateral"
|
||||
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "Aplicativos"
|
||||
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "Documentos recentes"
|
||||
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "LOCAIS"
|
||||
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
#~ msgstr "RESULTADOS DA BUSCA"
|
||||
|
||||
#~ msgid "Unknown"
|
||||
#~ msgstr "Desconhecido"
|
||||
|
||||
#~ msgid "Can't lock screen: %s"
|
||||
#~ msgstr "Não foi possível travar a tela: %s"
|
||||
|
||||
#~ msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
#~ msgstr "Não foi possível definir a proteção de tela para uma tela vazia: %s"
|
||||
|
||||
#~ msgid "Can't logout: %s"
|
||||
#~ msgstr "Não foi possível encerrar a sessão: %s"
|
||||
|
||||
#~ msgid "Browse"
|
||||
#~ msgstr "Navegar"
|
||||
|
||||
|
199
po/sl.po
199
po/sl.po
@ -8,8 +8,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-03-21 15:49+0000\n"
|
||||
"PO-Revision-Date: 2010-03-21 21:59+0100\n"
|
||||
"POT-Creation-Date: 2010-05-21 16:35+0000\n"
|
||||
"PO-Revision-Date: 2010-05-21 20:03+0100\n"
|
||||
"Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n"
|
||||
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -29,29 +29,65 @@ msgstr "Gnome Lupina"
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Upravljanje oken in zaganjanje programov"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
|
||||
msgid "Clock"
|
||||
msgstr "Ura"
|
||||
|
||||
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
|
||||
msgid "Customize the panel clock"
|
||||
msgstr "Prilagodi uro pladnja"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:1
|
||||
msgid "Clock Format"
|
||||
msgstr "Zapis ure"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:2
|
||||
msgid "Clock Preferences"
|
||||
msgstr "Možnosti ure"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:3
|
||||
msgid "Panel Display"
|
||||
msgstr "Prikazovanje pladnja"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:4
|
||||
msgid "Show seco_nds"
|
||||
msgstr "Pokaži _sekunde"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:5
|
||||
msgid "Show the _date"
|
||||
msgstr "Pokaži _datum"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:6
|
||||
msgid "_12 hour format"
|
||||
msgstr "_12-urni zapis časa"
|
||||
|
||||
#: ../data/clock-preferences.ui.h:7
|
||||
msgid "_24 hour format"
|
||||
msgstr "_24-urni zapis časa"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:311
|
||||
#: ../js/ui/dash.js:852
|
||||
#: ../js/ui/appDisplay.js:306
|
||||
#: ../js/ui/dash.js:850
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Programi"
|
||||
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
#: ../js/ui/appDisplay.js:338
|
||||
msgid "PREFERENCES"
|
||||
msgstr "Možnosti"
|
||||
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
#: ../js/ui/appDisplay.js:705
|
||||
msgid "New Window"
|
||||
msgstr "Novo okno"
|
||||
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
#: ../js/ui/appDisplay.js:709
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Odstrani iz priljubljenih"
|
||||
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
#: ../js/ui/appDisplay.js:710
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Dodaj med priljubljene"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
#: ../js/ui/appDisplay.js:1037
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "S potegom na to mesto se izbor doda med priljubljene"
|
||||
|
||||
@ -65,155 +101,168 @@ msgstr "Program \"%s\" je dodan med priljubljeno."
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "Program \"%s\" je odstranjen iz priljubljenih."
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
#: ../js/ui/dash.js:189
|
||||
msgid "Find"
|
||||
msgstr "Najdi"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:505
|
||||
msgid "Searching..."
|
||||
msgstr "Iskanje ..."
|
||||
|
||||
#: ../js/ui/dash.js:521
|
||||
#: ../js/ui/dash.js:519
|
||||
msgid "No matching results."
|
||||
msgstr "Ni zadetkov iskanja"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:871
|
||||
#: ../js/ui/placeDisplay.js:579
|
||||
#: ../js/ui/dash.js:869
|
||||
#: ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "Mesta in naprave"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:878
|
||||
#: ../js/ui/docDisplay.js:488
|
||||
#: ../js/ui/dash.js:876
|
||||
#: ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "Nedavni predmeti"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
#: ../js/ui/lookingGlass.js:466
|
||||
msgid "No extensions installed"
|
||||
msgstr "Ni nameščenih razširitev"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
#: ../js/ui/lookingGlass.js:503
|
||||
msgid "Enabled"
|
||||
msgstr "Omogočeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
#: ../js/ui/lookingGlass.js:505
|
||||
msgid "Disabled"
|
||||
msgstr "Onemogočeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
#: ../js/ui/lookingGlass.js:507
|
||||
msgid "Error"
|
||||
msgstr "Napaka"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
#: ../js/ui/lookingGlass.js:509
|
||||
msgid "Out of date"
|
||||
msgstr "Zastarelo"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
#: ../js/ui/lookingGlass.js:534
|
||||
msgid "View Source"
|
||||
msgstr "Poglej vir"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
#: ../js/ui/lookingGlass.js:540
|
||||
msgid "Web Page"
|
||||
msgstr "Spletna stran"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
#: ../js/ui/overview.js:161
|
||||
msgid "Undo"
|
||||
msgstr "Razveljavi"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:385
|
||||
#: ../js/ui/panel.js:887
|
||||
msgid "Activities"
|
||||
msgstr "Dejavnosti"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
#. Translators: This is the time format with date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:1102
|
||||
msgid "%a %b %e, %R:%S"
|
||||
msgstr "%a. %e. %b., %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1103
|
||||
msgid "%a %b %e, %R"
|
||||
msgstr "%a, %e. %b., %R"
|
||||
|
||||
#. Translators: This is the time format without date used
|
||||
#. in 24-hour mode.
|
||||
#: ../js/ui/panel.js:1107
|
||||
msgid "%a %R:%S"
|
||||
msgstr "%a. %R:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1108
|
||||
msgid "%a %R"
|
||||
msgstr "%a. %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
#. Translators: This is a time format with date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1115
|
||||
msgid "%a %b %e, %l:%M:%S %p"
|
||||
msgstr "%a. %e. %b., %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1116
|
||||
msgid "%a %b %e, %l:%M %p"
|
||||
msgstr "%a. %e. %b., %H:%M"
|
||||
|
||||
#. Translators: This is a time format without date used
|
||||
#. for AM/PM.
|
||||
#: ../js/ui/panel.js:1120
|
||||
msgid "%a %l:%M:%S %p"
|
||||
msgstr "%a, %H:%M:%S"
|
||||
|
||||
#: ../js/ui/panel.js:1121
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Ni mogoče odklopiti '%s'"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Poskusi znova"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "Povezava z ..."
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
#: ../js/ui/runDialog.js:231
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Vnos ukaza:"
|
||||
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#: ../js/ui/runDialog.js:375
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Izvajanje '%s' je spodletelo:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
#: ../js/ui/statusMenu.js:90
|
||||
msgid "Available"
|
||||
msgstr "Razpoložljivo"
|
||||
msgstr "Na voljo"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
#: ../js/ui/statusMenu.js:94
|
||||
msgid "Busy"
|
||||
msgstr "Zasedeno"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
#: ../js/ui/statusMenu.js:98
|
||||
msgid "Invisible"
|
||||
msgstr "Nevidno"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
#: ../js/ui/statusMenu.js:105
|
||||
msgid "Account Information..."
|
||||
msgstr "Podrobnosti računa ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Stranska vrstica"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
#: ../js/ui/statusMenu.js:109
|
||||
msgid "System Preferences..."
|
||||
msgstr "Sistemske možnosti ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
#: ../js/ui/statusMenu.js:116
|
||||
msgid "Lock Screen"
|
||||
msgstr "Zakleni zaslon"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
#: ../js/ui/statusMenu.js:120
|
||||
msgid "Switch User"
|
||||
msgstr "Preklop uporabnika"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
#: ../js/ui/statusMenu.js:125
|
||||
msgid "Log Out..."
|
||||
msgstr "Odjava ..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
#: ../js/ui/statusMenu.js:129
|
||||
msgid "Shut Down..."
|
||||
msgstr "Izklopi ..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Programi"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Nedavni dokumenti"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
@ -224,11 +273,19 @@ msgstr "%s je končal začenjanje"
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' storitev je pripravljena"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
#: ../js/ui/workspacesView.js:239
|
||||
msgid "Can't add a new workspace because maximum workspaces limit has been reached."
|
||||
msgstr "Ni mogoče dodati nove delovne površine, ker je doseženo njihovo največje dovoljeno število."
|
||||
|
||||
#: ../js/ui/workspacesView.js:256
|
||||
msgid "Can't remove the first workspace."
|
||||
msgstr "Ni mogoče odstraniti prve delovne površine."
|
||||
|
||||
#: ../src/shell-global.c:1011
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Pred manj kot eno minuto"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#: ../src/shell-global.c:1015
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -237,7 +294,7 @@ msgstr[1] "Pred %d minuto"
|
||||
msgstr[2] "Pred %d minutama"
|
||||
msgstr[3] "Pred %d minutami"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#: ../src/shell-global.c:1020
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -246,7 +303,7 @@ msgstr[1] "Pred %d uro"
|
||||
msgstr[2] "Pred %d urama"
|
||||
msgstr[3] "Pred %d urami"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#: ../src/shell-global.c:1025
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -255,7 +312,7 @@ msgstr[1] "Pred %d dnevom"
|
||||
msgstr[2] "Pred %d dnevoma"
|
||||
msgstr[3] "Pred %d dnevi"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#: ../src/shell-global.c:1030
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
@ -288,6 +345,16 @@ msgstr "Poišči"
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Quit"
|
||||
#~ msgstr "Končaj"
|
||||
#~ msgid "Sidebar"
|
||||
#~ msgstr "Stranska vrstica"
|
||||
#~ msgid "%H:%M"
|
||||
#~ msgstr "%H:%M"
|
||||
#~ msgid "Applications"
|
||||
#~ msgstr "Programi"
|
||||
#~ msgid "Recent Documents"
|
||||
#~ msgstr "Nedavni dokumenti"
|
||||
#~ msgid "PLACES"
|
||||
#~ msgstr "Mesta"
|
||||
#~ msgid "SEARCH RESULTS"
|
||||
|
161
po/sr.po
161
po/sr.po
@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-01-18 20:13+0000\n"
|
||||
"PO-Revision-Date: 2010-01-19 00:14+0000\n"
|
||||
"POT-Creation-Date: 2010-03-20 22:48+0000\n"
|
||||
"PO-Revision-Date: 2010-03-24 01:45+0100\n"
|
||||
"Last-Translator: Милош Поповић <gpopac@gmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -27,78 +27,177 @@ msgid "Window management and application launching"
|
||||
msgstr "Управник прозорима и покретач програма"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ПРОГРАМИ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ПОСТАВКЕ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:647
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
msgid "New Window"
|
||||
msgstr "Нови прозор"
|
||||
|
||||
#: ../js/ui/appDisplay.js:651
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Уклони из омиљених"
|
||||
|
||||
#: ../js/ui/appDisplay.js:652
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додај у омиљене"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1004
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Превуците овде како би додали у омиљене"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Нађи..."
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s је додат међу омиљене"
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
#| msgid "Remove from Favorites"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s је уклоњен из омиљених"
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
#| msgid "Find..."
|
||||
msgid "Find"
|
||||
msgstr "Нађи"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "Searching..."
|
||||
msgstr "Тражим..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:521
|
||||
msgid "No matching results."
|
||||
msgstr "Ништа није пронађено."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "МЕСТА И УРЕЂАЈИ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "СКОРАШЊЕ СТАВКЕ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Нису инсталирана проширења"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr "Омогућено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr "Онемогућено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Грешка"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr "Истекао је датум"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Погледај извор"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Интернет страница"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Опозови"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
#: ../js/ui/panel.js:385
|
||||
msgid "Activities"
|
||||
msgstr "Активности"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
msgid "%a %R"
|
||||
msgstr "%A, %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Не могу да демонтирам „%s“"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
msgid "Retry"
|
||||
msgstr "Понови"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
msgid "Connect to..."
|
||||
msgstr "Повежи се на..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Унесите наредбу:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Није успело покретање „%s“:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Доступан"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Заузет"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Невидљив"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Подаци о налогу..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
#| msgid "Search"
|
||||
msgid "Sidebar"
|
||||
msgstr "Бочна трака"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Поставке система..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Закључај екран"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Промени корисника"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Одјави ме..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Искључи..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
@ -112,11 +211,21 @@ msgstr "Програми"
|
||||
msgid "Recent Documents"
|
||||
msgstr "Скорашњи документи"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s је покренут"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "„%s“ је спреман"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Пре мање од једног минута"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -125,7 +234,7 @@ msgstr[1] "Пре %d минута"
|
||||
msgstr[2] "Пре %d минута"
|
||||
msgstr[3] "Пре %d минута"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -134,7 +243,7 @@ msgstr[1] "Пре %d сата"
|
||||
msgstr[2] "Пре %d сата"
|
||||
msgstr[3] "Пре %d сата"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -143,7 +252,7 @@ msgstr[1] "Пре %d дана"
|
||||
msgstr[2] "Пре %d дана"
|
||||
msgstr[3] "Пре %d дана"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
161
po/sr@latin.po
161
po/sr@latin.po
@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-01-18 20:13+0000\n"
|
||||
"PO-Revision-Date: 2010-01-19 00:14+0000\n"
|
||||
"POT-Creation-Date: 2010-03-20 22:48+0000\n"
|
||||
"PO-Revision-Date: 2010-03-24 01:45+0100\n"
|
||||
"Last-Translator: Miloš Popović <gpopac@gmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -27,78 +27,177 @@ msgid "Window management and application launching"
|
||||
msgstr "Upravnik prozorima i pokretač programa"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:252 ../js/ui/dash.js:865
|
||||
#: ../js/ui/appDisplay.js:311 ../js/ui/dash.js:852
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMI"
|
||||
|
||||
#: ../js/ui/appDisplay.js:276
|
||||
#: ../js/ui/appDisplay.js:343
|
||||
msgid "PREFERENCES"
|
||||
msgstr "POSTAVKE"
|
||||
|
||||
#: ../js/ui/appDisplay.js:647
|
||||
#: ../js/ui/appDisplay.js:728
|
||||
msgid "New Window"
|
||||
msgstr "Novi prozor"
|
||||
|
||||
#: ../js/ui/appDisplay.js:651
|
||||
#: ../js/ui/appDisplay.js:732
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Ukloni iz omiljenih"
|
||||
|
||||
#: ../js/ui/appDisplay.js:652
|
||||
#: ../js/ui/appDisplay.js:733
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Dodaj u omiljene"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1004
|
||||
#: ../js/ui/appDisplay.js:1085
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Prevucite ovde kako bi dodali u omiljene"
|
||||
|
||||
#: ../js/ui/dash.js:240
|
||||
msgid "Find..."
|
||||
msgstr "Nađi..."
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s je dodat među omiljene"
|
||||
|
||||
#: ../js/ui/dash.js:493
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
#| msgid "Remove from Favorites"
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s je uklonjen iz omiljenih"
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
#| msgid "Find..."
|
||||
msgid "Find"
|
||||
msgstr "Nađi"
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
msgid "Searching..."
|
||||
msgstr "Tražim..."
|
||||
|
||||
#: ../js/ui/dash.js:507
|
||||
#: ../js/ui/dash.js:521
|
||||
msgid "No matching results."
|
||||
msgstr "Ništa nije pronađeno."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:885 ../js/ui/placeDisplay.js:519
|
||||
#: ../js/ui/dash.js:871 ../js/ui/placeDisplay.js:579
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "MESTA I UREĐAJI"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:892
|
||||
#: ../js/ui/dash.js:878 ../js/ui/docDisplay.js:488
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "SKORAŠNJE STAVKE"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Nisu instalirana proširenja"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr "Omogućeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr "Onemogućeno"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Greška"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr "Istekao je datum"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Pogledaj izvor"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Internet stranica"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Opozovi"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:336
|
||||
#: ../js/ui/panel.js:385
|
||||
msgid "Activities"
|
||||
msgstr "Aktivnosti"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:549
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:616
|
||||
msgid "%a %R"
|
||||
msgstr "%A, %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:144
|
||||
#: ../js/ui/placeDisplay.js:103
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Ne mogu da demontiram „%s“"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:106
|
||||
msgid "Retry"
|
||||
msgstr "Ponovi"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:151
|
||||
msgid "Connect to..."
|
||||
msgstr "Poveži se na..."
|
||||
|
||||
#: ../js/ui/runDialog.js:245
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Unesite naredbu:"
|
||||
|
||||
#: ../js/ui/runDialog.js:361
|
||||
#: ../js/ui/runDialog.js:374
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Nije uspelo pokretanje „%s“:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Dostupan"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Zauzet"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Nevidljiv"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Podaci o nalogu..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
#| msgid "Search"
|
||||
msgid "Sidebar"
|
||||
msgstr "Bočna traka"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Postavke sistema..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Zaključaj ekran"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Promeni korisnika"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Odjavi me..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Isključi..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
@ -112,11 +211,21 @@ msgstr "Programi"
|
||||
msgid "Recent Documents"
|
||||
msgstr "Skorašnji dokumenti"
|
||||
|
||||
#: ../src/shell-global.c:890
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s je pokrenut"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "„%s“ je spreman"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Pre manje od jednog minuta"
|
||||
|
||||
#: ../src/shell-global.c:894
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
@ -125,7 +234,7 @@ msgstr[1] "Pre %d minuta"
|
||||
msgstr[2] "Pre %d minuta"
|
||||
msgstr[3] "Pre %d minuta"
|
||||
|
||||
#: ../src/shell-global.c:899
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
@ -134,7 +243,7 @@ msgstr[1] "Pre %d sata"
|
||||
msgstr[2] "Pre %d sata"
|
||||
msgstr[3] "Pre %d sata"
|
||||
|
||||
#: ../src/shell-global.c:904
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
@ -143,7 +252,7 @@ msgstr[1] "Pre %d dana"
|
||||
msgstr[2] "Pre %d dana"
|
||||
msgstr[3] "Pre %d dana"
|
||||
|
||||
#: ../src/shell-global.c:909
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
|
280
po/uk.po
Normal file
280
po/uk.po
Normal file
@ -0,0 +1,280 @@
|
||||
# Ukrainian translation for gnome-shell.
|
||||
# Copyright (C) 2010 Free Software Foundation
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Maxim V. Dziumanenko <dziumanenko@gmail.com>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
|
||||
"shell&component=general\n"
|
||||
"POT-Creation-Date: 2010-03-31 13:32+0000\n"
|
||||
"PO-Revision-Date: 2010-03-31 13:32+0000\n"
|
||||
"Last-Translator: Maxim V. Dziumanenko <dziumanenko@gmail.com>\n"
|
||||
"Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Shell"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Керування вікнами та запуск програм"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/appDisplay.js:312 ../js/ui/dash.js:855
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ПРОГРАМИ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:344
|
||||
msgid "PREFERENCES"
|
||||
msgstr "ПАРАМЕТРИ"
|
||||
|
||||
#: ../js/ui/appDisplay.js:734
|
||||
msgid "New Window"
|
||||
msgstr "Нове вікно"
|
||||
|
||||
#: ../js/ui/appDisplay.js:738
|
||||
msgid "Remove from Favorites"
|
||||
msgstr "Видалити з улюбленого"
|
||||
|
||||
#: ../js/ui/appDisplay.js:739
|
||||
msgid "Add to Favorites"
|
||||
msgstr "Додати до улюбленого"
|
||||
|
||||
#: ../js/ui/appDisplay.js:1091
|
||||
msgid "Drag here to add favorites"
|
||||
msgstr "Перетягніть сюди для додавання до улюбленого"
|
||||
|
||||
#: ../js/ui/appFavorites.js:89
|
||||
#, c-format
|
||||
msgid "%s has been added to your favorites."
|
||||
msgstr "%s додано до улюбленого."
|
||||
|
||||
#: ../js/ui/appFavorites.js:107
|
||||
#, c-format
|
||||
msgid "%s has been removed from your favorites."
|
||||
msgstr "%s видалено з улюбленого."
|
||||
|
||||
#: ../js/ui/dash.js:194
|
||||
msgid "Find"
|
||||
msgstr "Знайти"
|
||||
|
||||
#: ../js/ui/dash.js:510
|
||||
msgid "Searching..."
|
||||
msgstr "Пошук..."
|
||||
|
||||
#: ../js/ui/dash.js:524
|
||||
msgid "No matching results."
|
||||
msgstr "Немає відповідностей."
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:874 ../js/ui/placeDisplay.js:543
|
||||
msgid "PLACES & DEVICES"
|
||||
msgstr "МІСЦЯ ТА ПРИСТРОЇ"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:881 ../js/ui/docDisplay.js:489
|
||||
msgid "RECENT ITEMS"
|
||||
msgstr "ОСТАННІ ДОКУМЕНТИ"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:363
|
||||
msgid "No extensions installed"
|
||||
msgstr "Не встановлено розширення"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:400
|
||||
msgid "Enabled"
|
||||
msgstr "Увімкнено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:402
|
||||
msgid "Disabled"
|
||||
msgstr "Вимкнено"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:404
|
||||
msgid "Error"
|
||||
msgstr "Помилка"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:406
|
||||
msgid "Out of date"
|
||||
msgstr "Застаріло"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:431
|
||||
msgid "View Source"
|
||||
msgstr "Переглянути джерело"
|
||||
|
||||
#: ../js/ui/lookingGlass.js:437
|
||||
msgid "Web Page"
|
||||
msgstr "Веб-сторінка"
|
||||
|
||||
#: ../js/ui/overview.js:182
|
||||
msgid "Undo"
|
||||
msgstr "Вернути"
|
||||
|
||||
#. Button on the left side of the panel.
|
||||
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
|
||||
#: ../js/ui/panel.js:388
|
||||
msgid "Activities"
|
||||
msgstr "Дії"
|
||||
|
||||
#. Translators: This is the time format used in 24-hour mode.
|
||||
#: ../js/ui/panel.js:619
|
||||
msgid "%a %R"
|
||||
msgstr "%a %R"
|
||||
|
||||
#. Translators: This is a time format used for AM/PM.
|
||||
#: ../js/ui/panel.js:622
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:108
|
||||
#, c-format
|
||||
msgid "Failed to unmount '%s'"
|
||||
msgstr "Помилка при відключенні '%s'"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:111
|
||||
msgid "Retry"
|
||||
msgstr "Повторити"
|
||||
|
||||
#: ../js/ui/placeDisplay.js:156
|
||||
msgid "Connect to..."
|
||||
msgstr "З'єднатися з..."
|
||||
|
||||
#: ../js/ui/runDialog.js:232
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Введіть команду:"
|
||||
|
||||
#: ../js/ui/runDialog.js:376
|
||||
#, c-format
|
||||
msgid "Execution of '%s' failed:"
|
||||
msgstr "Не вдається виконати «%s»:"
|
||||
|
||||
#: ../js/ui/statusMenu.js:107
|
||||
msgid "Available"
|
||||
msgstr "Доступний"
|
||||
|
||||
#: ../js/ui/statusMenu.js:112
|
||||
msgid "Busy"
|
||||
msgstr "Зайнятий"
|
||||
|
||||
#: ../js/ui/statusMenu.js:117
|
||||
msgid "Invisible"
|
||||
msgstr "Невидимий"
|
||||
|
||||
#: ../js/ui/statusMenu.js:126
|
||||
msgid "Account Information..."
|
||||
msgstr "Інформація про користувача..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:132
|
||||
msgid "Sidebar"
|
||||
msgstr "Бічна панель"
|
||||
|
||||
#: ../js/ui/statusMenu.js:142
|
||||
msgid "System Preferences..."
|
||||
msgstr "Параметри системи..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:151
|
||||
msgid "Lock Screen"
|
||||
msgstr "Блокувати екран"
|
||||
|
||||
#: ../js/ui/statusMenu.js:156
|
||||
msgid "Switch User"
|
||||
msgstr "Змінити користувача"
|
||||
|
||||
#: ../js/ui/statusMenu.js:162
|
||||
msgid "Log Out..."
|
||||
msgstr "Завершити сеанс..."
|
||||
|
||||
#: ../js/ui/statusMenu.js:167
|
||||
msgid "Shut Down..."
|
||||
msgstr "Вимкнути..."
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/widget.js:163
|
||||
msgid "%H:%M"
|
||||
msgstr "%H:%M"
|
||||
|
||||
#: ../js/ui/widget.js:317
|
||||
msgid "Applications"
|
||||
msgstr "Програми"
|
||||
|
||||
#: ../js/ui/widget.js:339
|
||||
msgid "Recent Documents"
|
||||
msgstr "Недавні документи"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:47
|
||||
#, c-format
|
||||
msgid "%s has finished starting"
|
||||
msgstr "%s завершив запуск"
|
||||
|
||||
#: ../js/ui/windowAttentionHandler.js:49
|
||||
#, c-format
|
||||
msgid "'%s' is ready"
|
||||
msgstr "'%s' готовий"
|
||||
|
||||
#: ../src/shell-global.c:967
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Менше хвилини тому"
|
||||
|
||||
#: ../src/shell-global.c:971
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d хвилина тому"
|
||||
msgstr[1] "%d хвилини тому"
|
||||
msgstr[2] "%d хвилин тому"
|
||||
|
||||
#: ../src/shell-global.c:976
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d година тому"
|
||||
msgstr[1] "%d години тому"
|
||||
msgstr[2] "%d годин тому"
|
||||
|
||||
#: ../src/shell-global.c:981
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d день тому"
|
||||
msgstr[1] "%d дні тому"
|
||||
msgstr[2] "%d днів тому"
|
||||
|
||||
#: ../src/shell-global.c:986
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d тиждень тому"
|
||||
msgstr[1] "%d тижні тому"
|
||||
msgstr[2] "%d тижнів тому"
|
||||
|
||||
#: ../src/shell-uri-util.c:89
|
||||
msgid "Home Folder"
|
||||
msgstr "Домашня тека"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:104
|
||||
msgid "File System"
|
||||
msgstr "Файлова система"
|
||||
|
||||
#: ../src/shell-uri-util.c:250
|
||||
msgid "Search"
|
||||
msgstr "Пошук"
|
||||
|
||||
#. Translators: the first string is the name of a gvfs
|
||||
#. * method, and the second string is a path. For
|
||||
#. * example, "Trash: some-directory". It means that the
|
||||
#. * directory called "some-directory" is in the trash.
|
||||
#.
|
||||
#: ../src/shell-uri-util.c:300
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
big_cflags = \
|
||||
-I$(top_srcdir)/src \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DG_LOG_DOMAIN=\"Big\" \
|
||||
$(BIG_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
big_built_sources = \
|
||||
big-enum-types.h \
|
||||
big-enum-types.c \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES += $(big_built_sources)
|
||||
|
||||
BIG_STAMP_FILES = stamp-big-marshal.h stamp-big-enum-types.h
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
big_source_h = \
|
||||
big/box.h \
|
||||
big/rectangle.h \
|
||||
big/theme-image.h \
|
||||
$(NULL)
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
big_source_c = \
|
||||
big/box.c \
|
||||
big/rectangle.c \
|
||||
big/theme-image.c \
|
||||
$(NULL)
|
||||
|
||||
big-enum-types.h: stamp-big-enum-types.h Makefile
|
||||
@true
|
||||
stamp-big-enum-types.h: $(big_source_h) big/big-enum-types.h.in
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/big/big-enum-types.h.in \
|
||||
$(big_source_h) ) >> xgen-beth && \
|
||||
(cmp -s xgen-beth big-enum-types.h || cp xgen-beth big-enum-types.h) && \
|
||||
rm -f xgen-beth && \
|
||||
echo timestamp > $(@F)
|
||||
|
||||
big-enum-types.c: stamp-big-enum-types.h big/big-enum-types.c.in
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/big/big-enum-types.c.in \
|
||||
$(big_source_h) ) >> xgen-betc && \
|
||||
cp xgen-betc big-enum-types.c && \
|
||||
rm -f xgen-betc
|
||||
|
||||
noinst_LTLIBRARIES += libbig-1.0.la
|
||||
|
||||
libbig_1_0_la_LIBADD = $(BIG_LIBS)
|
||||
libbig_1_0_la_SOURCES = \
|
||||
$(big_source_c) \
|
||||
$(big_source_h) \
|
||||
$(big_built_sources) \
|
||||
$(NULL)
|
||||
libbig_1_0_la_CPPFLAGS = $(big_cflags)
|
||||
libbig_1_0_la_LDFLAGS = $(LDADD)
|
||||
|
||||
CLEANFILES += $(BIG_STAMP_FILES) $(BUILT_SOURCES)
|
||||
|
||||
EXTRA_DIST += \
|
||||
big/README \
|
||||
big/big-enum-types.h.in \
|
||||
big/big-enum-types.c.in
|
@ -74,8 +74,10 @@ st_source_h = \
|
||||
st/st-button.h \
|
||||
st/st-clickable.h \
|
||||
st/st-clipboard.h \
|
||||
st/st-container.h \
|
||||
st/st-drawing-area.h \
|
||||
st/st-entry.h \
|
||||
st/st-group.h \
|
||||
st/st-im-text.h \
|
||||
st/st-label.h \
|
||||
st/st-overflow-box.h \
|
||||
@ -83,13 +85,11 @@ st_source_h = \
|
||||
st/st-scrollable.h \
|
||||
st/st-scroll-bar.h \
|
||||
st/st-scroll-view.h \
|
||||
st/st-shadow-texture.h \
|
||||
st/st-shadow.h \
|
||||
st/st-subtexture.h \
|
||||
st/st-table.h \
|
||||
st/st-table-child.h \
|
||||
st/st-texture-cache.h \
|
||||
st/st-texture-frame.h \
|
||||
st/st-theme.h \
|
||||
st/st-theme-context.h \
|
||||
st/st-theme-node.h \
|
||||
@ -109,7 +109,8 @@ BUILT_SOURCES += st.h
|
||||
st_source_private_h = \
|
||||
st/st-private.h \
|
||||
st/st-table-private.h \
|
||||
st/st-theme-private.h
|
||||
st/st-theme-private.h \
|
||||
st/st-theme-node-private.h
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
st_source_c = \
|
||||
@ -121,8 +122,10 @@ st_source_c = \
|
||||
st/st-button.c \
|
||||
st/st-clickable.c \
|
||||
st/st-clipboard.c \
|
||||
st/st-container.c \
|
||||
st/st-drawing-area.c \
|
||||
st/st-entry.c \
|
||||
st/st-group.c \
|
||||
st/st-im-text.c \
|
||||
st/st-label.c \
|
||||
st/st-overflow-box.c \
|
||||
@ -130,23 +133,22 @@ st_source_c = \
|
||||
st/st-scrollable.c \
|
||||
st/st-scroll-bar.c \
|
||||
st/st-scroll-view.c \
|
||||
st/st-shadow-texture.c \
|
||||
st/st-shadow.c \
|
||||
st/st-subtexture.c \
|
||||
st/st-table.c \
|
||||
st/st-table-child.c \
|
||||
st/st-texture-cache.c \
|
||||
st/st-texture-frame.c \
|
||||
st/st-theme.c \
|
||||
st/st-theme-context.c \
|
||||
st/st-theme-node.c \
|
||||
st/st-theme-node-drawing.c \
|
||||
st/st-tooltip.c \
|
||||
st/st-widget.c \
|
||||
$(NULL)
|
||||
|
||||
noinst_LTLIBRARIES += libst-1.0.la
|
||||
|
||||
libst_1_0_la_LIBADD = $(ST_LIBS)
|
||||
libst_1_0_la_LIBADD = -lm $(ST_LIBS)
|
||||
libst_1_0_la_SOURCES = \
|
||||
$(st_source_c) \
|
||||
$(st_source_private_h) \
|
||||
|
@ -15,6 +15,7 @@ TRAY_STAMP_FILES = stamp-na-marshal.h
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
tray_source = \
|
||||
gtk-compat.h \
|
||||
tray/na-tray-child.c \
|
||||
tray/na-tray-child.h \
|
||||
tray/na-tray-manager.c \
|
||||
|
171
src/Makefile.am
171
src/Makefile.am
@ -8,7 +8,7 @@ noinst_PROGRAMS =
|
||||
|
||||
.AUTOPARALLEL:
|
||||
|
||||
bin_SCRIPTS = gnome-shell
|
||||
bin_SCRIPTS = gnome-shell gnome-shell-clock-preferences
|
||||
|
||||
gnome-shell: gnome-shell.in
|
||||
$(AM_V_GEN) sed -e "s|@MUTTER_BIN_DIR[@]|$(MUTTER_BIN_DIR)|" \
|
||||
@ -24,7 +24,13 @@ gnome-shell: gnome-shell.in
|
||||
CLEANFILES += gnome-shell
|
||||
EXTRA_DIST += gnome-shell.in
|
||||
|
||||
include Makefile-big.am
|
||||
gnome-shell-clock-preferences: gnome-shell-clock-preferences.in
|
||||
$(AM_V_GEN) sed -e "s|@pkgdatadir[@]|$(pkgdatadir)|" \
|
||||
-e "s|@GJS_CONSOLE[@]|$(GJS_CONSOLE)|" \
|
||||
$< > $@ && chmod a+x $@
|
||||
CLEANFILES += gnome-shell-clock-preferences
|
||||
EXTRA_DIST += gnome-shell-clock-preferences.in
|
||||
|
||||
include Makefile-gdmuser.am
|
||||
include Makefile-st.am
|
||||
include Makefile-tray.am
|
||||
@ -43,60 +49,69 @@ plugin_LTLIBRARIES = libgnome-shell.la
|
||||
|
||||
shell_built_sources = \
|
||||
shell-marshal.h \
|
||||
shell-marshal.c
|
||||
shell-marshal.c \
|
||||
shell-enum-types.h \
|
||||
shell-enum-types.c
|
||||
|
||||
BUILT_SOURCES += $(shell_built_sources)
|
||||
EXTRA_DIST += shell-marshal.list
|
||||
|
||||
SHELL_STAMP_FILES = stamp-shell-marshal.h
|
||||
CLEANFILES += $(SHELL_STAMP_FILES)
|
||||
|
||||
libgnome_shell_la_SOURCES = \
|
||||
$(shell_built_sources) \
|
||||
gnome-shell-plugin.c \
|
||||
shell-app.c \
|
||||
shell-app.h \
|
||||
shell-app-private.h \
|
||||
shell-app-system.c \
|
||||
shell-app-system.h \
|
||||
shell-app-usage.c \
|
||||
shell-app-usage.h \
|
||||
shell-arrow.c \
|
||||
shell_public_headers_h = \
|
||||
shell-app.h \
|
||||
shell-app-system.h \
|
||||
shell-app-usage.h \
|
||||
shell-arrow.h \
|
||||
shell-doc-system.c \
|
||||
shell-doc-system.h \
|
||||
shell-drawing.c \
|
||||
shell-drawing.h \
|
||||
shell-embedded-window.c \
|
||||
shell-embedded-window.h \
|
||||
shell-embedded-window-private.h \
|
||||
shell-gconf.c \
|
||||
shell-gconf.h \
|
||||
shell-generic-container.c \
|
||||
shell-generic-container.h \
|
||||
shell-gtk-embed.c \
|
||||
shell-gtk-embed.h \
|
||||
shell-menu.c \
|
||||
shell-menu.h \
|
||||
shell-overflow-list.c \
|
||||
shell-doc-system.h \
|
||||
shell-drawing.h \
|
||||
shell-embedded-window.h \
|
||||
shell-gconf.h \
|
||||
shell-generic-container.h \
|
||||
shell-gtk-embed.h \
|
||||
shell-menu.h \
|
||||
shell-overflow-list.h \
|
||||
shell-process.c \
|
||||
shell-process.h \
|
||||
shell-global.c \
|
||||
shell-global.h \
|
||||
shell-global-private.h \
|
||||
shell-slicer.c \
|
||||
shell-slicer.h \
|
||||
shell-stack.c \
|
||||
shell-stack.h \
|
||||
shell-tray-manager.c \
|
||||
shell-tray-manager.h \
|
||||
shell-uri-util.c \
|
||||
shell-uri-util.h \
|
||||
shell-process.h \
|
||||
shell-global.h \
|
||||
shell-perf-log.h \
|
||||
shell-slicer.h \
|
||||
shell-stack.h \
|
||||
shell-tray-manager.h \
|
||||
shell-uri-util.h \
|
||||
shell-window-tracker.h \
|
||||
shell-wm.h \
|
||||
shell-xfixes-cursor.h
|
||||
|
||||
libgnome_shell_la_SOURCES = \
|
||||
$(shell_built_sources) \
|
||||
$(shell_public_headers_h) \
|
||||
gnome-shell-plugin.c \
|
||||
gtk-compat.h \
|
||||
shell-app.c \
|
||||
shell-app-private.h \
|
||||
shell-app-system.c \
|
||||
shell-app-usage.c \
|
||||
shell-arrow.c \
|
||||
shell-doc-system.c \
|
||||
shell-drawing.c \
|
||||
shell-embedded-window.c \
|
||||
shell-embedded-window-private.h \
|
||||
shell-gconf.c \
|
||||
shell-generic-container.c \
|
||||
shell-gtk-embed.c \
|
||||
shell-menu.c \
|
||||
shell-overflow-list.c \
|
||||
shell-process.c \
|
||||
shell-global.c \
|
||||
shell-global-private.h \
|
||||
shell-perf-log.c \
|
||||
shell-slicer.c \
|
||||
shell-stack.c \
|
||||
shell-tray-manager.c \
|
||||
shell-uri-util.c \
|
||||
shell-window-tracker.c \
|
||||
shell-window-tracker.h \
|
||||
shell-wm.c \
|
||||
shell-wm.h
|
||||
shell-wm.c \
|
||||
shell-xfixes-cursor.c
|
||||
|
||||
|
||||
|
||||
non_gir_sources = \
|
||||
shell-embedded-window-private.h \
|
||||
@ -140,6 +155,7 @@ stamp-shell-marshal.h: Makefile shell-marshal.list
|
||||
(cmp -s xgen-smh shell-marshal.h || cp -f xgen-smh shell-marshal.h) && \
|
||||
rm -f xgen-smh && \
|
||||
echo timestamp > $(@F)
|
||||
CLEANFILES += stamp-shell-marshal.h
|
||||
|
||||
shell-marshal.c: Makefile shell-marshal.list
|
||||
$(AM_V_GEN) (echo "#include \"shell-marshal.h\"" ; \
|
||||
@ -150,29 +166,50 @@ shell-marshal.c: Makefile shell-marshal.list
|
||||
cp -f xgen-smc shell-marshal.c && \
|
||||
rm -f xgen-smc
|
||||
|
||||
|
||||
shell-enum-types.h: stamp-shell-enum-types.h Makefile
|
||||
@true
|
||||
stamp-shell-enum-types.h: $(srcdir)/shell-enum-types.h.in $(shell_public_headers_h)
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $< \
|
||||
$(shell_public_headers_h) ) > $@.tmp && \
|
||||
(cmp -s $@.tmp shell-enum-types.h || mv $@.tmp shell-enum-types.h) && \
|
||||
rm -f $@.tmp && \
|
||||
echo timestamp > $(@F)
|
||||
EXTRA_DIST += shell-enum-types.h.in
|
||||
CLEANFILES += stamp-shell-enum-types.h
|
||||
|
||||
shell-enum-types.c: shell-enum-types.c.in stamp-shell-enum-types.h
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $< \
|
||||
$(shell_public_headers_h) ) > $@.tmp && \
|
||||
mv $@.tmp $@ && \
|
||||
rm -f $@.tmp
|
||||
EXTRA_DIST += shell-enum-types.c.in
|
||||
|
||||
libgnome_shell_la_LDFLAGS = -avoid-version -module
|
||||
libgnome_shell_la_LIBADD = \
|
||||
libgnome_shell_la_LIBADD =-lm \
|
||||
$(MUTTER_PLUGIN_LIBS) \
|
||||
$(LIBGNOMEUI_LIBS) \
|
||||
libbig-1.0.la \
|
||||
libst-1.0.la \
|
||||
libgdmuser-1.0.la \
|
||||
libtray.la
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||
|
||||
typelibdir = $(pkglibdir)
|
||||
typelib_DATA = Shell-0.1.typelib Big-1.0.typelib St-1.0.typelib Gdm-1.0.typelib
|
||||
typelib_DATA = Shell-0.1.typelib St-1.0.typelib Gdm-1.0.typelib
|
||||
|
||||
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) Big-1.0.gir St-1.0.gir libgnome-shell.la Makefile
|
||||
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) St-1.0.gir libgnome-shell.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
--namespace=Shell \
|
||||
--nsversion=0.1 \
|
||||
--add-include-path=$(MUTTER_LIB_DIR)/mutter/ \
|
||||
--include=Clutter-1.0 \
|
||||
--include=Meta-2.29 \
|
||||
--include=Meta-2.31 \
|
||||
--libtool="$(LIBTOOL)" \
|
||||
--add-include-path=$(builddir) \
|
||||
--include=Big-1.0 \
|
||||
--include=St-1.0 \
|
||||
--program=mutter \
|
||||
--program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \
|
||||
@ -184,7 +221,7 @@ CLEANFILES += Shell-0.1.gir
|
||||
|
||||
# The dependency on libgnome-shell.la here is because g-ir-compiler opens it
|
||||
# (not the fake library, since we've already done the rewriting)
|
||||
Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir Big-1.0.gir
|
||||
Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir
|
||||
$(AM_V_GEN) \
|
||||
$(G_IR_COMPILER) \
|
||||
--includedir=. \
|
||||
@ -192,25 +229,6 @@ Shell-0.1.typelib: libgnome-shell.la Shell-0.1.gir Big-1.0.gir
|
||||
Shell-0.1.gir -o $@
|
||||
CLEANFILES += Shell-0.1.typelib
|
||||
|
||||
Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libbig-1.0.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
--namespace=Big \
|
||||
--nsversion=1.0 \
|
||||
--include=Clutter-1.0 \
|
||||
--include=GdkPixbuf-2.0 \
|
||||
--libtool="$(LIBTOOL)" \
|
||||
--library=libbig-1.0.la \
|
||||
$(addprefix $(srcdir)/,$(big_source_h)) \
|
||||
$(addprefix $(srcdir)/,$(big_source_c)) \
|
||||
$(srcdir)/big-enum-types.h \
|
||||
$(big_cflags) \
|
||||
-o $@
|
||||
CLEANFILES += Big-1.0.gir
|
||||
|
||||
Big-1.0.typelib: libbig-1.0.la Big-1.0.gir
|
||||
$(AM_V_GEN) $(G_IR_COMPILER) Big-1.0.gir -o $@
|
||||
CLEANFILES += Big-1.0.typelib
|
||||
|
||||
St-1.0.gir: $(mutter) $(G_IR_SCANNER) libst-1.0.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
--namespace=St \
|
||||
@ -220,7 +238,6 @@ St-1.0.gir: $(mutter) $(G_IR_SCANNER) libst-1.0.la Makefile
|
||||
--add-include-path=$(builddir) \
|
||||
--libtool="$(LIBTOOL)" \
|
||||
--library=libst-1.0.la \
|
||||
--library=libbig-1.0.la \
|
||||
-DST_COMPILATION \
|
||||
$(addprefix $(srcdir)/,$(st_source_h)) \
|
||||
$(addprefix $(srcdir)/,$(st_source_c)) \
|
||||
@ -249,7 +266,7 @@ Gdm-1.0.gir: $(mutter) $(G_IR_SCANNER) libgdmuser-1.0.la Makefile
|
||||
-o $@
|
||||
CLEANFILES += Gdm-1.0.gir
|
||||
|
||||
Gdm-1.0.typelib: libbig-1.0.la Gdm-1.0.gir
|
||||
Gdm-1.0.typelib: Gdm-1.0.gir
|
||||
$(AM_V_GEN) $(G_IR_COMPILER) Gdm-1.0.gir -o $@
|
||||
CLEANFILES += Gdm-1.0.typelib
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
The Clutter actors and other files in this directory were created by
|
||||
litl, LLC. They are released under the terms of the Library General
|
||||
Public license.
|
||||
|
||||
The idea is that these actors may eventually make their way into Clutter
|
||||
or into other libraries.
|
||||
|
||||
litl has requested that these actors should not be publically
|
||||
installed under the 'big_*' names to avoid conflicts with their
|
||||
development. So if you use them in your applications, do *NOT*
|
||||
install:
|
||||
|
||||
- A 'libbig' library
|
||||
- The header files
|
||||
- gobject-introspection data for these actors
|
||||
|
||||
Into public locations. You can of course, take the code and rename it,
|
||||
as long as you respect the provisions of the LGPL, or install into
|
||||
private locations as we do for gnome-shell. (We install the typelib
|
||||
into a private location, link the source files directly into the
|
||||
gnome-shell plugin so no external library is needed, and we don't
|
||||
install the header files at all.)
|
||||
|
||||
Patches applied:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=562929
|
3060
src/big/box.c
3060
src/big/box.c
File diff suppressed because it is too large
Load Diff
129
src/big/box.h
129
src/big/box.h
@ -1,129 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
|
||||
/* big-box.h: Box container.
|
||||
|
||||
Copyright (C) 2006-2008 Red Hat, Inc.
|
||||
Copyright (C) 2008 litl, LLC.
|
||||
|
||||
The libbigwidgets-lgpl is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The libbigwidgets-lgpl is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the libbigwidgets-lgpl; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation, Inc., 59 Temple Place -
|
||||
Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BIG_BOX_H__
|
||||
#define __BIG_BOX_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BIG_TYPE_BOX (big_box_get_type ())
|
||||
#define BIG_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BIG_TYPE_BOX, BigBox))
|
||||
#define BIG_IS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BIG_TYPE_BOX))
|
||||
#define BIG_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BIG_TYPE_BOX, BigBoxClass))
|
||||
#define BIG_IS_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BIG_TYPE_BOX))
|
||||
#define BIG_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BIG_TYPE_BOX, BigBoxClass))
|
||||
|
||||
typedef struct _BigBox BigBox;
|
||||
typedef struct _BigBoxPrivate BigBoxPrivate;
|
||||
typedef struct _BigBoxClass BigBoxClass;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIG_BOX_PACK_NONE = 0,
|
||||
BIG_BOX_PACK_EXPAND = 1 << 0,
|
||||
BIG_BOX_PACK_END = 1 << 1,
|
||||
BIG_BOX_PACK_IF_FITS = 1 << 2,
|
||||
BIG_BOX_PACK_FIXED = 1 << 3,
|
||||
BIG_BOX_PACK_ALLOCATE_WHEN_HIDDEN = 1 << 4
|
||||
} BigBoxPackFlags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIG_BOX_ALIGNMENT_FIXED = 0,
|
||||
BIG_BOX_ALIGNMENT_FILL = 1,
|
||||
BIG_BOX_ALIGNMENT_START = 2,
|
||||
BIG_BOX_ALIGNMENT_END = 3,
|
||||
BIG_BOX_ALIGNMENT_CENTER = 4
|
||||
} BigBoxAlignment;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIG_BOX_ORIENTATION_VERTICAL = 1,
|
||||
BIG_BOX_ORIENTATION_HORIZONTAL = 2
|
||||
} BigBoxOrientation;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BIG_BOX_BACKGROUND_REPEAT_NONE = 0,
|
||||
BIG_BOX_BACKGROUND_REPEAT_X = 1,
|
||||
BIG_BOX_BACKGROUND_REPEAT_Y = 2,
|
||||
BIG_BOX_BACKGROUND_REPEAT_BOTH = 3,
|
||||
} BigBoxBackgroundRepeat;
|
||||
|
||||
struct _BigBox
|
||||
{
|
||||
ClutterActor parent_instance;
|
||||
|
||||
BigBoxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _BigBoxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
GType big_box_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *big_box_new (BigBoxOrientation orientation);
|
||||
|
||||
void big_box_prepend (BigBox *box,
|
||||
ClutterActor *child,
|
||||
BigBoxPackFlags flags);
|
||||
|
||||
void big_box_append (BigBox *box,
|
||||
ClutterActor *child,
|
||||
BigBoxPackFlags flags);
|
||||
|
||||
gboolean big_box_is_empty (BigBox *box);
|
||||
|
||||
void big_box_remove_all (BigBox *box);
|
||||
|
||||
void big_box_insert_after (BigBox *box,
|
||||
ClutterActor *child,
|
||||
ClutterActor *ref_child,
|
||||
BigBoxPackFlags flags);
|
||||
|
||||
void big_box_insert_before (BigBox *box,
|
||||
ClutterActor *child,
|
||||
ClutterActor *ref_child,
|
||||
BigBoxPackFlags flags);
|
||||
|
||||
void big_box_set_child_packing (BigBox *box,
|
||||
ClutterActor *child,
|
||||
BigBoxPackFlags flags);
|
||||
|
||||
void big_box_set_child_align (BigBox *box,
|
||||
ClutterActor *child,
|
||||
BigBoxAlignment fixed_x_align,
|
||||
BigBoxAlignment fixed_y_align);
|
||||
|
||||
void big_box_set_padding (BigBox *box,
|
||||
int padding);
|
||||
|
||||
void big_box_set_border_width (BigBox *box,
|
||||
int border_width);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BIG_BOX_H__ */
|
@ -1,658 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/* rectangle.c: Rounded rectangle.
|
||||
|
||||
Copyright (C) 2008 litl, LLC.
|
||||
|
||||
The libbigwidgets-lgpl is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The libbigwidgets-lgpl is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the libbigwidgets-lgpl; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation, Inc., 59 Temple Place -
|
||||
Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <cairo/cairo.h>
|
||||
|
||||
#include "rectangle.h"
|
||||
|
||||
typedef struct {
|
||||
gint ref_count;
|
||||
|
||||
ClutterColor color;
|
||||
ClutterColor border_color;
|
||||
int radius;
|
||||
int border_width;
|
||||
|
||||
CoglHandle texture;
|
||||
guint8 *data;
|
||||
} Corner;
|
||||
|
||||
struct BigRectangle {
|
||||
ClutterRectangle parent_instance;
|
||||
float radius;
|
||||
Corner *corner;
|
||||
CoglHandle corner_material;
|
||||
CoglHandle border_material;
|
||||
CoglHandle background_material;
|
||||
gboolean corners_dirty;
|
||||
};
|
||||
|
||||
/* map of { radius, border_width, border_color, color } to Corner textures */
|
||||
static GHashTable *all_corners = NULL;
|
||||
|
||||
struct BigRectangleClass {
|
||||
ClutterRectangleClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(BigRectangle, big_rectangle, CLUTTER_TYPE_RECTANGLE)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_CORNER_RADIUS
|
||||
};
|
||||
|
||||
static gboolean
|
||||
corner_equal(gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
const Corner *corner_a;
|
||||
const Corner *corner_b;
|
||||
|
||||
corner_a = a;
|
||||
corner_b = b;
|
||||
|
||||
return *((guint32 *)&corner_a->color) == *((guint32 *)&corner_b->color) &&
|
||||
*((guint32 *)&corner_a->border_color) == *((guint32 *)&corner_b->border_color) &&
|
||||
corner_a->border_width == corner_b->border_width &&
|
||||
corner_a->radius == corner_b->radius;
|
||||
}
|
||||
|
||||
static guint
|
||||
corner_hash(gconstpointer key)
|
||||
{
|
||||
const Corner *corner;
|
||||
guint hashed[4];
|
||||
|
||||
corner = key;
|
||||
|
||||
hashed[0] = *((guint *)&(corner->color));
|
||||
hashed[1] = *((guint *)&(corner->border_color));
|
||||
hashed[2] = *((guint *)&(corner->border_width));
|
||||
hashed[3] = *((guint *)&(corner->radius));
|
||||
|
||||
return hashed[0] ^ hashed[1] ^ hashed[2] ^ hashed[3];
|
||||
}
|
||||
|
||||
static Corner *
|
||||
create_corner_texture(Corner *src)
|
||||
{
|
||||
Corner *corner;
|
||||
CoglHandle texture;
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *surface;
|
||||
guint x, y;
|
||||
guint rowstride;
|
||||
guint8 *data;
|
||||
guint32 *src_p;
|
||||
guint8 *dst_p;
|
||||
guint size;
|
||||
|
||||
corner = g_memdup(src, sizeof(Corner));
|
||||
|
||||
size = 2 * MAX(corner->border_width, corner->radius);
|
||||
rowstride = size * 4;
|
||||
data = g_new0(guint8, size * rowstride);
|
||||
|
||||
surface = cairo_image_surface_create_for_data(data,
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
size, size,
|
||||
rowstride);
|
||||
cr = cairo_create(surface);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_scale(cr, size, size);
|
||||
|
||||
if (corner->border_width < corner->radius) {
|
||||
double internal_radius = 0.5 * (1.0 - (double) corner->border_width / corner->radius);
|
||||
|
||||
if (corner->border_width != 0) {
|
||||
cairo_set_source_rgba(cr,
|
||||
(double)corner->border_color.red / G_MAXUINT8,
|
||||
(double)corner->border_color.green / G_MAXUINT8,
|
||||
(double)corner->border_color.blue / G_MAXUINT8,
|
||||
(double)corner->border_color.alpha / G_MAXUINT8);
|
||||
|
||||
cairo_arc(cr, 0.5, 0.5, 0.5, 0, 2 * M_PI);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
|
||||
cairo_set_source_rgba(cr,
|
||||
(double)corner->color.red / G_MAXUINT8,
|
||||
(double)corner->color.green / G_MAXUINT8,
|
||||
(double)corner->color.blue / G_MAXUINT8,
|
||||
(double)corner->color.alpha / G_MAXUINT8);
|
||||
cairo_arc(cr, 0.5, 0.5, internal_radius, 0, 2 * M_PI);
|
||||
cairo_fill(cr);
|
||||
|
||||
} else {
|
||||
double radius;
|
||||
|
||||
radius = (gdouble)corner->radius / corner->border_width;
|
||||
|
||||
cairo_set_source_rgba(cr,
|
||||
(double)corner->border_color.red / G_MAXUINT8,
|
||||
(double)corner->border_color.green / G_MAXUINT8,
|
||||
(double)corner->border_color.blue / G_MAXUINT8,
|
||||
(double)corner->border_color.alpha / G_MAXUINT8);
|
||||
|
||||
cairo_arc(cr, radius, radius, radius, M_PI, 3 * M_PI / 2);
|
||||
cairo_line_to(cr, 1.0 - radius, 0.0);
|
||||
cairo_arc(cr, 1.0 - radius, radius, radius, 3 * M_PI / 2, 2*M_PI);
|
||||
cairo_line_to(cr, 1.0, 1.0 - radius);
|
||||
cairo_arc(cr, 1.0 - radius, 1.0 - radius, radius, 0, M_PI / 2);
|
||||
cairo_line_to(cr, radius, 1.0);
|
||||
cairo_arc(cr, radius, 1.0 - radius, radius, M_PI / 2, M_PI);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
cairo_destroy(cr);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
|
||||
corner->data = g_new0(guint8, size * rowstride);
|
||||
|
||||
/* cogl doesn't seem to support the conversion, do it manually */
|
||||
/* borrowed from clutter-cairo, conversion from ARGB pre-multiplied
|
||||
* to RGBA */
|
||||
for (y = 0; y < size; y++) {
|
||||
src_p = (guint32 *) (data + y * rowstride);
|
||||
dst_p = corner->data + y * rowstride;
|
||||
|
||||
for (x = 0; x < size; x++) {
|
||||
guint8 alpha = (*src_p >> 24) & 0xff;
|
||||
|
||||
if (alpha == 0) {
|
||||
dst_p[0] = dst_p[1] = dst_p[2] = dst_p[3] = alpha;
|
||||
} else {
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
dst_p[0] = (((*src_p >> 16) & 0xff) * 255 ) / alpha;
|
||||
dst_p[1] = (((*src_p >> 8) & 0xff) * 255 ) / alpha;
|
||||
dst_p[2] = (((*src_p >> 0) & 0xff) * 255 ) / alpha;
|
||||
dst_p[3] = alpha;
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
dst_p[0] = alpha;
|
||||
dst_p[1] = (((*src_p >> 0) & 0xff) * 255 ) / alpha;
|
||||
dst_p[2] = (((*src_p >> 8) & 0xff) * 255 ) / alpha;
|
||||
dst_p[3] = (((*src_p >> 16) & 0xff) * 255 ) / alpha;
|
||||
#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
|
||||
#error unknown ENDIAN type
|
||||
#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
|
||||
}
|
||||
dst_p += 4;
|
||||
src_p++;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(data);
|
||||
|
||||
texture = cogl_texture_new_from_data(size, size,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
rowstride,
|
||||
corner->data);
|
||||
g_assert(texture != COGL_INVALID_HANDLE);
|
||||
|
||||
corner->ref_count = 1;
|
||||
corner->texture = texture;
|
||||
|
||||
g_hash_table_insert(all_corners, corner, corner);
|
||||
|
||||
return corner;
|
||||
}
|
||||
|
||||
static void
|
||||
corner_unref(Corner *corner)
|
||||
{
|
||||
corner->ref_count --;
|
||||
|
||||
if (corner->ref_count == 0) {
|
||||
g_hash_table_remove(all_corners, corner);
|
||||
|
||||
cogl_handle_unref(corner->texture);
|
||||
g_free(corner->data);
|
||||
g_free(corner);
|
||||
}
|
||||
}
|
||||
|
||||
static Corner *
|
||||
corner_get(guint radius,
|
||||
ClutterColor *color,
|
||||
guint border_width,
|
||||
ClutterColor *border_color)
|
||||
{
|
||||
Corner key;
|
||||
Corner *corner;
|
||||
|
||||
if (all_corners == NULL) {
|
||||
all_corners = g_hash_table_new(corner_hash, corner_equal);
|
||||
}
|
||||
|
||||
key.radius = radius;
|
||||
key.color = *color;
|
||||
key.border_color = *border_color;
|
||||
key.border_width = border_width;
|
||||
|
||||
corner = g_hash_table_lookup(all_corners, &key);
|
||||
|
||||
if (!corner) {
|
||||
corner = create_corner_texture(&key);
|
||||
} else {
|
||||
corner->ref_count ++;
|
||||
}
|
||||
|
||||
return corner;
|
||||
}
|
||||
|
||||
/* To match the CSS specification, we want the border to look like it was
|
||||
* drawn over the background. But actually drawing the border over the
|
||||
* background will produce slightly bad antialiasing at the edges, so
|
||||
* compute the effective border color instead.
|
||||
*/
|
||||
#define NORM(x) (t = (x) + 127, (t + (t >> 8)) >> 8)
|
||||
#define MULT(c,a) NORM(c*a)
|
||||
|
||||
static void
|
||||
premultiply (ClutterColor *color)
|
||||
{
|
||||
guint t;
|
||||
color->red = MULT (color->red, color->alpha);
|
||||
color->green = MULT (color->green, color->alpha);
|
||||
color->blue = MULT (color->blue, color->alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
unpremultiply (ClutterColor *color)
|
||||
{
|
||||
if (color->alpha != 0) {
|
||||
color->red = (color->red * 255 + 127) / color->alpha;
|
||||
color->green = (color->green * 255 + 127) / color->alpha;
|
||||
color->blue = (color->blue * 255 + 127) / color->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
over (const ClutterColor *source,
|
||||
const ClutterColor *destination,
|
||||
ClutterColor *result)
|
||||
{
|
||||
guint t;
|
||||
ClutterColor src = *source;
|
||||
ClutterColor dst = *destination;
|
||||
premultiply (&src);
|
||||
premultiply (&dst);
|
||||
|
||||
result->alpha = src.alpha + NORM ((255 - src.alpha) * dst.alpha);
|
||||
result->red = src.red + NORM ((255 - src.alpha) * dst.red);
|
||||
result->green = src.green + NORM ((255 - src.alpha) * dst.green);
|
||||
result->blue = src.blue + NORM ((255 - src.alpha) * dst.blue);
|
||||
|
||||
unpremultiply (result);
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_update_corners(BigRectangle *rectangle)
|
||||
{
|
||||
Corner *corner;
|
||||
|
||||
corner = NULL;
|
||||
|
||||
if (rectangle->radius != 0) {
|
||||
ClutterColor *color;
|
||||
ClutterColor *border_color;
|
||||
ClutterColor effective_border;
|
||||
guint border_width;
|
||||
|
||||
g_object_get(rectangle,
|
||||
"border-color", &border_color,
|
||||
"border-width", &border_width,
|
||||
"color", &color,
|
||||
NULL);
|
||||
|
||||
over (border_color, color, &effective_border);
|
||||
|
||||
corner = corner_get(rectangle->radius,
|
||||
color,
|
||||
border_width,
|
||||
&effective_border);
|
||||
|
||||
clutter_color_free(border_color);
|
||||
clutter_color_free(color);
|
||||
}
|
||||
|
||||
if (rectangle->corner) {
|
||||
corner_unref(rectangle->corner);
|
||||
}
|
||||
|
||||
rectangle->corner = corner;
|
||||
|
||||
if (corner) {
|
||||
if (!rectangle->corner_material)
|
||||
rectangle->corner_material = cogl_material_new();
|
||||
|
||||
cogl_material_set_layer (rectangle->corner_material, 0,
|
||||
rectangle->corner->texture);
|
||||
}
|
||||
|
||||
rectangle->corners_dirty = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_paint(ClutterActor *actor)
|
||||
{
|
||||
BigRectangle *rectangle;
|
||||
ClutterColor *color;
|
||||
ClutterColor *border_color;
|
||||
guint8 actor_opacity;
|
||||
CoglColor tmp_color;
|
||||
guint border_width;
|
||||
ClutterActorBox box;
|
||||
float radius;
|
||||
float width;
|
||||
float height;
|
||||
float max;
|
||||
|
||||
rectangle = BIG_RECTANGLE(actor);
|
||||
|
||||
/* We can't chain up, even when we the radius is 0, because of the different
|
||||
* interpretation of the border/background relationship here than for
|
||||
* ClutterRectangle.
|
||||
*/
|
||||
|
||||
if (rectangle->corners_dirty)
|
||||
big_rectangle_update_corners(rectangle);
|
||||
|
||||
g_object_get(rectangle,
|
||||
"border-color", &border_color,
|
||||
"border-width", &border_width,
|
||||
"color", &color,
|
||||
NULL);
|
||||
|
||||
if (border_color->alpha == 0 && color->alpha == 0)
|
||||
goto out;
|
||||
|
||||
actor_opacity = clutter_actor_get_paint_opacity (actor);
|
||||
|
||||
clutter_actor_get_allocation_box(actor, &box);
|
||||
|
||||
/* translation was already done */
|
||||
box.x2 -= box.x1;
|
||||
box.y2 -= box.y1;
|
||||
|
||||
width = box.x2;
|
||||
height = box.y2;
|
||||
|
||||
radius = rectangle->radius;
|
||||
|
||||
/* Optimization; if the border is transparent, it just looks like part of
|
||||
* the background */
|
||||
if (radius == 0 && border_color->alpha == 0)
|
||||
border_width = 0;
|
||||
|
||||
max = MAX(border_width, radius);
|
||||
|
||||
if (radius != 0) {
|
||||
cogl_color_set_from_4ub(&tmp_color,
|
||||
actor_opacity, actor_opacity, actor_opacity, actor_opacity);
|
||||
cogl_material_set_color(rectangle->corner_material, &tmp_color);
|
||||
cogl_set_source(rectangle->corner_material);
|
||||
|
||||
/* NW */
|
||||
cogl_rectangle_with_texture_coords(0, 0,
|
||||
max, max,
|
||||
0, 0,
|
||||
0.5, 0.5);
|
||||
|
||||
/* NE */
|
||||
cogl_rectangle_with_texture_coords(width - max, 0,
|
||||
width, max,
|
||||
0.5, 0,
|
||||
1.0, 0.5);
|
||||
|
||||
/* SW */
|
||||
cogl_rectangle_with_texture_coords(0, height - max,
|
||||
max, height,
|
||||
0, 0.5,
|
||||
0.5, 1.0);
|
||||
|
||||
/* SE */
|
||||
cogl_rectangle_with_texture_coords(width - max, height - max,
|
||||
width, height,
|
||||
0.5, 0.5,
|
||||
1.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
if (border_width != 0) {
|
||||
ClutterColor effective_border;
|
||||
over (border_color, color, &effective_border);
|
||||
|
||||
if (!rectangle->border_material)
|
||||
rectangle->border_material = cogl_material_new ();
|
||||
|
||||
cogl_color_set_from_4ub(&tmp_color,
|
||||
effective_border.red,
|
||||
effective_border.green,
|
||||
effective_border.blue,
|
||||
actor_opacity * effective_border.alpha / 255);
|
||||
cogl_color_premultiply (&tmp_color);
|
||||
cogl_material_set_color(rectangle->border_material, &tmp_color);
|
||||
cogl_set_source(rectangle->border_material);
|
||||
|
||||
if (radius > 0) { /* skip corners */
|
||||
/* NORTH */
|
||||
cogl_rectangle(max, 0,
|
||||
width - max, border_width);
|
||||
|
||||
/* EAST */
|
||||
cogl_rectangle(width - border_width, max,
|
||||
width, height - max);
|
||||
|
||||
/* SOUTH */
|
||||
cogl_rectangle(max, height - border_width,
|
||||
width - max, height);
|
||||
|
||||
/* WEST */
|
||||
cogl_rectangle(0, max,
|
||||
border_width, height - max);
|
||||
} else { /* include corners */
|
||||
/* NORTH */
|
||||
cogl_rectangle(0, 0,
|
||||
width, border_width);
|
||||
|
||||
/* EAST */
|
||||
cogl_rectangle(width - border_width, border_width,
|
||||
width, height - border_width);
|
||||
|
||||
/* SOUTH */
|
||||
cogl_rectangle(0, height - border_width,
|
||||
width, height);
|
||||
|
||||
/* WEST */
|
||||
cogl_rectangle(0, border_width,
|
||||
border_width, height - border_width);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rectangle->background_material)
|
||||
rectangle->background_material = cogl_material_new ();
|
||||
|
||||
cogl_color_set_from_4ub(&tmp_color,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
actor_opacity * color->alpha / 255);
|
||||
cogl_color_premultiply (&tmp_color);
|
||||
cogl_material_set_color(rectangle->background_material, &tmp_color);
|
||||
cogl_set_source(rectangle->background_material);
|
||||
|
||||
if (radius > border_width) {
|
||||
/* Once we've drawn the borders and corners, if the corners are bigger
|
||||
* the the border width, the remaining area is shaped like
|
||||
*
|
||||
* ########
|
||||
* ##########
|
||||
* ##########
|
||||
* ########
|
||||
*
|
||||
* We draw it in 3 pieces - first the top and bottom, then the main
|
||||
* rectangle
|
||||
*/
|
||||
cogl_rectangle(radius, border_width,
|
||||
width - radius, radius);
|
||||
cogl_rectangle(radius, height - radius,
|
||||
width - radius, height - border_width);
|
||||
}
|
||||
|
||||
cogl_rectangle(border_width, max,
|
||||
width - border_width, height - max);
|
||||
|
||||
out:
|
||||
clutter_color_free(border_color);
|
||||
clutter_color_free(color);
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_notify(GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BigRectangle *rectangle;
|
||||
|
||||
rectangle = BIG_RECTANGLE(object);
|
||||
|
||||
if (g_str_equal(pspec->name, "border-width") ||
|
||||
g_str_equal(pspec->name, "color") ||
|
||||
g_str_equal(pspec->name, "border-color")) {
|
||||
rectangle->corners_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BigRectangle *rectangle;
|
||||
|
||||
rectangle = BIG_RECTANGLE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CORNER_RADIUS:
|
||||
rectangle->radius = g_value_get_uint(value);
|
||||
rectangle->corners_dirty = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BigRectangle *rectangle;
|
||||
|
||||
rectangle = BIG_RECTANGLE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CORNER_RADIUS:
|
||||
g_value_set_uint(value, rectangle->radius);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_dispose(GObject *object)
|
||||
{
|
||||
BigRectangle *rectangle;
|
||||
|
||||
rectangle = BIG_RECTANGLE(object);
|
||||
|
||||
if (rectangle->corner) {
|
||||
corner_unref(rectangle->corner);
|
||||
rectangle->corner = NULL;
|
||||
}
|
||||
|
||||
if (rectangle->corner_material) {
|
||||
cogl_handle_unref (rectangle->corner_material);
|
||||
rectangle->corner_material = NULL;
|
||||
}
|
||||
|
||||
if (rectangle->background_material) {
|
||||
cogl_handle_unref (rectangle->background_material);
|
||||
rectangle->background_material = NULL;
|
||||
}
|
||||
|
||||
if (rectangle->border_material) {
|
||||
cogl_handle_unref (rectangle->border_material);
|
||||
rectangle->border_material = NULL;
|
||||
}
|
||||
|
||||
if (G_OBJECT_CLASS(big_rectangle_parent_class)->dispose)
|
||||
G_OBJECT_CLASS(big_rectangle_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
big_rectangle_class_init(BigRectangleClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = big_rectangle_dispose;
|
||||
gobject_class->set_property = big_rectangle_set_property;
|
||||
gobject_class->get_property = big_rectangle_get_property;
|
||||
gobject_class->notify = big_rectangle_notify;
|
||||
|
||||
actor_class->paint = big_rectangle_paint;
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_CORNER_RADIUS,
|
||||
g_param_spec_uint("corner-radius",
|
||||
"Corner radius",
|
||||
"Radius of the rectangle rounded corner",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
big_rectangle_init(BigRectangle *rectangle)
|
||||
{
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
Copyright (C) 2008 litl, LLC.
|
||||
|
||||
The libbigwidgets-lgpl is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The libbigwidgets-lgpl is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the libbigwidgets-lgpl; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation, Inc., 59 Temple Place -
|
||||
Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef __BIG_RECTANGLE_H__
|
||||
#define __BIG_RECTANGLE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BIG_TYPE_RECTANGLE (big_rectangle_get_type ())
|
||||
#define BIG_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BIG_TYPE_RECTANGLE, BigRectangle))
|
||||
#define BIG_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BIG_TYPE_RECTANGLE, BigRectangleClass))
|
||||
#define BIG_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BIG_TYPE_RECTANGLE))
|
||||
#define BIG_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BIG_TYPE_RECTANGLE))
|
||||
#define BIG_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BIG_TYPE_RECTANGLE, BigRectangleClass))
|
||||
|
||||
typedef struct BigRectangle BigRectangle;
|
||||
typedef struct BigRectangleClass BigRectangleClass;
|
||||
|
||||
GType big_rectangle_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BIG_RECTANGLE_H__ */
|
@ -1,791 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/* theme-image.c: Stretched image.
|
||||
|
||||
Copyright (C) 2005-2008 Red Hat, Inc.
|
||||
Copyright (C) 2008 litl, LLC.
|
||||
|
||||
The libbigwidgets-lgpl is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The libbigwidgets-lgpl is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the libbigwidgets-lgpl; see the file COPYING.LIB.
|
||||
If not, write to the Free Software Foundation, Inc., 59 Temple Place -
|
||||
Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include <librsvg/rsvg.h>
|
||||
#include <librsvg/rsvg-cairo.h>
|
||||
|
||||
#include "theme-image.h"
|
||||
|
||||
typedef enum {
|
||||
BIG_THEME_IMAGE_UNSET,
|
||||
BIG_THEME_IMAGE_SVG,
|
||||
BIG_THEME_IMAGE_SURFACE
|
||||
|
||||
} BigThemeImageType;
|
||||
|
||||
struct BigThemeImage {
|
||||
ClutterCairoTexture parent_instance;
|
||||
|
||||
guint border_top;
|
||||
guint border_bottom;
|
||||
guint border_left;
|
||||
guint border_right;
|
||||
|
||||
BigThemeImageType type;
|
||||
|
||||
union {
|
||||
RsvgHandle *svg_handle;
|
||||
cairo_surface_t *surface;
|
||||
} u;
|
||||
|
||||
guint render_idle;
|
||||
guint needs_render : 1;
|
||||
};
|
||||
|
||||
struct BigThemeImageClass {
|
||||
ClutterCairoTextureClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(BigThemeImage, big_theme_image, CLUTTER_TYPE_CAIRO_TEXTURE)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_BORDER_TOP,
|
||||
PROP_BORDER_BOTTOM,
|
||||
PROP_BORDER_LEFT,
|
||||
PROP_BORDER_RIGHT,
|
||||
|
||||
PROP_FILENAME,
|
||||
PROP_PIXBUF
|
||||
};
|
||||
|
||||
static void
|
||||
big_theme_image_render(BigThemeImage *image)
|
||||
{
|
||||
int source_width = 0;
|
||||
int source_height = 0;
|
||||
int source_x1 = 0, source_x2 = 0, source_y1 = 0, source_y2 = 0;
|
||||
int dest_x1 = 0, dest_x2 = 0, dest_y1 = 0, dest_y2 = 0;
|
||||
int i, j;
|
||||
int dest_width;
|
||||
int dest_height;
|
||||
ClutterGeometry geometry;
|
||||
cairo_t *cr;
|
||||
|
||||
image->needs_render = FALSE;
|
||||
|
||||
if (image->render_idle) {
|
||||
g_source_remove(image->render_idle);
|
||||
image->render_idle = 0;
|
||||
}
|
||||
|
||||
|
||||
/* To draw a theme image, we divide the source and destination into 9
|
||||
* pieces and draw each piece separately. (Some pieces may not exist
|
||||
* if we have 0-width borders, in which case they'll be skipped)
|
||||
*
|
||||
* i=0 i=1 i=2
|
||||
* border_left border_right
|
||||
* +------------+--------------------+--------------+
|
||||
* j=0: border_top | | | |
|
||||
* +------------+--------------------+--------------+
|
||||
* j=1 | | | |
|
||||
* +------------+--------------------+--------------+
|
||||
* j=2: border_bottom | | | |
|
||||
* +------------+--------------------+--------------+
|
||||
*
|
||||
*/
|
||||
|
||||
switch (image->type) {
|
||||
case BIG_THEME_IMAGE_SURFACE:
|
||||
if (!image->u.surface)
|
||||
return;
|
||||
|
||||
source_width = cairo_image_surface_get_width(image->u.surface);
|
||||
source_height = cairo_image_surface_get_height(image->u.surface);
|
||||
break;
|
||||
case BIG_THEME_IMAGE_SVG:
|
||||
{
|
||||
RsvgDimensionData dimensions;
|
||||
|
||||
if (!image->u.svg_handle)
|
||||
return;
|
||||
|
||||
rsvg_handle_get_dimensions(image->u.svg_handle, &dimensions);
|
||||
source_width = dimensions.width;
|
||||
source_height = dimensions.height;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
clutter_actor_get_allocation_geometry(CLUTTER_ACTOR(image), &geometry);
|
||||
|
||||
dest_width = geometry.width;
|
||||
dest_height = geometry.height;
|
||||
|
||||
cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(image));
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
switch (j) {
|
||||
case 0:
|
||||
source_y1 = 0;
|
||||
source_y2 = image->border_top;
|
||||
dest_y1 = 0;
|
||||
dest_y2 = image->border_top;
|
||||
break;
|
||||
case 1:
|
||||
source_y1 = image->border_top;
|
||||
source_y2 = source_height - image->border_bottom;
|
||||
dest_y1 = image->border_top;
|
||||
dest_y2 = dest_height - image->border_bottom;
|
||||
break;
|
||||
case 2:
|
||||
source_y1 = source_height - image->border_bottom;
|
||||
source_y2 = source_height;
|
||||
dest_y1 = dest_height - image->border_bottom;
|
||||
dest_y2 = dest_height;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dest_y2 <= dest_y1)
|
||||
continue;
|
||||
|
||||
/* pixbuf-theme-engine has a nice interpretation of source_y2 == source_y1,
|
||||
* dest_y2 != dest_y1, which is to linearly interpolate between the surrounding
|
||||
* areas. We could do that for the surface case by setting
|
||||
*
|
||||
* source_y1 == y - 0.5
|
||||
* source_y2 == y + 0.5
|
||||
*
|
||||
* but it's hard for the SVG case. source_y2 < source_y1 is pathological ... someone
|
||||
* specified borders that sum up larger than the image.
|
||||
*/
|
||||
if (source_y2 <= source_y1)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
source_x1 = 0;
|
||||
source_x2 = image->border_left;
|
||||
dest_x1 = 0;
|
||||
dest_x2 = image->border_left;
|
||||
break;
|
||||
case 1:
|
||||
source_x1 = image->border_left;
|
||||
source_x2 = source_width - image->border_right;
|
||||
dest_x1 = image->border_left;
|
||||
dest_x2 = dest_width - image->border_right;
|
||||
break;
|
||||
case 2:
|
||||
source_x1 = source_width - image->border_right;
|
||||
source_x2 = source_width;
|
||||
dest_x1 = dest_width - image->border_right;
|
||||
dest_x2 = dest_width;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dest_x2 <= dest_x1)
|
||||
continue;
|
||||
|
||||
if (source_x2 <= source_x1)
|
||||
continue;
|
||||
|
||||
cairo_save(cr);
|
||||
|
||||
cairo_rectangle(cr, dest_x1, dest_y1, dest_x2 - dest_x1, dest_y2 - dest_y1);
|
||||
cairo_clip(cr);
|
||||
|
||||
cairo_translate(cr, dest_x1, dest_y1);
|
||||
cairo_scale(cr,
|
||||
(double)(dest_x2 - dest_x1) / (source_x2 - source_x1),
|
||||
(double)(dest_y2 - dest_y1) / (source_y2 - source_y1));
|
||||
|
||||
switch (image->type) {
|
||||
case BIG_THEME_IMAGE_SURFACE:
|
||||
cairo_set_source_surface(cr, image->u.surface, - source_x1, - source_y1);
|
||||
cairo_paint(cr);
|
||||
break;
|
||||
case BIG_THEME_IMAGE_SVG:
|
||||
cairo_translate(cr, - source_x1, - source_y1);
|
||||
rsvg_handle_render_cairo(image->u.svg_handle, cr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cairo_restore(cr);
|
||||
}
|
||||
}
|
||||
|
||||
/* This will cause the surface content to be uploaded as
|
||||
* new texture content */
|
||||
cairo_destroy(cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
big_theme_image_render_idle(gpointer data)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = data;
|
||||
big_theme_image_render(image);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_queue_render(BigThemeImage *image)
|
||||
{
|
||||
image->needs_render = TRUE;
|
||||
if (!image->render_idle)
|
||||
image->render_idle = g_idle_add(big_theme_image_render_idle,
|
||||
image);
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_paint(ClutterActor *actor)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(actor);
|
||||
|
||||
if (image->needs_render)
|
||||
big_theme_image_render(image);
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS(big_theme_image_parent_class)->paint)
|
||||
CLUTTER_ACTOR_CLASS(big_theme_image_parent_class)->paint(actor);
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_allocate(ClutterActor *actor,
|
||||
const ClutterActorBox *box,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
guint old_width;
|
||||
guint old_height;
|
||||
guint width;
|
||||
guint height;
|
||||
|
||||
image = BIG_THEME_IMAGE(actor);
|
||||
|
||||
width = ABS(box->x2 - box->x1);
|
||||
height = ABS(box->y2 - box->y1);
|
||||
|
||||
g_object_get(actor,
|
||||
"surface-width", &old_width,
|
||||
"surface-height", &old_height,
|
||||
NULL);
|
||||
|
||||
if (width != old_width || height != old_height) {
|
||||
|
||||
clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(actor), width, height);
|
||||
|
||||
big_theme_image_queue_render(image);
|
||||
}
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS(big_theme_image_parent_class))
|
||||
CLUTTER_ACTOR_CLASS(big_theme_image_parent_class)->allocate(actor,
|
||||
box,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_get_preferred_height(ClutterActor *actor,
|
||||
float for_width,
|
||||
float *min_height_p,
|
||||
float *natural_height_p)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(actor);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (!natural_height_p)
|
||||
return;
|
||||
|
||||
*natural_height_p = 0;
|
||||
|
||||
switch (image->type) {
|
||||
case BIG_THEME_IMAGE_SURFACE:
|
||||
if (!image->u.surface)
|
||||
break;
|
||||
|
||||
*natural_height_p = cairo_image_surface_get_height(image->u.surface);
|
||||
break;
|
||||
case BIG_THEME_IMAGE_SVG:
|
||||
{
|
||||
RsvgDimensionData dimensions;
|
||||
|
||||
if (!image->u.svg_handle)
|
||||
return;
|
||||
|
||||
rsvg_handle_get_dimensions(image->u.svg_handle, &dimensions);
|
||||
*natural_height_p = dimensions.height;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_get_preferred_width(ClutterActor *actor,
|
||||
float for_height,
|
||||
float *min_width_p,
|
||||
float *natural_width_p)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(actor);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (!natural_width_p)
|
||||
return;
|
||||
|
||||
*natural_width_p = 0;
|
||||
|
||||
switch (image->type) {
|
||||
case BIG_THEME_IMAGE_SURFACE:
|
||||
if (!image->u.surface)
|
||||
break;
|
||||
|
||||
*natural_width_p = cairo_image_surface_get_width(image->u.surface);
|
||||
break;
|
||||
case BIG_THEME_IMAGE_SVG:
|
||||
{
|
||||
RsvgDimensionData dimensions;
|
||||
|
||||
if (!image->u.svg_handle)
|
||||
return;
|
||||
|
||||
rsvg_handle_get_dimensions(image->u.svg_handle, &dimensions);
|
||||
*natural_width_p = dimensions.width;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_set_border_value(BigThemeImage *image, guint *old_value, const GValue *new_value)
|
||||
{
|
||||
guint border_value;
|
||||
|
||||
border_value = g_value_get_uint(new_value);
|
||||
|
||||
if (*old_value != border_value) {
|
||||
*old_value = border_value;
|
||||
|
||||
big_theme_image_queue_render(image);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_set_filename(BigThemeImage *image, const char *filename)
|
||||
{
|
||||
if (!filename)
|
||||
return;
|
||||
|
||||
if (g_str_has_suffix(filename, ".png") ||
|
||||
g_str_has_suffix(filename, ".PNG")) {
|
||||
|
||||
image->type = BIG_THEME_IMAGE_SURFACE;
|
||||
|
||||
image->u.surface = cairo_image_surface_create_from_png(filename);
|
||||
|
||||
if (image->u.surface == NULL) {
|
||||
g_warning("Error when loading PNG from file %s", filename);
|
||||
}
|
||||
} else if (g_str_has_suffix(filename, ".svg") ||
|
||||
g_str_has_suffix(filename, ".SVG")) {
|
||||
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
image->u.svg_handle = rsvg_handle_new_from_file(filename, &error);
|
||||
|
||||
if (image->u.svg_handle == NULL) {
|
||||
g_warning("Error when loading SVG from file %s: %s", filename,
|
||||
error?error->message:"Error not set by RSVG");
|
||||
if (error)
|
||||
g_error_free(error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
image->type = BIG_THEME_IMAGE_SVG;
|
||||
} else {
|
||||
g_warning("%s: Unsupported file type", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
big_theme_image_queue_render(image);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
create_surface_from_pixbuf(const GdkPixbuf *pixbuf)
|
||||
{
|
||||
gint width = gdk_pixbuf_get_width (pixbuf);
|
||||
gint height = gdk_pixbuf_get_height (pixbuf);
|
||||
guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
|
||||
|
||||
guchar *cairo_pixels;
|
||||
cairo_format_t format;
|
||||
cairo_surface_t *surface;
|
||||
static const cairo_user_data_key_t key;
|
||||
|
||||
int j;
|
||||
|
||||
if (n_channels == 3)
|
||||
format = CAIRO_FORMAT_RGB24;
|
||||
else
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
|
||||
cairo_pixels = g_malloc (4 * width * height);
|
||||
|
||||
surface = cairo_image_surface_create_for_data((unsigned char *)cairo_pixels,
|
||||
format,
|
||||
width, height, 4 * width);
|
||||
|
||||
cairo_surface_set_user_data(surface, &key,
|
||||
cairo_pixels, (cairo_destroy_func_t)g_free);
|
||||
|
||||
for (j = height; j; j--) {
|
||||
guchar *p = gdk_pixels;
|
||||
guchar *q = cairo_pixels;
|
||||
|
||||
if (n_channels == 3) {
|
||||
guchar *end = p + 3 * width;
|
||||
|
||||
while (p < end) {
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
q[0] = p[2];
|
||||
q[1] = p[1];
|
||||
q[2] = p[0];
|
||||
#else
|
||||
q[1] = p[0];
|
||||
q[2] = p[1];
|
||||
q[3] = p[2];
|
||||
#endif
|
||||
p += 3;
|
||||
q += 4;
|
||||
}
|
||||
} else {
|
||||
guchar *end = p + 4 * width;
|
||||
guint t1,t2,t3;
|
||||
|
||||
#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
|
||||
|
||||
while (p < end) {
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
MULT(q[0], p[2], p[3], t1);
|
||||
MULT(q[1], p[1], p[3], t2);
|
||||
MULT(q[2], p[0], p[3], t3);
|
||||
q[3] = p[3];
|
||||
#else
|
||||
q[0] = p[3];
|
||||
MULT(q[1], p[0], p[3], t1);
|
||||
MULT(q[2], p[1], p[3], t2);
|
||||
MULT(q[3], p[2], p[3], t3);
|
||||
#endif
|
||||
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
#undef MULT
|
||||
}
|
||||
|
||||
gdk_pixels += gdk_rowstride;
|
||||
cairo_pixels += 4 * width;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_set_pixbuf(BigThemeImage *image, GdkPixbuf *pixbuf)
|
||||
{
|
||||
if (!pixbuf)
|
||||
return;
|
||||
|
||||
image->type = BIG_THEME_IMAGE_SURFACE;
|
||||
|
||||
image->u.surface = create_surface_from_pixbuf(pixbuf);
|
||||
|
||||
g_assert(image->u.surface != NULL);
|
||||
|
||||
big_theme_image_queue_render(image);
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_BORDER_TOP:
|
||||
big_theme_image_set_border_value(image, &image->border_top, value);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_BOTTOM:
|
||||
big_theme_image_set_border_value(image, &image->border_bottom, value);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_LEFT:
|
||||
big_theme_image_set_border_value(image, &image->border_left, value);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_RIGHT:
|
||||
big_theme_image_set_border_value(image, &image->border_right, value);
|
||||
break;
|
||||
|
||||
case PROP_FILENAME:
|
||||
big_theme_image_set_filename(image, g_value_get_string(value));
|
||||
break;
|
||||
|
||||
case PROP_PIXBUF:
|
||||
big_theme_image_set_pixbuf(image, g_value_get_object(value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_BORDER_TOP:
|
||||
g_value_set_uint(value, image->border_top);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_BOTTOM:
|
||||
g_value_set_uint(value, image->border_bottom);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_LEFT:
|
||||
g_value_set_uint(value, image->border_left);
|
||||
break;
|
||||
|
||||
case PROP_BORDER_RIGHT:
|
||||
g_value_set_uint(value, image->border_right);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_dispose(GObject *object)
|
||||
{
|
||||
BigThemeImage *image;
|
||||
|
||||
image = BIG_THEME_IMAGE(object);
|
||||
|
||||
if (image->render_idle) {
|
||||
g_source_remove(image->render_idle);
|
||||
image->render_idle = 0;
|
||||
}
|
||||
|
||||
switch (image->type) {
|
||||
case BIG_THEME_IMAGE_SVG:
|
||||
if (image->u.svg_handle) {
|
||||
g_object_unref(image->u.svg_handle);
|
||||
image->u.svg_handle = NULL;
|
||||
}
|
||||
break;
|
||||
case BIG_THEME_IMAGE_SURFACE:
|
||||
if (image->u.surface) {
|
||||
cairo_surface_destroy(image->u.surface);
|
||||
image->u.surface = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (G_OBJECT_CLASS(big_theme_image_parent_class)->dispose)
|
||||
G_OBJECT_CLASS(big_theme_image_parent_class)->dispose(object);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
big_theme_image_class_init(BigThemeImageClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = big_theme_image_dispose;
|
||||
gobject_class->set_property = big_theme_image_set_property;
|
||||
gobject_class->get_property = big_theme_image_get_property;
|
||||
|
||||
actor_class->allocate = big_theme_image_allocate;
|
||||
actor_class->get_preferred_width = big_theme_image_get_preferred_width;
|
||||
actor_class->get_preferred_height = big_theme_image_get_preferred_height;
|
||||
actor_class->paint = big_theme_image_paint;
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BORDER_TOP,
|
||||
g_param_spec_uint("border-top",
|
||||
"Border top",
|
||||
"Top dimension of the image border "
|
||||
"(none-scaled part)",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BORDER_BOTTOM,
|
||||
g_param_spec_uint("border-bottom",
|
||||
"Border bottom",
|
||||
"Bottom dimension of the image border "
|
||||
"(none-scaled part)",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BORDER_LEFT,
|
||||
g_param_spec_uint("border-left",
|
||||
"Border left",
|
||||
"Left dimension of the image border "
|
||||
"(none-scaled part)",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BORDER_RIGHT,
|
||||
g_param_spec_uint("border-right",
|
||||
"Border right",
|
||||
"Right dimension of the image border "
|
||||
"(none-scaled part)",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_FILENAME,
|
||||
g_param_spec_string("filename",
|
||||
"Filename",
|
||||
"Name of the file",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_PIXBUF,
|
||||
g_param_spec_object("pixbuf",
|
||||
"Pixbuf",
|
||||
"Pixbuf of the image",
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
|
||||
}
|
||||
|
||||
static void
|
||||
big_theme_image_init(BigThemeImage *image)
|
||||
{
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
big_theme_image_new_from_file(const char *filename,
|
||||
guint border_top,
|
||||
guint border_bottom,
|
||||
guint border_left,
|
||||
guint border_right)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = g_object_new(BIG_TYPE_THEME_IMAGE,
|
||||
/* FIXME ClutterCairo requires creating a bogus
|
||||
* surface with nonzero size
|
||||
*/
|
||||
"surface-width", 1,
|
||||
"surface-height", 1,
|
||||
"filename", filename,
|
||||
"border-top", border_top,
|
||||
"border-bottom", border_bottom,
|
||||
"border-left", border_left,
|
||||
"border-right", border_right,
|
||||
NULL);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
big_theme_image_new_from_pixbuf(GdkPixbuf *pixbuf,
|
||||
guint border_top,
|
||||
guint border_bottom,
|
||||
guint border_left,
|
||||
guint border_right)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = g_object_new(BIG_TYPE_THEME_IMAGE,
|
||||
/* FIXME ClutterCairo requires creating a bogus
|
||||
* surface with nonzero size
|
||||
*/
|
||||
"surface-width", 1,
|
||||
"surface-height", 1,
|
||||
"pixbuf", pixbuf,
|
||||
"border-top", border_top,
|
||||
"border-bottom", border_bottom,
|
||||
"border-left", border_left,
|
||||
"border-right", border_right,
|
||||
NULL);
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
||||
/* Copyright 2008 litl, LLC. All Rights Reserved. */
|
||||
|
||||
#ifndef __BIG_THEME_IMAGE_H__
|
||||
#define __BIG_THEME_IMAGE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BIG_TYPE_THEME_IMAGE (big_theme_image_get_type ())
|
||||
#define BIG_THEME_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BIG_TYPE_THEME_IMAGE, BigThemeImage))
|
||||
#define BIG_THEME_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BIG_TYPE_THEME_IMAGE, BigThemeImageClass))
|
||||
#define BIG_IS_THEME_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BIG_TYPE_THEME_IMAGE))
|
||||
#define BIG_IS_THEME_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BIG_TYPE_THEME_IMAGE))
|
||||
#define BIG_THEME_IMAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BIG_TYPE_THEME_IMAGE, BigThemeImageClass))
|
||||
|
||||
typedef struct BigThemeImage BigThemeImage;
|
||||
typedef struct BigThemeImageClass BigThemeImageClass;
|
||||
|
||||
GType big_theme_image_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor * big_theme_image_new_from_file (const gchar *filename,
|
||||
guint border_top,
|
||||
guint border_bottom,
|
||||
guint border_left,
|
||||
guint border_right);
|
||||
|
||||
ClutterActor * big_theme_image_new_from_pixbuf (GdkPixbuf *pixbuf,
|
||||
guint border_top,
|
||||
guint border_bottom,
|
||||
guint border_left,
|
||||
guint border_right);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BIG_THEME_IMAGE_H__ */
|
18
src/gnome-shell-clock-preferences.in
Normal file
18
src/gnome-shell-clock-preferences.in
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f "$0.in" ]
|
||||
then
|
||||
scriptDir="`dirname $0`"
|
||||
uiDir="$scriptDir/../data"
|
||||
jsDir="$scriptDir/../js"
|
||||
else
|
||||
uiDir="@pkgdatadir@"
|
||||
jsDir="@pkgdatadir@/js"
|
||||
fi
|
||||
|
||||
progName="`basename $0`"
|
||||
uiFile="$uiDir/clock-preferences.ui"
|
||||
export GJS_PATH="$jsDir"
|
||||
|
||||
@GJS_CONSOLE@ -c "const ClockPreferences = imports.prefs.clockPreferences;
|
||||
ClockPreferences.main({ progName: '$progName', uiFile: '$uiFile' });"
|
@ -32,23 +32,27 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gjs/gjs.h>
|
||||
#include <girepository.h>
|
||||
#include <gmodule.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "display.h"
|
||||
|
||||
#include "shell-global-private.h"
|
||||
#include "shell-perf-log.h"
|
||||
#include "shell-wm.h"
|
||||
#include "st.h"
|
||||
|
||||
static void gnome_shell_plugin_constructed (GObject *object);
|
||||
static void gnome_shell_plugin_dispose (GObject *object);
|
||||
static void gnome_shell_plugin_finalize (GObject *object);
|
||||
|
||||
static void gnome_shell_plugin_start (MutterPlugin *plugin);
|
||||
static void gnome_shell_plugin_minimize (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void gnome_shell_plugin_maximize (MutterPlugin *plugin,
|
||||
@ -118,10 +122,10 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass);
|
||||
|
||||
gobject_class->constructed = gnome_shell_plugin_constructed;
|
||||
gobject_class->dispose = gnome_shell_plugin_dispose;
|
||||
gobject_class->finalize = gnome_shell_plugin_finalize;
|
||||
|
||||
plugin_class->start = gnome_shell_plugin_start;
|
||||
plugin_class->map = gnome_shell_plugin_map;
|
||||
plugin_class->minimize = gnome_shell_plugin_minimize;
|
||||
plugin_class->maximize = gnome_shell_plugin_maximize;
|
||||
@ -138,25 +142,23 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
|
||||
static void
|
||||
gnome_shell_plugin_init (GnomeShellPlugin *shell_plugin)
|
||||
{
|
||||
_shell_global_set_plugin (shell_global_get(), MUTTER_PLUGIN(shell_plugin));
|
||||
meta_prefs_override_preference_location ("/apps/metacity/general/button_layout",
|
||||
"/desktop/gnome/shell/windows/button_layout");
|
||||
}
|
||||
|
||||
static void
|
||||
gnome_shell_plugin_constructed (GObject *object)
|
||||
update_font_options (GtkSettings *settings)
|
||||
{
|
||||
MutterPlugin *plugin = MUTTER_PLUGIN (object);
|
||||
GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (object);
|
||||
MetaScreen *screen;
|
||||
MetaDisplay *display;
|
||||
GError *error = NULL;
|
||||
int status;
|
||||
const char *shell_js;
|
||||
char **search_path;
|
||||
StThemeContext *context;
|
||||
ClutterStage *stage;
|
||||
ClutterBackend *backend;
|
||||
cairo_font_options_t *font_options;
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
gint dpi;
|
||||
gint hinting;
|
||||
gchar *hint_style_str;
|
||||
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
gint antialias;
|
||||
cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
|
||||
cairo_font_options_t *options;
|
||||
|
||||
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
||||
* drivers and we should just be rendering text at the right
|
||||
@ -165,21 +167,145 @@ gnome_shell_plugin_constructed (GObject *object)
|
||||
*/
|
||||
clutter_set_font_flags (clutter_get_font_flags () & ~CLUTTER_FONT_MIPMAPPING);
|
||||
|
||||
g_object_get (settings,
|
||||
"gtk-xft-dpi", &dpi,
|
||||
"gtk-xft-antialias", &antialias,
|
||||
"gtk-xft-hinting", &hinting,
|
||||
"gtk-xft-hintstyle", &hint_style_str,
|
||||
NULL);
|
||||
|
||||
stage = CLUTTER_STAGE (clutter_stage_get_default ());
|
||||
context = st_theme_context_get_for_stage (stage);
|
||||
|
||||
if (dpi != -1)
|
||||
/* GTK stores resolution as 1024 * dots/inch */
|
||||
st_theme_context_set_resolution (context, dpi / 1024);
|
||||
else
|
||||
st_theme_context_set_default_resolution (context);
|
||||
|
||||
/* Clutter (as of 0.9) passes comprehensively wrong font options
|
||||
* override whatever set_font_flags() did above.
|
||||
*
|
||||
* http://bugzilla.openedhand.com/show_bug.cgi?id=1456
|
||||
*/
|
||||
backend = clutter_get_default_backend ();
|
||||
font_options = cairo_font_options_create ();
|
||||
/* Default options for everything is reasonable; except that
|
||||
* we want to turn off subpixel anti-aliasing; since Clutter
|
||||
options = cairo_font_options_create ();
|
||||
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
||||
|
||||
if (hinting >= 0 && !hinting)
|
||||
{
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
}
|
||||
else if (hint_style_str)
|
||||
{
|
||||
if (strcmp (hint_style_str, "hintnone") == 0)
|
||||
hint_style = CAIRO_HINT_STYLE_NONE;
|
||||
else if (strcmp (hint_style_str, "hintslight") == 0)
|
||||
hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||
else if (strcmp (hint_style_str, "hintmedium") == 0)
|
||||
hint_style = CAIRO_HINT_STYLE_MEDIUM;
|
||||
else if (strcmp (hint_style_str, "hintfull") == 0)
|
||||
hint_style = CAIRO_HINT_STYLE_FULL;
|
||||
}
|
||||
|
||||
g_free (hint_style_str);
|
||||
|
||||
cairo_font_options_set_hint_style (options, hint_style);
|
||||
|
||||
/* We don't want to turn on subpixel anti-aliasing; since Clutter
|
||||
* doesn't currently have the code to support ARGB masks,
|
||||
* generating them then squashing them back to A8 is pointless.
|
||||
*/
|
||||
cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
|
||||
clutter_backend_set_font_options (backend, font_options);
|
||||
cairo_font_options_destroy (font_options);
|
||||
antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
|
||||
: CAIRO_ANTIALIAS_NONE;
|
||||
|
||||
cairo_font_options_set_antialias (options, antialias_mode);
|
||||
|
||||
clutter_backend_set_font_options (backend, options);
|
||||
cairo_font_options_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_notify_cb (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
update_font_options (settings);
|
||||
}
|
||||
|
||||
static void
|
||||
malloc_statistics_callback (ShellPerfLog *perf_log,
|
||||
gpointer data)
|
||||
{
|
||||
struct mallinfo info = mallinfo ();
|
||||
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.arenaSize",
|
||||
info.arena);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.mmapSize",
|
||||
info.hblkhd);
|
||||
shell_perf_log_update_statistic_i (perf_log,
|
||||
"malloc.usedSize",
|
||||
info.uordblks);
|
||||
}
|
||||
|
||||
static void
|
||||
add_statistics (GnomeShellPlugin *shell_plugin)
|
||||
{
|
||||
ShellPerfLog *perf_log = shell_perf_log_get_default ();
|
||||
|
||||
/* For probably historical reasons, mallinfo() defines the returned values,
|
||||
* even those in bytes as int, not size_t. We're determined not to use
|
||||
* more than 2G of malloc'ed memory, so are OK with that.
|
||||
*/
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.arenaSize",
|
||||
"Amount of memory allocated by malloc() with brk(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.mmapSize",
|
||||
"Amount of memory allocated by malloc() with mmap(), in bytes",
|
||||
"i");
|
||||
shell_perf_log_define_statistic (perf_log,
|
||||
"malloc.usedSize",
|
||||
"Amount of malloc'ed memory currently in use",
|
||||
"i");
|
||||
|
||||
shell_perf_log_add_statistics_callback (perf_log,
|
||||
malloc_statistics_callback,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gnome_shell_plugin_start (MutterPlugin *plugin)
|
||||
{
|
||||
GnomeShellPlugin *shell_plugin = GNOME_SHELL_PLUGIN (plugin);
|
||||
MetaScreen *screen;
|
||||
MetaDisplay *display;
|
||||
GtkSettings *settings;
|
||||
GError *error = NULL;
|
||||
int status;
|
||||
const char *shell_js;
|
||||
char **search_path;
|
||||
ShellGlobal *global;
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
g_object_connect (settings,
|
||||
"signal::notify::gtk-xft-dpi",
|
||||
G_CALLBACK (settings_notify_cb), NULL,
|
||||
"signal::notify::gtk-xft-antialias",
|
||||
G_CALLBACK (settings_notify_cb), NULL,
|
||||
"signal::notify::gtk-xft-hinting",
|
||||
G_CALLBACK (settings_notify_cb), NULL,
|
||||
"signal::notify::gtk-xft-hintstyle",
|
||||
G_CALLBACK (settings_notify_cb), NULL,
|
||||
NULL);
|
||||
update_font_options (settings);
|
||||
|
||||
screen = mutter_plugin_get_screen (plugin);
|
||||
display = meta_screen_get_display (screen);
|
||||
@ -194,7 +320,13 @@ gnome_shell_plugin_constructed (GObject *object)
|
||||
shell_plugin->gjs_context = gjs_context_new_with_search_path(search_path);
|
||||
g_strfreev(search_path);
|
||||
|
||||
_shell_global_set_gjs_context (shell_global_get (), shell_plugin->gjs_context);
|
||||
/* Initialize the global object here. */
|
||||
global = shell_global_get ();
|
||||
|
||||
_shell_global_set_plugin (global, MUTTER_PLUGIN(shell_plugin));
|
||||
_shell_global_set_gjs_context (global, shell_plugin->gjs_context);
|
||||
|
||||
add_statistics (shell_plugin);
|
||||
|
||||
if (!gjs_context_eval (shell_plugin->gjs_context,
|
||||
"const Main = imports.ui.main; Main.start();",
|
||||
|
@ -1,6 +1,15 @@
|
||||
#!@PYTHON@
|
||||
# -*- mode: Python; indent-tabs-mode: nil; -*-
|
||||
|
||||
import atexit
|
||||
import datetime
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
json = None
|
||||
import optparse
|
||||
import os
|
||||
import random
|
||||
@ -37,10 +46,15 @@ def get_running_session_environs():
|
||||
if not stat.st_uid == myuid:
|
||||
continue
|
||||
try:
|
||||
exe = os.readlink(piddir + '/exe')
|
||||
except OSError, e:
|
||||
f = open(piddir + "/cmdline")
|
||||
command = f.read()
|
||||
f.close()
|
||||
except IOError, e:
|
||||
continue
|
||||
if os.path.basename(exe) != 'gnome-session':
|
||||
# /proc/cmdline is separated and terminated by NULs
|
||||
command = command.split("\x00")[0]
|
||||
command = os.path.basename(command)
|
||||
if command != 'gnome-session':
|
||||
continue
|
||||
try:
|
||||
f = open(os.path.join(piddir, 'environ'))
|
||||
@ -124,7 +138,7 @@ def _get_glx_extensions():
|
||||
|
||||
return (server_glx_extensions, client_glx_extensions, glx_extensions)
|
||||
|
||||
def start_shell():
|
||||
def start_shell(perf_output=None):
|
||||
bin_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(bin_dir, 'gnome-shell.in')):
|
||||
running_from_source_tree = True
|
||||
@ -192,6 +206,12 @@ def start_shell():
|
||||
# need to force indirect rendering for NVIDIA.
|
||||
env['LIBGL_ALWAYS_INDIRECT'] = '1'
|
||||
|
||||
if options.perf is not None:
|
||||
env['SHELL_PERF_MODULE'] = options.perf
|
||||
|
||||
if perf_output is not None:
|
||||
env['SHELL_PERF_OUTPUT'] = perf_output
|
||||
|
||||
if options.debug:
|
||||
debug_command = options.debug_command.split()
|
||||
args = list(debug_command)
|
||||
@ -205,6 +225,258 @@ def start_shell():
|
||||
args.append('--sync')
|
||||
return subprocess.Popen(args, env=env)
|
||||
|
||||
def run_shell(perf_output=None):
|
||||
if options.debug:
|
||||
# Record initial terminal state so we can reset it to that
|
||||
# later, in case we kill gdb at a bad time
|
||||
termattrs = termios.tcgetattr(0);
|
||||
|
||||
normal_exit = False
|
||||
|
||||
if options.verbose:
|
||||
print "Starting shell"
|
||||
|
||||
try:
|
||||
shell = None
|
||||
if options.xephyr:
|
||||
xephyr = start_xephyr()
|
||||
# This makes us not grab the org.gnome.Panel or
|
||||
# org.freedesktop.Notifications D-Bus names
|
||||
os.environ['GNOME_SHELL_NO_REPLACE'] = '1'
|
||||
shell = start_shell()
|
||||
else:
|
||||
xephyr = None
|
||||
shell = start_shell(perf_output=perf_output)
|
||||
|
||||
# Wait for shell to exit
|
||||
if options.verbose:
|
||||
print "Waiting for shell to exit"
|
||||
shell.wait()
|
||||
|
||||
except KeyboardInterrupt, e:
|
||||
try:
|
||||
os.kill(shell.pid, signal.SIGKILL)
|
||||
except:
|
||||
pass
|
||||
shell.wait()
|
||||
finally:
|
||||
# Clean up Xephyr if it outlived the shell
|
||||
if xephyr:
|
||||
try:
|
||||
os.kill(xephyr.pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if shell is None:
|
||||
print "Failed to start shell"
|
||||
elif shell.returncode == 0:
|
||||
normal_exit = True
|
||||
if options.verbose:
|
||||
print "Shell exited normally"
|
||||
elif shell.returncode < 0:
|
||||
# Python has no mapping for strsignal; not worth using
|
||||
# ctypes for this.
|
||||
print "Shell killed with signal %d" % - shell.returncode
|
||||
else:
|
||||
# Normal reason here would be losing connection the X server
|
||||
if options.verbose:
|
||||
print "Shell exited with return code %d" % shell.returncode
|
||||
|
||||
if options.debug:
|
||||
termios.tcsetattr(0, termios.TCSANOW, termattrs);
|
||||
|
||||
return normal_exit
|
||||
|
||||
def upload_performance_report(report_text):
|
||||
# Local imports to avoid impacting gnome-shell startup time
|
||||
import base64
|
||||
from ConfigParser import RawConfigParser
|
||||
import hashlib
|
||||
import hmac
|
||||
import httplib
|
||||
import urlparse
|
||||
import urllib
|
||||
|
||||
try:
|
||||
config_home = os.environ['XDG_CONFIG_HOME']
|
||||
except KeyError:
|
||||
config_home = None
|
||||
|
||||
if not config_home:
|
||||
config_home = os.path.expanduser("~/.config")
|
||||
|
||||
config_file = os.path.join(config_home, "gnome-shell/perf.ini")
|
||||
|
||||
try:
|
||||
config = RawConfigParser()
|
||||
f = open(config_file)
|
||||
config.readfp(f)
|
||||
f.close()
|
||||
|
||||
base_url = config.get('upload', 'url')
|
||||
system_name = config.get('upload', 'name')
|
||||
secret_key = config.get('upload', 'key')
|
||||
except Exception, e:
|
||||
print "Can't read upload configuration from %s: %s" % (config_file, str(e))
|
||||
sys.exit(1)
|
||||
|
||||
# Determine host, port and upload URL from provided data, we're
|
||||
# a bit extra-careful about normalization since the URL is part
|
||||
# of the signature.
|
||||
|
||||
split = urlparse.urlsplit(base_url)
|
||||
scheme = split[0].lower()
|
||||
netloc = split[1]
|
||||
base_path = split[2]
|
||||
|
||||
m = re.match(r'^(.*?)(?::(\d+))?$', netloc)
|
||||
if m.group(2):
|
||||
host, port = m.group(1), int(m.group(2))
|
||||
else:
|
||||
host, port = m.group(1), None
|
||||
|
||||
if scheme != "http":
|
||||
print "'%s' is not a HTTP URL" % base_url
|
||||
sys.exit(1)
|
||||
|
||||
if port is None:
|
||||
port = 80
|
||||
|
||||
if base_path.endswith('/'):
|
||||
base_path = base_path[:-1]
|
||||
|
||||
if port == 80:
|
||||
normalized_base = "%s://%s%s" % (scheme, host, base_path)
|
||||
else:
|
||||
normalized_base = "%s://%s:%d%s" % (scheme, host, port, base_path)
|
||||
|
||||
upload_url = normalized_base + '/system/%s/upload' % system_name
|
||||
upload_path = urlparse.urlsplit(upload_url)[2] # path portion
|
||||
|
||||
# Create signature based on upload URL and the report data
|
||||
|
||||
signature_data = 'POST&' + upload_url + "&&"
|
||||
h = hmac.new(secret_key, digestmod=hashlib.sha1)
|
||||
h.update(signature_data)
|
||||
h.update(report_text)
|
||||
signature = urllib.quote(base64.b64encode(h.digest()), "~")
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'gnome-shell',
|
||||
'Content-Type': 'application/json',
|
||||
'X-Shell-Signature': 'HMAC-SHA1 ' + signature
|
||||
};
|
||||
|
||||
connection = httplib.HTTPConnection(host, port)
|
||||
connection.request('POST', upload_path, report_text, headers)
|
||||
response = connection.getresponse()
|
||||
|
||||
if response.status == 200:
|
||||
print "Performance report upload succeeded"
|
||||
else:
|
||||
print "Performance report upload failed with status %d" % response.status
|
||||
print response.read()
|
||||
|
||||
def run_performance_test():
|
||||
iters = options.perf_iters
|
||||
if options.perf_warmup:
|
||||
iters += 1
|
||||
|
||||
logs = []
|
||||
metric_summaries = {}
|
||||
|
||||
for i in xrange(0, iters):
|
||||
# We create an empty temporary file that the shell will overwrite
|
||||
# with the contents.
|
||||
handle, output_file = tempfile.mkstemp(".json", "gnome-shell-perf.")
|
||||
os.close(handle)
|
||||
|
||||
# Run the performance test and collect the output as JSON
|
||||
normal_exit = False
|
||||
try:
|
||||
normal_exit = run_shell(perf_output=output_file)
|
||||
finally:
|
||||
if not normal_exit:
|
||||
os.remove(output_file)
|
||||
|
||||
if not normal_exit:
|
||||
return False
|
||||
|
||||
try:
|
||||
f = open(output_file)
|
||||
output = json.load(f)
|
||||
f.close()
|
||||
finally:
|
||||
os.remove(output_file)
|
||||
|
||||
# Grab the event definitions and monitor layout the first time around
|
||||
if i == 0:
|
||||
events = output['events']
|
||||
monitors = output['monitors']
|
||||
|
||||
if options.perf_warmup and i == 0:
|
||||
continue
|
||||
|
||||
for metric in output['metrics']:
|
||||
name = metric['name']
|
||||
if not name in metric_summaries:
|
||||
summary = {}
|
||||
summary['description'] = metric['description']
|
||||
summary['units'] = metric['units']
|
||||
summary['values'] = []
|
||||
metric_summaries[name] = summary
|
||||
else:
|
||||
summary = metric_summaries[name]
|
||||
|
||||
summary['values'].append(metric['value'])
|
||||
|
||||
logs.append(output['log'])
|
||||
|
||||
if options.perf_output or options.perf_upload:
|
||||
# Write a complete report, formatted as JSON. The Javascript/C code that
|
||||
# generates the individual reports we are summarizing here is very careful
|
||||
# to format them nicely, but we just dump out a compressed no-whitespace
|
||||
# version here for simplicity. Using json.dump(indent=0) doesn't real
|
||||
# improve the readability of the output much.
|
||||
report = {
|
||||
'date': datetime.datetime.now().isoformat(),
|
||||
'events': events,
|
||||
'monitors': monitors,
|
||||
'metrics': metric_summaries,
|
||||
'logs': logs
|
||||
}
|
||||
|
||||
# Add the Git revision if available
|
||||
bin_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
||||
if os.path.exists(os.path.join(bin_dir, 'gnome-shell.in')):
|
||||
top_dir = os.path.dirname(bin_dir)
|
||||
git_dir = os.path.join(top_dir, '.git')
|
||||
if os.path.exists(git_dir):
|
||||
env = dict(os.environ)
|
||||
env['GIT_DIR'] = git_dir
|
||||
revision = subprocess.Popen(['git', 'rev-parse', 'HEAD'],
|
||||
env=env,
|
||||
stdout=subprocess.PIPE).communicate()[0].strip()
|
||||
report['revision'] = revision
|
||||
|
||||
if options.perf_output:
|
||||
f = open(options.perf_output, 'w')
|
||||
json.dump(report, f)
|
||||
f.close()
|
||||
|
||||
if options.perf_upload:
|
||||
upload_performance_report(json.dumps(report))
|
||||
else:
|
||||
# Write a human readable summary
|
||||
print '------------------------------------------------------------';
|
||||
for metric in sorted(metric_summaries.keys()):
|
||||
summary = metric_summaries[metric]
|
||||
print "#", summary['description']
|
||||
print metric, ", ".join((str(x) for x in summary['values']))
|
||||
print '------------------------------------------------------------';
|
||||
|
||||
return True
|
||||
|
||||
def restore_gnome():
|
||||
# Do imports lazily to save time and memory
|
||||
import gio
|
||||
@ -251,6 +523,17 @@ parser.add_option("", "--debug-command", metavar="COMMAND",
|
||||
help="Command to use for debugging (defaults to 'gdb --args')")
|
||||
parser.add_option("-v", "--verbose", action="store_true")
|
||||
parser.add_option("", "--sync", action="store_true")
|
||||
parser.add_option("", "--perf", metavar="PERF_MODULE",
|
||||
help="Specify the name of a performance module to run")
|
||||
parser.add_option("", "--perf-iters", type="int", metavar="ITERS",
|
||||
help="Numbers of iterations of performance module to run",
|
||||
default=1)
|
||||
parser.add_option("", "--perf-warmup", action="store_true",
|
||||
help="Run a dry run before performance tests")
|
||||
parser.add_option("", "--perf-output", metavar="OUTPUT_FILE",
|
||||
help="Output file to write performance report")
|
||||
parser.add_option("", "--perf-upload", action="store_true",
|
||||
help="Upload performance report to server")
|
||||
parser.add_option("", "--xephyr", action="store_true",
|
||||
help="Run a debugging instance inside Xephyr")
|
||||
parser.add_option("", "--geometry", metavar="GEOMETRY",
|
||||
@ -271,9 +554,15 @@ if args:
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
if options.create_extension:
|
||||
import json
|
||||
if options.create_extension and json is None:
|
||||
print 'The Python simplejson module is required to create a new GNOME Shell extension'
|
||||
sys.exit(1)
|
||||
|
||||
if options.perf and json is None:
|
||||
print 'The Python simplejson module is required for performance tests'
|
||||
sys.exit(1)
|
||||
|
||||
if options.create_extension:
|
||||
print
|
||||
print '''Name should be a very short (ideally descriptive) string.
|
||||
Examples are: "Click To Focus", "Adblock", "Shell Window Shrinker".
|
||||
@ -301,7 +590,7 @@ use an extension title clicktofocus@janedoe.example.com.'''
|
||||
if uuid == '':
|
||||
uuid = sample_uuid
|
||||
|
||||
extension_path = os.path.join(os.path.expanduser('~/.config'), 'gnome-shell', 'extensions', uuid)
|
||||
extension_path = os.path.join(os.path.expanduser('~/.local'), 'share', 'gnome-shell', 'extensions', uuid)
|
||||
if os.path.exists(extension_path):
|
||||
print "Extension path %r already exists" % (extension_path, )
|
||||
sys.exit(0)
|
||||
@ -356,6 +645,11 @@ function main() {
|
||||
subprocess.Popen(['gnome-open', extensionjs_path])
|
||||
sys.exit(0)
|
||||
|
||||
# Handle ssh logins
|
||||
if 'DISPLAY' not in os.environ:
|
||||
running_env = get_running_session_environs()
|
||||
os.environ.update(running_env)
|
||||
|
||||
if options.eval_file:
|
||||
import dbus
|
||||
|
||||
@ -390,73 +684,16 @@ else:
|
||||
# tfp does not work correctly in Xephyr
|
||||
use_tfp = not options.xephyr
|
||||
|
||||
if options.verbose:
|
||||
print "Starting shell"
|
||||
|
||||
|
||||
# Handle ssh logins
|
||||
if 'DISPLAY' not in os.environ:
|
||||
running_env = get_running_session_environs()
|
||||
os.environ.update(running_env)
|
||||
|
||||
if options.debug:
|
||||
# Record initial terminal state so we can reset it to that
|
||||
# later, in case we kill gdb at a bad time
|
||||
termattrs = termios.tcgetattr(0);
|
||||
|
||||
# We only respawn the previous environment on abnormal exit;
|
||||
# for a clean exit, we assume that gnome-shell was replaced with
|
||||
# something else.
|
||||
normal_exit = False
|
||||
|
||||
try:
|
||||
shell = None
|
||||
if options.xephyr:
|
||||
xephyr = start_xephyr()
|
||||
# This makes us not grab the org.gnome.Panel or
|
||||
# org.freedesktop.Notifications D-Bus names
|
||||
os.environ['GNOME_SHELL_NO_REPLACE'] = '1'
|
||||
shell = start_shell()
|
||||
if options.perf:
|
||||
normal_exit = run_performance_test()
|
||||
else:
|
||||
xephyr = None
|
||||
shell = start_shell()
|
||||
|
||||
# Wait for shell to exit
|
||||
if options.verbose:
|
||||
print "Waiting for shell to exit"
|
||||
shell.wait()
|
||||
|
||||
except KeyboardInterrupt, e:
|
||||
try:
|
||||
os.kill(shell.pid, signal.SIGKILL)
|
||||
except:
|
||||
pass
|
||||
shell.wait()
|
||||
normal_exit = run_shell()
|
||||
finally:
|
||||
# Clean up Xephyr if it outlived the shell
|
||||
if xephyr:
|
||||
try:
|
||||
os.kill(xephyr.pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if shell is None:
|
||||
print "Failed to start shell"
|
||||
elif shell.returncode == 0:
|
||||
normal_exit = True
|
||||
if options.verbose:
|
||||
print "Shell exited normally"
|
||||
elif shell.returncode < 0:
|
||||
# Python has no mapping for strsignal; not worth using
|
||||
# ctypes for this.
|
||||
print "Shell killed with signal %d" % - shell.returncode
|
||||
else:
|
||||
# Normal reason here would be losing connection the X server
|
||||
if options.verbose:
|
||||
print "Shell exited with return code %d" % shell.returncode
|
||||
|
||||
if options.debug:
|
||||
termios.tcsetattr(0, termios.TCSANOW, termattrs);
|
||||
|
||||
if not options.xephyr and options.replace and not normal_exit:
|
||||
if not options.xephyr and options.replace and (options.perf or not normal_exit):
|
||||
restore_gnome()
|
||||
|
19
src/gtk-compat.h
Normal file
19
src/gtk-compat.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __GTK_COMPAT_H__
|
||||
#define __GTK_COMPAT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Provide a compatibility layer for accessor functions introduced
|
||||
* in GTK+ 2.20 which we need to build with GSEAL_ENABLE.
|
||||
* That way it is still possible to build with GTK+ 2.18 when not
|
||||
* using GSEAL_ENABLE
|
||||
*/
|
||||
|
||||
#if !GTK_CHECK_VERSION(2, 20, 0)
|
||||
|
||||
#define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED (w)
|
||||
#define gtk_widget_get_mapped(w) GTK_WIDGET_MAPPED (w)
|
||||
|
||||
#endif /* GTK_CHECK_VERSION(2, 20, 0) */
|
||||
|
||||
#endif /* __GTK_COMPAT_H__ */
|
@ -13,6 +13,8 @@ ShellApp* _shell_app_new_for_window (MetaWindow *window);
|
||||
|
||||
ShellApp* _shell_app_new (ShellAppInfo *appinfo);
|
||||
|
||||
void _shell_app_set_starting (ShellApp *app, gboolean starting);
|
||||
|
||||
void _shell_app_add_window (ShellApp *app, MetaWindow *window);
|
||||
|
||||
void _shell_app_remove_window (ShellApp *app, MetaWindow *window);
|
||||
|
@ -27,7 +27,8 @@
|
||||
*/
|
||||
static const char*const known_vendor_prefixes[] = { "gnome",
|
||||
"fedora",
|
||||
"mozilla" };
|
||||
"mozilla",
|
||||
NULL };
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -308,9 +309,15 @@ reread_entries (ShellAppSystem *self,
|
||||
g_slist_free (*cache);
|
||||
*cache = NULL;
|
||||
|
||||
*cache = gather_entries_recurse (self, *cache, unique, trunk);
|
||||
|
||||
gmenu_tree_item_unref (trunk);
|
||||
if (!trunk)
|
||||
{
|
||||
*cache = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*cache = gather_entries_recurse (self, *cache, unique, trunk);
|
||||
gmenu_tree_item_unref (trunk);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -484,6 +491,49 @@ shell_app_system_get_app (ShellAppSystem *self,
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_get_app_for_path:
|
||||
* @system: a #ShellAppSystem
|
||||
* @desktop_path: (utf8): UTF-8 encoded absolute file name
|
||||
*
|
||||
* Find or create a #ShellApp corresponding to a given absolute
|
||||
* file name which must be in the standard paths (XDG_DATA_DIRS).
|
||||
* For files outside the datadirs, this function returns %NULL.
|
||||
*
|
||||
* If already cached elsewhere in memory, return that instance.
|
||||
* Otherwise, create a new one.
|
||||
*
|
||||
* Return value: (transfer full): The #ShellApp for id, or %NULL if none
|
||||
*/
|
||||
ShellApp *
|
||||
shell_app_system_get_app_for_path (ShellAppSystem *system,
|
||||
const char *desktop_path)
|
||||
{
|
||||
const char *basename;
|
||||
ShellAppInfo *info;
|
||||
|
||||
basename = g_strrstr (desktop_path, "/");
|
||||
if (basename)
|
||||
basename += 1;
|
||||
else
|
||||
basename = desktop_path;
|
||||
|
||||
info = g_hash_table_lookup (system->priv->app_id_to_info, basename);
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
|
||||
{
|
||||
const char *full_path = gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*) info->entry);
|
||||
if (strcmp (desktop_path, full_path) != 0)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
return shell_app_system_get_app (system, basename);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_get_app_for_window:
|
||||
* @self: A #ShellAppSystem
|
||||
@ -1181,10 +1231,16 @@ shell_app_info_launch_full (ShellAppInfo *info,
|
||||
meta_window_activate (info->window, timestamp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
filename = shell_app_info_get_desktop_file_path (info);
|
||||
gapp = g_desktop_app_info_new_from_filename (filename);
|
||||
g_free (filename);
|
||||
else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
|
||||
{
|
||||
gapp = g_desktop_app_info_new (shell_app_info_get_id (info));
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = shell_app_info_get_desktop_file_path (info);
|
||||
gapp = g_desktop_app_info_new_from_filename (filename);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
if (!gapp)
|
||||
{
|
||||
@ -1199,11 +1255,6 @@ shell_app_info_launch_full (ShellAppInfo *info,
|
||||
if (timestamp == 0)
|
||||
timestamp = clutter_get_current_event_time ();
|
||||
|
||||
/* Shell design calls for on application launch, no window is focused,
|
||||
* and we have startup notification displayed.
|
||||
*/
|
||||
meta_display_focus_the_no_focus_window (display, screen, timestamp);
|
||||
|
||||
if (workspace < 0)
|
||||
workspace = meta_screen_get_active_workspace_index (screen);
|
||||
|
||||
|
@ -70,6 +70,7 @@ gboolean shell_app_info_launch (ShellAppInfo *info,
|
||||
ShellAppInfo *shell_app_system_load_from_desktop_file (ShellAppSystem *system, const char *filename, GError **error);
|
||||
|
||||
ShellApp *shell_app_system_get_app (ShellAppSystem *system, const char *id);
|
||||
ShellApp *shell_app_system_get_app_for_path (ShellAppSystem *system, const char *desktop_path);
|
||||
ShellApp *shell_app_system_get_app_for_window (ShellAppSystem *self, MetaWindow *window);
|
||||
|
||||
void _shell_app_system_register_app (ShellAppSystem *self, ShellApp *app);
|
||||
|
@ -381,7 +381,7 @@ on_session_status_changed (DBusGProxy *proxy,
|
||||
static void
|
||||
shell_app_usage_init (ShellAppUsage *self)
|
||||
{
|
||||
char *shell_config_dir, *path;
|
||||
char *shell_userdata_dir, *path;
|
||||
DBusGConnection *session_bus;
|
||||
ShellWindowTracker *tracker;
|
||||
|
||||
@ -404,9 +404,9 @@ shell_app_usage_init (ShellAppUsage *self)
|
||||
self->currently_idle = FALSE;
|
||||
self->enable_monitoring = FALSE;
|
||||
|
||||
g_object_get (shell_global_get(), "configdir", &shell_config_dir, NULL),
|
||||
path = g_build_filename (shell_config_dir, DATA_FILENAME, NULL);
|
||||
g_free (shell_config_dir);
|
||||
g_object_get (shell_global_get(), "userdatadir", &shell_userdata_dir, NULL),
|
||||
path = g_build_filename (shell_userdata_dir, DATA_FILENAME, NULL);
|
||||
g_free (shell_userdata_dir);
|
||||
self->configfile = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
restore_from_file (self);
|
||||
|
334
src/shell-app.c
334
src/shell-app.c
@ -2,9 +2,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "st.h"
|
||||
#include "shell-app-private.h"
|
||||
#include "shell-global.h"
|
||||
#include "shell-enum-types.h"
|
||||
#include "display.h"
|
||||
#include "st.h"
|
||||
#include "shell-window-tracker.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@ -21,15 +25,23 @@ struct _ShellApp
|
||||
|
||||
ShellAppInfo *info;
|
||||
|
||||
guint32 last_user_time;
|
||||
|
||||
guint workspace_switch_id;
|
||||
|
||||
gboolean window_sort_stale;
|
||||
GSList *windows;
|
||||
|
||||
ShellAppState state;
|
||||
gboolean window_sort_stale : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_STATE
|
||||
};
|
||||
|
||||
enum {
|
||||
WINDOWS_CHANGED,
|
||||
LAST_SIGNAL
|
||||
@ -37,6 +49,25 @@ enum {
|
||||
|
||||
static guint shell_app_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
shell_app_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellApp *app = SHELL_APP (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STATE:
|
||||
g_value_set_enum (value, app->state);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
shell_app_get_id (ShellApp *app)
|
||||
{
|
||||
@ -219,11 +250,201 @@ shell_app_is_transient (ShellApp *app)
|
||||
return shell_app_info_is_transient (app->info);
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_app_launch (ShellApp *self,
|
||||
GError **error)
|
||||
typedef struct {
|
||||
MetaWorkspace *workspace;
|
||||
GSList **transients;
|
||||
} CollectTransientsData;
|
||||
|
||||
static gboolean
|
||||
collect_transients_on_workspace (MetaWindow *window,
|
||||
gpointer datap)
|
||||
{
|
||||
return shell_app_info_launch (self->info, error);
|
||||
CollectTransientsData *data = datap;
|
||||
|
||||
if (data->workspace && meta_window_get_workspace (window) != data->workspace)
|
||||
return TRUE;
|
||||
|
||||
*data->transients = g_slist_prepend (*data->transients, window);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The basic idea here is that when we're targeting a window,
|
||||
* if it has transients we want to pick the most recent one
|
||||
* the user interacted with.
|
||||
* This function makes raising GEdit with the file chooser
|
||||
* open work correctly.
|
||||
*/
|
||||
static MetaWindow *
|
||||
find_most_recent_transient_on_same_workspace (MetaDisplay *display,
|
||||
MetaWindow *reference)
|
||||
{
|
||||
GSList *transients, *transients_sorted, *iter;
|
||||
MetaWindow *result;
|
||||
CollectTransientsData data;
|
||||
|
||||
transients = NULL;
|
||||
data.workspace = meta_window_get_workspace (reference);
|
||||
data.transients = &transients;
|
||||
|
||||
meta_window_foreach_transient (reference, collect_transients_on_workspace, &data);
|
||||
|
||||
transients_sorted = meta_display_sort_windows_by_stacking (display, transients);
|
||||
/* Reverse this so we're top-to-bottom (yes, we should probably change the order
|
||||
* returned from the sort_windows_by_stacking function)
|
||||
*/
|
||||
transients_sorted = g_slist_reverse (transients_sorted);
|
||||
g_slist_free (transients);
|
||||
transients = NULL;
|
||||
|
||||
result = NULL;
|
||||
for (iter = transients_sorted; iter; iter = iter->next)
|
||||
{
|
||||
MetaWindow *window = iter->data;
|
||||
MetaWindowType wintype = meta_window_get_window_type (window);
|
||||
|
||||
/* Don't want to focus UTILITY types, like the Gimp toolbars */
|
||||
if (wintype == META_WINDOW_NORMAL ||
|
||||
wintype == META_WINDOW_DIALOG)
|
||||
{
|
||||
result = window;
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_slist_free (transients_sorted);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_activate_window:
|
||||
* @app: a #ShellApp
|
||||
* @window: (allow-none): Window to be focused
|
||||
* @timestamp: Event timestamp
|
||||
*
|
||||
* Bring all windows for the given app to the foreground,
|
||||
* but ensure that @window is on top. If @window is %NULL,
|
||||
* the window with the most recent user time for the app
|
||||
* will be used.
|
||||
*
|
||||
* This function has no effect if @app is not currently running.
|
||||
*/
|
||||
void
|
||||
shell_app_activate_window (ShellApp *app,
|
||||
MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GSList *windows;
|
||||
|
||||
if (shell_app_get_state (app) != SHELL_APP_STATE_RUNNING)
|
||||
return;
|
||||
|
||||
windows = shell_app_get_windows (app);
|
||||
if (window == NULL && windows)
|
||||
window = windows->data;
|
||||
|
||||
if (!g_slist_find (windows, window))
|
||||
return;
|
||||
else
|
||||
{
|
||||
GSList *iter;
|
||||
ShellGlobal *global = shell_global_get ();
|
||||
MetaScreen *screen = shell_global_get_screen (global);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaWorkspace *active = meta_screen_get_active_workspace (screen);
|
||||
MetaWorkspace *workspace = meta_window_get_workspace (window);
|
||||
guint32 last_user_timestamp = meta_display_get_last_user_time (display);
|
||||
MetaWindow *most_recent_transient;
|
||||
|
||||
if (meta_display_xserver_time_is_before (display, timestamp, last_user_timestamp))
|
||||
{
|
||||
meta_window_set_demands_attention (window);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now raise all the other windows for the app that are on
|
||||
* the same workspace, in reverse order to preserve the stacking.
|
||||
*/
|
||||
for (iter = windows; iter; iter = iter->next)
|
||||
{
|
||||
MetaWindow *other_window = iter->data;
|
||||
|
||||
if (other_window != window)
|
||||
meta_window_raise (other_window);
|
||||
}
|
||||
|
||||
/* If we have a transient that the user's interacted with more recently than
|
||||
* the window, pick that.
|
||||
*/
|
||||
most_recent_transient = find_most_recent_transient_on_same_workspace (display, window);
|
||||
if (most_recent_transient
|
||||
&& meta_display_xserver_time_is_before (display,
|
||||
meta_window_get_user_time (window),
|
||||
meta_window_get_user_time (most_recent_transient)))
|
||||
window = most_recent_transient;
|
||||
|
||||
if (active != workspace)
|
||||
meta_workspace_activate_with_focus (workspace, window, timestamp);
|
||||
else
|
||||
meta_window_activate (window, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_activate:
|
||||
* @app: a #ShellApp
|
||||
*
|
||||
* Perform an appropriate default action for operating on this application,
|
||||
* dependent on its current state. For example, if the application is not
|
||||
* currently running, launch it. If it is running, activate the most
|
||||
* recently used NORMAL window (or if that window has a transient, the most
|
||||
* recently used transient for that window).
|
||||
*/
|
||||
void
|
||||
shell_app_activate (ShellApp *app)
|
||||
{
|
||||
switch (app->state)
|
||||
{
|
||||
case SHELL_APP_STATE_STOPPED:
|
||||
/* TODO sensibly handle this error */
|
||||
shell_app_info_launch (app->info, NULL);
|
||||
break;
|
||||
case SHELL_APP_STATE_STARTING:
|
||||
break;
|
||||
case SHELL_APP_STATE_RUNNING:
|
||||
shell_app_activate_window (app, NULL, shell_global_get_current_time (shell_global_get ()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_open_new_window:
|
||||
* @app: a #ShellApp
|
||||
*
|
||||
* Request that the application create a new window.
|
||||
*/
|
||||
void
|
||||
shell_app_open_new_window (ShellApp *app)
|
||||
{
|
||||
/* Here we just always launch the application again, even if we know
|
||||
* it was already running. For most applications this
|
||||
* should have the effect of creating a new window, whether that's
|
||||
* a second process (in the case of Calculator) or IPC to existing
|
||||
* instance (Firefox). There are a few less-sensical cases such
|
||||
* as say Pidgin. Ideally, we have the application express to us
|
||||
* that it supports an explicit new-window action.
|
||||
*/
|
||||
shell_app_info_launch (app->info, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_get_state:
|
||||
* @app: a #ShellApp
|
||||
*
|
||||
* Returns: State of the application
|
||||
*/
|
||||
ShellAppState
|
||||
shell_app_get_state (ShellApp *app)
|
||||
{
|
||||
return app->state;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,10 +562,9 @@ shell_app_is_on_workspace (ShellApp *app,
|
||||
* @other: A #ShellApp
|
||||
*
|
||||
* Compare one #ShellApp instance to another, in the following way:
|
||||
* - Running applications sort before not-running applications.
|
||||
* - If one of them has visible windows and the other does not, the one
|
||||
* with visible windows is first.
|
||||
* - If one has no windows at all (i.e. it's not running) and the other
|
||||
* does, the one with windows is first.
|
||||
* - Finally, the application which the user interacted with most recently
|
||||
* compares earlier.
|
||||
*/
|
||||
@ -353,7 +573,13 @@ shell_app_compare (ShellApp *app,
|
||||
ShellApp *other)
|
||||
{
|
||||
gboolean vis_app, vis_other;
|
||||
GSList *windows_app, *windows_other;
|
||||
|
||||
if (app->state != other->state)
|
||||
{
|
||||
if (app->state == SHELL_APP_STATE_RUNNING)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
vis_app = shell_app_has_visible_windows (app);
|
||||
vis_other = shell_app_has_visible_windows (other);
|
||||
@ -368,10 +594,7 @@ shell_app_compare (ShellApp *app,
|
||||
else if (!app->windows && other->windows)
|
||||
return 1;
|
||||
|
||||
windows_app = shell_app_get_windows (app);
|
||||
windows_other = shell_app_get_windows (other);
|
||||
|
||||
return meta_window_get_user_time (windows_other->data) - meta_window_get_user_time (windows_app->data);
|
||||
return other->last_user_time - app->last_user_time;
|
||||
}
|
||||
|
||||
ShellApp *
|
||||
@ -399,6 +622,18 @@ _shell_app_new (ShellAppInfo *info)
|
||||
return app;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_state_transition (ShellApp *app,
|
||||
ShellAppState state)
|
||||
{
|
||||
if (app->state == state)
|
||||
return;
|
||||
g_return_if_fail (!(app->state == SHELL_APP_STATE_RUNNING &&
|
||||
state == SHELL_APP_STATE_STARTING));
|
||||
app->state = state;
|
||||
g_object_notify (G_OBJECT (app), "state");
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_on_unmanaged (MetaWindow *window,
|
||||
ShellApp *app)
|
||||
@ -411,6 +646,8 @@ shell_app_on_user_time_changed (MetaWindow *window,
|
||||
GParamSpec *pspec,
|
||||
ShellApp *app)
|
||||
{
|
||||
app->last_user_time = meta_window_get_user_time (window);
|
||||
|
||||
/* Ideally we don't want to emit windows-changed if the sort order
|
||||
* isn't actually changing. This check catches most of those.
|
||||
*/
|
||||
@ -437,6 +674,8 @@ void
|
||||
_shell_app_add_window (ShellApp *app,
|
||||
MetaWindow *window)
|
||||
{
|
||||
guint32 user_time;
|
||||
|
||||
if (g_slist_find (app->windows, window))
|
||||
return;
|
||||
|
||||
@ -445,6 +684,13 @@ _shell_app_add_window (ShellApp *app,
|
||||
g_signal_connect (window, "notify::user-time", G_CALLBACK(shell_app_on_user_time_changed), app);
|
||||
app->window_sort_stale = TRUE;
|
||||
|
||||
user_time = meta_window_get_user_time (window);
|
||||
if (user_time > app->last_user_time)
|
||||
app->last_user_time = user_time;
|
||||
|
||||
if (app->state != SHELL_APP_STATE_RUNNING)
|
||||
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
||||
|
||||
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
||||
|
||||
if (app->workspace_switch_id == 0)
|
||||
@ -484,12 +730,58 @@ _shell_app_remove_window (ShellApp *app,
|
||||
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
||||
|
||||
if (app->windows == NULL)
|
||||
disconnect_workspace_switch (app);
|
||||
{
|
||||
disconnect_workspace_switch (app);
|
||||
|
||||
shell_app_state_transition (app, SHELL_APP_STATE_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_shell_app_set_starting (ShellApp *app,
|
||||
gboolean starting)
|
||||
{
|
||||
if (starting && app->state == SHELL_APP_STATE_STOPPED)
|
||||
shell_app_state_transition (app, SHELL_APP_STATE_STARTING);
|
||||
else if (!starting && app->state == SHELL_APP_STATE_STARTING)
|
||||
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_request_quit:
|
||||
* @app: A #ShellApp
|
||||
*
|
||||
* Initiate an asynchronous request to quit this application.
|
||||
* The application may interact with the user, and the user
|
||||
* might cancel the quit request from the application UI.
|
||||
*
|
||||
* This operation may not be supported for all applications.
|
||||
*
|
||||
* Returns: %TRUE if a quit request is supported for this application
|
||||
*/
|
||||
gboolean
|
||||
shell_app_request_quit (ShellApp *app)
|
||||
{
|
||||
GSList *iter;
|
||||
|
||||
/* TODO - check for an XSMP connection; we could probably use that */
|
||||
|
||||
for (iter = app->windows; iter; iter = iter->next)
|
||||
{
|
||||
MetaWindow *win = iter->data;
|
||||
|
||||
if (!shell_window_tracker_is_window_interesting (win))
|
||||
continue;
|
||||
|
||||
meta_window_delete (win, shell_global_get_current_time (shell_global_get ()));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_init (ShellApp *self)
|
||||
{
|
||||
self->state = SHELL_APP_STATE_STOPPED;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -516,6 +808,7 @@ shell_app_class_init(ShellAppClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = shell_app_get_property;
|
||||
gobject_class->dispose = shell_app_dispose;
|
||||
|
||||
shell_app_signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
||||
@ -525,4 +818,19 @@ shell_app_class_init(ShellAppClass *klass)
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* ShellApp:state:
|
||||
*
|
||||
* The high-level state of the application, effectively whether it's
|
||||
* running or not, or transitioning between those states.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_STATE,
|
||||
g_param_spec_enum ("state",
|
||||
"State",
|
||||
"Application state",
|
||||
SHELL_TYPE_APP_STATE,
|
||||
SHELL_APP_STATE_STOPPED,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define __SHELL_APP_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
@ -25,6 +26,12 @@ struct _ShellAppClass
|
||||
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SHELL_APP_STATE_STOPPED,
|
||||
SHELL_APP_STATE_STARTING,
|
||||
SHELL_APP_STATE_RUNNING
|
||||
} ShellAppState;
|
||||
|
||||
GType shell_app_get_type (void) G_GNUC_CONST;
|
||||
|
||||
const char *shell_app_get_id (ShellApp *app);
|
||||
@ -34,7 +41,16 @@ ClutterActor *shell_app_get_faded_icon (ShellApp *app, float size);
|
||||
char *shell_app_get_name (ShellApp *app);
|
||||
char *shell_app_get_description (ShellApp *app);
|
||||
gboolean shell_app_is_transient (ShellApp *app);
|
||||
gboolean shell_app_launch (ShellApp *info, GError **error);
|
||||
|
||||
void shell_app_activate_window (ShellApp *app, MetaWindow *window, guint32 timestamp);
|
||||
|
||||
void shell_app_activate (ShellApp *app);
|
||||
|
||||
void shell_app_open_new_window (ShellApp *app);
|
||||
|
||||
ShellAppState shell_app_get_state (ShellApp *app);
|
||||
|
||||
gboolean shell_app_request_quit (ShellApp *app);
|
||||
|
||||
guint shell_app_get_n_windows (ShellApp *app);
|
||||
|
||||
|
@ -51,20 +51,24 @@ shell_draw_clock (StDrawingArea *area,
|
||||
|
||||
void
|
||||
shell_draw_box_pointer (StDrawingArea *area,
|
||||
ShellPointerDirection direction,
|
||||
ClutterColor *border_color,
|
||||
ClutterColor *background_color)
|
||||
ShellPointerDirection direction)
|
||||
{
|
||||
StThemeNode *theme_node;
|
||||
ClutterColor border_color, body_color;
|
||||
guint width, height;
|
||||
cairo_t *cr;
|
||||
|
||||
theme_node = st_widget_get_theme_node (ST_WIDGET (area));
|
||||
st_theme_node_get_border_color (theme_node, (StSide)direction, &border_color);
|
||||
st_theme_node_get_foreground_color (theme_node, &body_color);
|
||||
|
||||
st_drawing_area_get_surface_size (area, &width, &height);
|
||||
|
||||
cr = st_drawing_area_get_context (area);
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
|
||||
clutter_cairo_set_source_color (cr, border_color);
|
||||
clutter_cairo_set_source_color (cr, &border_color);
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
@ -98,7 +102,7 @@ shell_draw_box_pointer (StDrawingArea *area,
|
||||
|
||||
cairo_stroke_preserve (cr);
|
||||
|
||||
clutter_cairo_set_source_color (cr, background_color);
|
||||
clutter_cairo_set_source_color (cr, &body_color);
|
||||
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
@ -8,17 +8,16 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Note that these correspond to StSide */
|
||||
typedef enum {
|
||||
SHELL_POINTER_UP,
|
||||
SHELL_POINTER_RIGHT,
|
||||
SHELL_POINTER_DOWN,
|
||||
SHELL_POINTER_LEFT,
|
||||
SHELL_POINTER_RIGHT
|
||||
SHELL_POINTER_LEFT
|
||||
} ShellPointerDirection;
|
||||
|
||||
void shell_draw_box_pointer (StDrawingArea *area,
|
||||
ShellPointerDirection direction,
|
||||
ClutterColor *border_color,
|
||||
ClutterColor *background_color);
|
||||
ShellPointerDirection direction);
|
||||
|
||||
void shell_draw_clock (StDrawingArea *area,
|
||||
int hour,
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
#include "shell-embedded-window-private.h"
|
||||
#include "gtk-compat.h"
|
||||
|
||||
/* This type is a subclass of GtkWindow that ties the window to a
|
||||
* ShellGtkEmbed; the window is reparented into the stage
|
||||
@ -55,8 +56,12 @@ static void
|
||||
shell_embedded_window_show (GtkWidget *widget)
|
||||
{
|
||||
ShellEmbeddedWindow *window = SHELL_EMBEDDED_WINDOW (widget);
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
|
||||
/* Skip GtkWindow, but run the default GtkWidget handling which
|
||||
* marks the widget visible */
|
||||
widget_class = g_type_class_peek (GTK_TYPE_WIDGET);
|
||||
widget_class->show (widget);
|
||||
|
||||
if (window->priv->actor)
|
||||
{
|
||||
@ -107,7 +112,7 @@ shell_embedded_window_realize (GtkWidget *widget)
|
||||
* modifying the GDK hierarchy.
|
||||
*/
|
||||
XReparentWindow (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
|
||||
GDK_WINDOW_XWINDOW (widget->window),
|
||||
GDK_WINDOW_XWINDOW (gtk_widget_get_window (widget)),
|
||||
stage_xwindow,
|
||||
window->priv->position.x, window->priv->position.y);
|
||||
}
|
||||
@ -202,7 +207,8 @@ _shell_embedded_window_set_actor (ShellEmbeddedWindow *window,
|
||||
|
||||
window->priv->actor = actor;
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (window) && CLUTTER_ACTOR_IS_REALIZED (actor))
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (window))
|
||||
&& CLUTTER_ACTOR_IS_REALIZED (actor))
|
||||
gtk_widget_map (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
@ -222,8 +228,8 @@ _shell_embedded_window_allocate (ShellEmbeddedWindow *window,
|
||||
window->priv->position.width = width;
|
||||
window->priv->position.height = height;
|
||||
|
||||
if (GTK_WIDGET_REALIZED (window))
|
||||
gdk_window_move_resize (GTK_WIDGET (window)->window,
|
||||
if (gtk_widget_get_realized (GTK_WIDGET (window)))
|
||||
gdk_window_move_resize (gtk_widget_get_window (GTK_WIDGET (window)),
|
||||
x, y, width, height);
|
||||
|
||||
allocation.x = 0;
|
||||
@ -239,7 +245,7 @@ _shell_embedded_window_realize (ShellEmbeddedWindow *window)
|
||||
{
|
||||
g_return_if_fail (SHELL_IS_EMBEDDED_WINDOW (window));
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (window))
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (window)))
|
||||
gtk_widget_map (GTK_WIDGET (window));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "big-enum-types.h"
|
||||
#include "shell-enum-types.h"
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
@ -1,6 +1,6 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#ifndef __BIG_ENUM_TYPES_H__
|
||||
#define __BIG_ENUM_TYPES_H__
|
||||
#ifndef __SHELL_ENUM_TYPES_H__
|
||||
#define __SHELL_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
@ -15,11 +15,11 @@ G_BEGIN_DECLS
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* !__BIG_ENUM_TYPES_H__ */
|
||||
#endif /* !__SHELL_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define BIG_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
#define SHELL_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
|
||||
/*** END value-header ***/
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user