Compare commits
113 Commits
Author | SHA1 | Date | |
---|---|---|---|
dfbbf9b436 | |||
a230ad9225 | |||
7a87474bcd | |||
479acf2d18 | |||
943c5e2edc | |||
1340413740 | |||
3adec65e20 | |||
d116f707c5 | |||
6f94b8cffe | |||
14a7e310fc | |||
bf680fdc7c | |||
851bf18265 | |||
452e98e3bc | |||
3cb54f6707 | |||
ed7881d6c9 | |||
ea1a45a878 | |||
003807334b | |||
24a5c3c19a | |||
62b2d69c2b | |||
cdbb7f8f5f | |||
ecc1f964c9 | |||
0f4e9189c5 | |||
799f56fe87 | |||
af9ab5dbb6 | |||
3486fcc89a | |||
1e2018d1b7 | |||
fb46bad665 | |||
e2d912c037 | |||
2879d9cdef | |||
300cefd66a | |||
72b4d2a234 | |||
02e438b1f8 | |||
58690c210e | |||
61f19a6c22 | |||
7465338ea1 | |||
9dff05a394 | |||
9f5a5ad635 | |||
2dcd0511c4 | |||
dd1a309cb6 | |||
9563515e97 | |||
ba77c51ee0 | |||
2e83b95484 | |||
756374b2e4 | |||
527ff6fb1d | |||
fb4fc496da | |||
8d9bd87c22 | |||
36acb0a63d | |||
3e0f5aec0c | |||
4f5c3b4b74 | |||
a4bf54e465 | |||
d94606587b | |||
74ea9f9305 | |||
4dc04d8c53 | |||
6e298759a4 | |||
3b320de8d7 | |||
30d3c1fe72 | |||
7469a2626a | |||
d534597589 | |||
ec3c8464d3 | |||
6319f649c2 | |||
44d34aba19 | |||
4245c573df | |||
c27b6493d6 | |||
7200207009 | |||
9ba66fd800 | |||
e4552fca40 | |||
b7d892e4c6 | |||
5b096be68b | |||
e843d11566 | |||
9c7803030e | |||
67ef36ef8e | |||
4c1614f6a5 | |||
3766784799 | |||
56e16ef712 | |||
559c313fc7 | |||
5e10d56d89 | |||
d289ce6aca | |||
c68e69bd6e | |||
a6f312cfd3 | |||
ca51a8c926 | |||
ec95a1c2d3 | |||
a418558b73 | |||
f097304f3b | |||
ea4ea4a9b2 | |||
b94452ee42 | |||
51db34d223 | |||
059c330d95 | |||
557f9ceb97 | |||
4aae57c274 | |||
fb0ca1ba9d | |||
51723bb93b | |||
1e41f869de | |||
28517e4c34 | |||
619066780f | |||
1636e6c187 | |||
d17c94f9b9 | |||
4b47803162 | |||
15a3f39f65 | |||
f7d85e618c | |||
f00500d3d5 | |||
25a5da074c | |||
43d737c663 | |||
789e24b59a | |||
b51bcf3e2b | |||
babb13f603 | |||
21ef33df65 | |||
83b1cedb86 | |||
36ee36283a | |||
74eac21870 | |||
e330c5ea17 | |||
e6644b7feb | |||
47af454115 | |||
1f31e80c47 |
9
.gitignore
vendored
9
.gitignore
vendored
@ -18,7 +18,15 @@ config
|
||||
configure
|
||||
data/gnome-shell.desktop
|
||||
data/gnome-shell.desktop.in
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
libtool
|
||||
omf.make
|
||||
po/*.gmo
|
||||
po/Makefile.in.in
|
||||
po/POTFILES
|
||||
po/stamp-it
|
||||
scripts/launcher.pyc
|
||||
src/*.gir
|
||||
src/*.typelib
|
||||
@ -31,3 +39,4 @@ src/gnome-shell
|
||||
src/test-recorder
|
||||
src/test-recorder.ogg
|
||||
stamp-h1
|
||||
xmldocs.make
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = data js src
|
||||
SUBDIRS = data js src po
|
||||
|
||||
EXTRA_DIST = \
|
||||
.project \
|
||||
|
28
autogen.sh
28
autogen.sh
@ -1,8 +1,22 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
(cd `dirname $0`;
|
||||
touch ChangeLog NEWS &&
|
||||
autoreconf --install --symlink &&
|
||||
autoreconf &&
|
||||
./configure --enable-maintainer-mode $@
|
||||
)
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="gnome-shell"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level gnome-shell directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "your OS vendor's package manager)."
|
||||
exit 1
|
||||
}
|
||||
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh
|
||||
|
19
configure.ac
19
configure.ac
@ -1,8 +1,8 @@
|
||||
AC_INIT(gnome-shell, 2.27.0)
|
||||
AC_INIT(gnome-shell, 2.27.1)
|
||||
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
|
||||
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
|
||||
AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip foreign])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
|
||||
@ -22,6 +22,9 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
|
||||
|
||||
PKG_PROG_PKG_CONFIG(0.16)
|
||||
|
||||
IT_PROG_INTLTOOL(0.26)
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||
AM_GCONF_SOURCE_2
|
||||
|
||||
@ -43,15 +46,16 @@ fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_RECORDER, $build_recorder)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugins gjs-gi-1.0 libgnome-menu $recorder_modules gconf-2.0 gdk-x11-2.0 clutter-x11-1.0 clutter-glx-1.0)
|
||||
# Collect more than 20 libraries for a prize!
|
||||
PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1 mutter-plugins
|
||||
gjs-gi-1.0 libgnome-menu $recorder_modules gconf-2.0
|
||||
gdk-x11-2.0 clutter-x11-1.0 clutter-glx-1.0
|
||||
gnome-desktop-2.0 >= 2.26 libstartup-notification-1.0
|
||||
gobject-introspection-1.0 >= 0.6.4)
|
||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
||||
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)
|
||||
# We require libgnomeui for generating thumbnails for recent files with GnomeThumbnailFactory.
|
||||
# We'll switch to using GnomeDesktopThumbnailFactory once the branch of gnome-desktop that contains
|
||||
# it becomes stable.
|
||||
PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0)
|
||||
|
||||
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
|
||||
# FIXME: metacity-plugins.pc should point directly to its .gir file
|
||||
@ -120,4 +124,5 @@ AC_OUTPUT([
|
||||
js/misc/Makefile
|
||||
js/ui/Makefile
|
||||
src/Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
|
@ -17,10 +17,10 @@ imagedir = $(pkgdatadir)/images
|
||||
dist_image_DATA = \
|
||||
add-workspace.svg \
|
||||
close.svg \
|
||||
close-black.svg \
|
||||
info.svg \
|
||||
remove-workspace.svg \
|
||||
view-more-activated.svg \
|
||||
view-more.svg
|
||||
magnifier.svg \
|
||||
remove-workspace.svg
|
||||
|
||||
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||
schema_DATA = gnome-shell.schemas
|
||||
|
66
data/close-black.svg
Normal file
66
data/close-black.svg
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="16px"
|
||||
height="16px"
|
||||
viewBox="0 0 16 16"
|
||||
enable-background="new 0 0 16 16"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46+devel"
|
||||
sodipodi:docname="close-black.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata2399"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs2397"><linearGradient
|
||||
id="linearGradient3173"><stop
|
||||
style="stop-color:#c4c4c4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3175" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3177" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 8 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="16 : 8 : 1"
|
||||
inkscape:persp3d-origin="8 : 5.3333333 : 1"
|
||||
id="perspective2401" /></defs><sodipodi:namedview
|
||||
inkscape:window-height="811"
|
||||
inkscape:window-width="1272"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="32.125"
|
||||
inkscape:cx="8"
|
||||
inkscape:cy="10.440056"
|
||||
inkscape:window-x="40"
|
||||
inkscape:window-y="40"
|
||||
inkscape:current-layer="Foreground" />
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M10.5,3.5l2,2L10,8l2.5,2.5l-2,2L8,10l-2.5,2.5l-2-2L6,8L3.5,5.5l2-2L8,6L10.5,3.5 z M0,8c0-4.418,3.582-8,8-8s8,3.582,8,8s-3.582,8-8,8S0,12.418,0,8z"
|
||||
id="path2394"
|
||||
style="fill-opacity:1;fill:#000000" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -35,7 +35,7 @@
|
||||
<applyto>/desktop/gnome/shell/sidebar/visible</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Whether or not to display the sidebar</short>
|
||||
<long>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
@ -8,22 +9,22 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
version="1.0"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="29px"
|
||||
height="18px"
|
||||
viewBox="0 0 29 18"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 18 18"
|
||||
enable-background="new 0 0 29 18"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="search_1.svg"
|
||||
inkscape:version="0.46+devel"
|
||||
sodipodi:docname="magnifier.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata16"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs14"><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 9 : 1"
|
||||
@ -34,46 +35,46 @@
|
||||
inkscape:window-height="728"
|
||||
inkscape:window-width="1103"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageopacity="1"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
pagecolor="#000000"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="19.275862"
|
||||
inkscape:cx="14.5"
|
||||
inkscape:cy="9"
|
||||
inkscape:window-x="40"
|
||||
inkscape:window-y="40"
|
||||
inkscape:current-layer="Foreground"><inkscape:grid
|
||||
showgrid="true"
|
||||
inkscape:zoom="27.260185"
|
||||
inkscape:cx="9.5844061"
|
||||
inkscape:cy="9.4435574"
|
||||
inkscape:window-x="142"
|
||||
inkscape:window-y="26"
|
||||
inkscape:current-layer="Foreground"
|
||||
inkscape:snap-global="true"
|
||||
showguides="false"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2391" /></sodipodi:namedview>
|
||||
<path
|
||||
d="M0,3c0-1.657,1.343-3,3-3h17c0.515,0,1.027,0.195,1.42,0.588l6.992,6.992c0.784,0.784,0.784,2.056,0,2.84l-6.992,6.992 C21.028,17.804,20.514,18,20,18H3c-1.657,0-3-1.343-3-3V3z"
|
||||
id="path3"
|
||||
style="fill:#151e2f;fill-opacity:1" />
|
||||
id="grid2391"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" /></sodipodi:namedview>
|
||||
|
||||
<g
|
||||
id="g5"
|
||||
style="fill:#4669a9;fill-opacity:1">
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
transform="translate(-4,-0.023114)">
|
||||
<path
|
||||
fill="#FFFFFF"
|
||||
d="M6.246,13.98c-0.319-0.319-0.319-0.837,0-1.157l3.717-3.717c0.319-0.319,0.837-0.319,1.157,0l0.786,0.787 c0.32,0.319,0.32,0.837,0,1.157l-3.717,3.717c-0.32,0.319-0.838,0.319-1.157,0L6.246,13.98L6.246,13.98z"
|
||||
d="m 6.246,13.98 c -0.319,-0.319 -0.319,-0.837 0,-1.157 L 9.963,9.106 c 0.319,-0.319 0.837,-0.319 1.157,0 l 0.786,0.787 c 0.32,0.319 0.32,0.837 0,1.157 l -3.717,3.717 c -0.32,0.319 -0.838,0.319 -1.157,0 l -0.786,-0.787 0,0 z"
|
||||
id="path7"
|
||||
style="fill:#4669a9;fill-opacity:1" />
|
||||
style="fill:#ffffff;fill-opacity:1" />
|
||||
<path
|
||||
fill="#FFFFFF"
|
||||
d="M9.076,11.937"
|
||||
d="M 9.076,11.937"
|
||||
id="path9"
|
||||
style="fill:#4669a9;fill-opacity:1" />
|
||||
style="fill:#ffffff;fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
fill="#FFFFFF"
|
||||
d="M11.25,7.5c0-1.243,1.007-2.25,2.25-2.25s2.25,1.007,2.25,2.25 s-1.007,2.25-2.25,2.25S11.25,8.743,11.25,7.5z M9,7.5C9,5.015,11.015,3,13.5,3S18,5.015,18,7.5S15.985,12,13.5,12S9,9.985,9,7.5z"
|
||||
d="m 7.25,7.476886 c 0,-1.243 1.007,-2.25 2.2499998,-2.25 1.2430002,0 2.2500002,1.007 2.2500002,2.25 0,1.243 -1.007,2.25 -2.2500002,2.25 C 8.257,9.726886 7.25,8.719886 7.25,7.476886 z m -2.25,0 c 0,-2.485 2.015,-4.5 4.4999998,-4.5 2.4850002,0 4.5000002,2.015 4.5000002,4.5 0,2.4849998 -2.015,4.5 -4.5000002,4.5 C 7.015,11.976886 5,9.9618858 5,7.476886 z"
|
||||
id="path11"
|
||||
style="fill:#4669a9;fill-opacity:1" />
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.9 KiB |
@ -1,66 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Foreground"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="29px"
|
||||
height="18px"
|
||||
viewBox="0 0 29 18"
|
||||
enable-background="new 0 0 29 18"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
sodipodi:docname="search_2.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
|
||||
id="metadata16"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs14"><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 9 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="29 : 9 : 1"
|
||||
inkscape:persp3d-origin="14.5 : 6 : 1"
|
||||
id="perspective18" />
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
inkscape:window-height="728"
|
||||
inkscape:window-width="1103"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
showgrid="false"
|
||||
inkscape:zoom="19.275862"
|
||||
inkscape:cx="14.5"
|
||||
inkscape:cy="9"
|
||||
inkscape:window-x="40"
|
||||
inkscape:window-y="40"
|
||||
inkscape:current-layer="Foreground"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid2391" /></sodipodi:namedview>
|
||||
|
||||
<path
|
||||
style="fill:#4669a9;fill-opacity:1"
|
||||
id="path9"
|
||||
d="" />
|
||||
<path
|
||||
id="path3"
|
||||
style="fill:#3d5a93;fill-opacity:1"
|
||||
d="M 0,3 C 0,1.343 1.343,0 3,0 L 20,0 C 20.515,0 21.027,0.195 21.42,0.588 L 28.412,7.58 C 29.196,8.364 29.196,9.636 28.412,10.42 L 21.42,17.412 C 21.028,17.804 20.514,18 20,18 L 3,18 C 1.343,18 0,16.657 0,15 L 0,3 zM 13.5,3 C 11.015,3 9,5.015 9,7.5 C 9,8.2423219 9.1815696,8.9452421 9.5,9.5625 L 6.25,12.8125 C 5.931,13.1325 5.9310002,13.64975 6.25,13.96875 L 7.03125,14.78125 C 7.35025,15.10025 7.8674999,15.10025 8.1875,14.78125 L 11.46875,11.5 C 12.080227,11.810879 12.767137,12 13.5,12 C 15.985,12 18,9.985 18,7.5 C 18,5.015 15.985,3 13.5,3 z M 11.25,7.5 C 11.25,6.257 12.257,5.25 13.5,5.25 C 14.743,5.25 15.75,6.257 15.75,7.5 C 15.75,8.743 14.743,9.75 13.5,9.75 C 12.257,9.75 11.25,8.743 11.25,7.5 z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.7 KiB |
@ -85,19 +85,18 @@ DocInfo.prototype = {
|
||||
|
||||
var docManagerInstance = null;
|
||||
|
||||
function getDocManager(size) {
|
||||
function getDocManager() {
|
||||
if (docManagerInstance == null)
|
||||
docManagerInstance = new DocManager(size);
|
||||
docManagerInstance = new DocManager();
|
||||
return docManagerInstance;
|
||||
}
|
||||
|
||||
function DocManager(size) {
|
||||
this._init(size);
|
||||
function DocManager() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DocManager.prototype = {
|
||||
_init: function(iconSize) {
|
||||
this._iconSize = iconSize;
|
||||
_init: function() {
|
||||
this._recentManager = Gtk.RecentManager.get_default();
|
||||
this._items = {};
|
||||
this._recentManager.connect('changed', Lang.bind(this, function(recentManager) {
|
||||
@ -112,6 +111,9 @@ DocManager.prototype = {
|
||||
let newItems = {};
|
||||
for (let i = 0; i < docs.length; i++) {
|
||||
let recentInfo = docs[i];
|
||||
if (!recentInfo.exists())
|
||||
continue;
|
||||
|
||||
let docInfo = new DocInfo(recentInfo);
|
||||
|
||||
// we use GtkRecentInfo URI as an item Id
|
||||
@ -126,7 +128,7 @@ DocManager.prototype = {
|
||||
dump them here */
|
||||
let texCache = Shell.TextureCache.get_default();
|
||||
for (var uri in deleted) {
|
||||
texCache.evict_recent_thumbnail(this._iconSize, this._items[uri]);
|
||||
texCache.evict_recent_thumbnail(this._items[uri]);
|
||||
}
|
||||
this._items = newItems;
|
||||
},
|
||||
|
@ -3,6 +3,7 @@ jsuidir = $(pkgdatadir)/js/ui
|
||||
dist_jsui_DATA = \
|
||||
altTab.js \
|
||||
appDisplay.js \
|
||||
appIcon.js \
|
||||
button.js \
|
||||
chrome.js \
|
||||
dash.js \
|
||||
@ -12,7 +13,7 @@ dist_jsui_DATA = \
|
||||
link.js \
|
||||
lookingGlass.js \
|
||||
main.js \
|
||||
overlay.js \
|
||||
overview.js \
|
||||
panel.js \
|
||||
places.js \
|
||||
runDialog.js \
|
||||
|
@ -44,10 +44,8 @@ AltTabPopup.prototype = {
|
||||
spacing: POPUP_GRID_SPACING,
|
||||
orientation: Big.BoxOrientation.VERTICAL });
|
||||
|
||||
// Icon grid. It would be nice to use Tidy.Grid for the this,
|
||||
// but Tidy.Grid is lame in various ways. (Eg, it seems to
|
||||
// have a minimum size of 200x200.) So we create a vertical
|
||||
// Big.Box containing multiple horizontal Big.Boxes.
|
||||
// Icon grid. TODO: Investigate Nbtk.Grid once that lands. Currently
|
||||
// just implemented using a chain of Big.Box.
|
||||
this._grid = new Big.Box({ spacing: POPUP_GRID_SPACING,
|
||||
orientation: Big.BoxOrientation.VERTICAL });
|
||||
let gcenterbox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
@ -144,8 +142,6 @@ AltTabPopup.prototype = {
|
||||
show : function(initialSelection) {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
Main.startModal();
|
||||
|
||||
global.window_group.add_actor(this._overlay);
|
||||
this._overlay.raise_top();
|
||||
this._overlay.show();
|
||||
@ -164,8 +160,6 @@ AltTabPopup.prototype = {
|
||||
destroy : function() {
|
||||
this.actor.destroy();
|
||||
this._overlay.destroy();
|
||||
|
||||
Main.endModal();
|
||||
},
|
||||
|
||||
select : function(n) {
|
||||
|
@ -6,12 +6,14 @@ const Pango = imports.gi.Pango;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Tidy = imports.gi.Tidy;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppIcon = imports.ui.appIcon;
|
||||
const DND = imports.ui.dnd;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
@ -20,12 +22,6 @@ const Workspaces = imports.ui.workspaces;
|
||||
const ENTERED_MENU_COLOR = new Clutter.Color();
|
||||
ENTERED_MENU_COLOR.from_pixel(0x00ff0022);
|
||||
|
||||
const GLOW_COLOR = new Clutter.Color();
|
||||
GLOW_COLOR.from_pixel(0x4f6ba4ff);
|
||||
const GLOW_PADDING = 5;
|
||||
|
||||
|
||||
const APP_ICON_SIZE = 48;
|
||||
const WELL_DEFAULT_COLUMNS = 4;
|
||||
const WELL_ITEM_HSPACING = 0;
|
||||
const WELL_ITEM_VSPACING = 4;
|
||||
@ -74,6 +70,10 @@ AppDisplayItem.prototype = {
|
||||
// Returns a preview icon for the item.
|
||||
_createPreviewIcon : function() {
|
||||
return this._appInfo.create_icon_texture(GenericDisplay.PREVIEW_ICON_SIZE);
|
||||
},
|
||||
|
||||
shellWorkspaceLaunch: function() {
|
||||
this.launch();
|
||||
}
|
||||
};
|
||||
|
||||
@ -193,12 +193,15 @@ AppDisplay.prototype = {
|
||||
this._appSystem.connect('favorites-changed', Lang.bind(this, function(appSys) {
|
||||
this._redisplay(false);
|
||||
}));
|
||||
this._appMonitor.connect('changed', Lang.bind(this, function(monitor) {
|
||||
this._appMonitor.connect('app-added', Lang.bind(this, function(monitor) {
|
||||
this._redisplay(false);
|
||||
}));
|
||||
this._appMonitor.connect('app-removed', Lang.bind(this, function(monitor) {
|
||||
this._redisplay(false);
|
||||
}));
|
||||
|
||||
// Load the apps now so it doesn't slow down the first
|
||||
// transition into the overlay
|
||||
// transition into the Overview
|
||||
this._refreshCache();
|
||||
|
||||
this._focusInMenus = true;
|
||||
@ -308,7 +311,7 @@ AppDisplay.prototype = {
|
||||
|
||||
_redisplayMenus: function() {
|
||||
this._menuDisplay.remove_all();
|
||||
this._addMenuItem('Frequent', null, 'gtk-select-all');
|
||||
this._addMenuItem(_("Frequent"), null, 'gtk-select-all');
|
||||
for (let i = 0; i < this._menus.length; i++) {
|
||||
let menu = this._menus[i];
|
||||
this._addMenuItem(menu.name, menu.id, menu.icon, i+1);
|
||||
@ -330,12 +333,18 @@ AppDisplay.prototype = {
|
||||
this._allItems = {};
|
||||
this._appCategories = {};
|
||||
|
||||
this._menus = this._appSystem.get_menus();
|
||||
// Loop over the toplevel menu items, load the set of desktop file ids
|
||||
// associated with each one
|
||||
for (let i = 0; i < this._menus.length; i++) {
|
||||
let menu = this._menus[i];
|
||||
// associated with each one, skipping empty menus
|
||||
let allMenus = this._appSystem.get_menus();
|
||||
this._menus = [];
|
||||
for (let i = 0; i < allMenus.length; i++) {
|
||||
let menu = allMenus[i];
|
||||
let menuApps = this._appSystem.get_applications_for_menu(menu.id);
|
||||
let hasVisibleApps = menuApps.some(function (app) { return !app.get_is_nodisplay(); });
|
||||
if (!hasVisibleApps) {
|
||||
continue;
|
||||
}
|
||||
this._menus.push(menu);
|
||||
for (let j = 0; j < menuApps.length; j++) {
|
||||
let app = menuApps[j];
|
||||
this._addApp(app);
|
||||
@ -444,104 +453,46 @@ function WellDisplayItem(appInfo, isFavorite) {
|
||||
}
|
||||
|
||||
WellDisplayItem.prototype = {
|
||||
__proto__ : AppIcon.AppIcon.prototype,
|
||||
|
||||
_init : function(appInfo, isFavorite) {
|
||||
this.appInfo = appInfo;
|
||||
AppIcon.AppIcon.prototype._init.call(this, appInfo);
|
||||
|
||||
this.isFavorite = isFavorite;
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
corner_radius: 2,
|
||||
border: 0,
|
||||
padding: 1,
|
||||
border_color: GenericDisplay.ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR,
|
||||
reactive: true });
|
||||
this.actor._delegate = this;
|
||||
this.actor.connect('button-release-event', Lang.bind(this, function (b, e) {
|
||||
this._handleActivate();
|
||||
}));
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
|
||||
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
this._icon = appInfo.create_icon_texture(APP_ICON_SIZE);
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
||||
|
||||
let nameBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
this._nameBox = nameBox;
|
||||
|
||||
this._name = new Clutter.Text({ color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans 12px",
|
||||
line_alignment: Pango.Alignment.CENTER,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: appInfo.get_name() });
|
||||
nameBox.append(this._name, Big.BoxPackFlags.NONE);
|
||||
if (this._windows.length > 0) {
|
||||
let glow = new Shell.DrawingArea({});
|
||||
glow.connect('redraw', Lang.bind(this, function (e, tex) {
|
||||
Shell.draw_glow(tex,
|
||||
GLOW_COLOR.red / 255,
|
||||
GLOW_COLOR.green / 255,
|
||||
GLOW_COLOR.blue / 255,
|
||||
GLOW_COLOR.alpha / 255);
|
||||
}));
|
||||
this._name.connect('notify::allocation', Lang.bind(this, function () {
|
||||
let x = this._name.x;
|
||||
let y = this._name.y;
|
||||
let width = this._name.width;
|
||||
let height = this._name.height;
|
||||
// If we're smaller than the allocated box width, pad out the glow a bit
|
||||
// to make it more visible
|
||||
if ((width + GLOW_PADDING * 2) < this._nameBox.width) {
|
||||
width += GLOW_PADDING * 2;
|
||||
x -= GLOW_PADDING;
|
||||
}
|
||||
glow.set_size(width, height);
|
||||
glow.set_position(x, y);
|
||||
}));
|
||||
nameBox.add_actor(glow);
|
||||
glow.lower(this._name);
|
||||
}
|
||||
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
||||
},
|
||||
|
||||
_handleActivate: function () {
|
||||
if (this._windows.length == 0)
|
||||
this.launch();
|
||||
else {
|
||||
if (this._windows.length == 0) {
|
||||
this.appInfo.launch();
|
||||
Main.overview.hide();
|
||||
} else {
|
||||
/* Pick the first window and activate it;
|
||||
* In the future, we want to have a menu dropdown here. */
|
||||
let first = this._windows[0];
|
||||
Main.overlay.activateWindow (first, Clutter.get_current_event_time());
|
||||
Main.overview.activateWindow(first, Clutter.get_current_event_time());
|
||||
}
|
||||
this.emit('activated');
|
||||
},
|
||||
|
||||
// Opens an application represented by this display item.
|
||||
launch : function() {
|
||||
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.appInfo.launch();
|
||||
},
|
||||
|
||||
// Draggable interface - FIXME deduplicate with GenericDisplay
|
||||
getDragActor: function(stageX, stageY) {
|
||||
this.dragActor = this.appInfo.create_icon_texture(APP_ICON_SIZE);
|
||||
|
||||
// If the user dragged from the icon itself, then position
|
||||
// the dragActor over the original icon. Otherwise center it
|
||||
// around the pointer
|
||||
let [iconX, iconY] = this._icon.get_transformed_position();
|
||||
let [iconWidth, iconHeight] = this._icon.get_transformed_size();
|
||||
if (stageX > iconX && stageX <= iconX + iconWidth &&
|
||||
stageY > iconY && stageY <= iconY + iconHeight)
|
||||
this.dragActor.set_position(iconX, iconY);
|
||||
else
|
||||
this.dragActor.set_position(stageX - this.dragActor.width / 2, stageY - this.dragActor.height / 2);
|
||||
return this.dragActor;
|
||||
return this.appInfo.create_icon_texture(this._icon.height);
|
||||
},
|
||||
|
||||
// Returns the original icon that is being used as a source for the cloned texture
|
||||
@ -555,8 +506,6 @@ WellDisplayItem.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(WellDisplayItem.prototype);
|
||||
|
||||
function WellGrid() {
|
||||
this._init();
|
||||
}
|
||||
@ -565,9 +514,7 @@ WellGrid.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new Shell.GenericContainer();
|
||||
|
||||
this._separator = new Big.Box({ border_color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
border_top: 1,
|
||||
height: 1 });
|
||||
this._separator = new Big.Box({ height: 1 });
|
||||
this.actor.add_actor(this._separator);
|
||||
this._separatorIndex = 0;
|
||||
this._cachedSeparatorY = 0;
|
||||
@ -611,20 +558,17 @@ WellGrid.prototype = {
|
||||
let y = box.y1;
|
||||
let columnIndex = 0;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let [childMinWidth, childMinHeight,
|
||||
childNaturalWidth, childNaturalHeight] = children[i].get_preferred_size();
|
||||
let [childMinWidth, childNaturalWidth] = children[i].get_preferred_width(-1);
|
||||
|
||||
/* Center the item in its allocation */
|
||||
/* Center the item in its allocation horizontally */
|
||||
let width = Math.min(itemWidth, childNaturalWidth);
|
||||
let height = Math.min(itemHeight, childNaturalHeight);
|
||||
let horizSpacing = (itemWidth - width) / 2;
|
||||
let vertSpacing = (itemHeight - height) / 2;
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = Math.floor(x + horizSpacing);
|
||||
childBox.y1 = Math.floor(y + vertSpacing);
|
||||
childBox.y1 = y;
|
||||
childBox.x2 = childBox.x1 + width;
|
||||
childBox.y2 = childBox.y1 + height;
|
||||
childBox.y2 = childBox.y1 + itemHeight;
|
||||
children[i].allocate(childBox, flags);
|
||||
|
||||
let atSeparator = (i == this._separatorIndex - 1);
|
||||
@ -763,7 +707,10 @@ AppWell.prototype = {
|
||||
this._appSystem.connect('favorites-changed', Lang.bind(this, function(appSys) {
|
||||
this._redisplay();
|
||||
}));
|
||||
this._appMonitor.connect('changed', Lang.bind(this, function(monitor) {
|
||||
this._appMonitor.connect('window-added', Lang.bind(this, function(monitor) {
|
||||
this._redisplay();
|
||||
}));
|
||||
this._appMonitor.connect('window-removed', Lang.bind(this, function(monitor) {
|
||||
this._redisplay();
|
||||
}));
|
||||
|
||||
@ -796,11 +743,10 @@ AppWell.prototype = {
|
||||
/* hardcode here pending some design about how exactly desktop contexts behave */
|
||||
let contextId = "";
|
||||
|
||||
let runningIds = this._appMonitor.get_running_app_ids(contextId).filter(function (e) {
|
||||
return !(e in favoriteIdsHash);
|
||||
let running = this._appMonitor.get_running_apps(contextId).filter(function (e) {
|
||||
return !(e.get_id() in favoriteIdsHash);
|
||||
});
|
||||
let favorites = this._lookupApps(favoriteIds);
|
||||
let running = this._lookupApps(runningIds);
|
||||
|
||||
let displays = []
|
||||
this._addApps(favorites, true);
|
||||
@ -813,9 +759,6 @@ AppWell.prototype = {
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = apps[i];
|
||||
let display = new WellDisplayItem(app, this.isFavorite);
|
||||
display.connect('activated', Lang.bind(this, function (display) {
|
||||
Main.overlay.hide();
|
||||
}));
|
||||
this._grid.actor.add_actor(display.actor);
|
||||
}
|
||||
},
|
||||
@ -824,22 +767,25 @@ AppWell.prototype = {
|
||||
acceptDrop : function(source, actor, x, y, time) {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
let id = null;
|
||||
let appSystem = Shell.AppSystem.get_default();
|
||||
|
||||
let app = null;
|
||||
if (source instanceof WellDisplayItem) {
|
||||
id = source.appInfo.get_id();
|
||||
app = source.appInfo;
|
||||
} else if (source instanceof AppDisplayItem) {
|
||||
id = source.getId();
|
||||
app = appSystem.lookup_cached_app(source.getId());
|
||||
} else if (source instanceof Workspaces.WindowClone) {
|
||||
let appMonitor = Shell.AppMonitor.get_default();
|
||||
let app = appMonitor.get_window_app(source.metaWindow);
|
||||
id = app.get_id();
|
||||
app = appMonitor.get_window_app(source.metaWindow);
|
||||
}
|
||||
|
||||
if (id == null) {
|
||||
// Don't allow favoriting of transient apps
|
||||
if (app == null || app.is_transient()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let appSystem = Shell.AppSystem.get_default();
|
||||
let id = app.get_id();
|
||||
|
||||
let favoriteIds = this._appSystem.get_favorites();
|
||||
let favoriteIdsObject = this._arrayValues(favoriteIds);
|
||||
|
||||
|
83
js/ui/appIcon.js
Normal file
83
js/ui/appIcon.js
Normal file
@ -0,0 +1,83 @@
|
||||
/* -*- 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 Shell = imports.gi.Shell;
|
||||
const Lang = imports.lang;
|
||||
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const GLOW_COLOR = new Clutter.Color();
|
||||
GLOW_COLOR.from_pixel(0x4f6ba4ff);
|
||||
const GLOW_PADDING = 5;
|
||||
|
||||
const APP_ICON_SIZE = 48;
|
||||
|
||||
function AppIcon(appInfo) {
|
||||
this._init(appInfo);
|
||||
}
|
||||
|
||||
AppIcon.prototype = {
|
||||
_init : function(appInfo) {
|
||||
this.appInfo = appInfo;
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
corner_radius: 2,
|
||||
border: 0,
|
||||
padding: 1,
|
||||
border_color: GenericDisplay.ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR,
|
||||
reactive: true });
|
||||
this.actor._delegate = this;
|
||||
|
||||
let iconBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._icon = appInfo.create_icon_texture(APP_ICON_SIZE);
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
||||
|
||||
let nameBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
this._nameBox = nameBox;
|
||||
|
||||
this._name = new Clutter.Text({ color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
font_name: "Sans 12px",
|
||||
line_alignment: Pango.Alignment.CENTER,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: appInfo.get_name() });
|
||||
nameBox.append(this._name, Big.BoxPackFlags.NONE);
|
||||
if (this._windows.length > 0) {
|
||||
let glow = new Shell.DrawingArea({});
|
||||
glow.connect('redraw', Lang.bind(this, function (e, tex) {
|
||||
Shell.draw_app_highlight(tex,
|
||||
this._windows.length,
|
||||
GLOW_COLOR.red / 255,
|
||||
GLOW_COLOR.green / 255,
|
||||
GLOW_COLOR.blue / 255,
|
||||
GLOW_COLOR.alpha / 255);
|
||||
}));
|
||||
this._name.connect('notify::allocation', Lang.bind(this, function () {
|
||||
let x = this._name.x;
|
||||
let y = this._name.y;
|
||||
let width = this._name.width;
|
||||
let height = this._name.height;
|
||||
// If we're smaller than the allocated box width, pad out the glow a bit
|
||||
// to make it more visible
|
||||
if ((width + GLOW_PADDING * 2) < this._nameBox.width) {
|
||||
width += GLOW_PADDING * 2;
|
||||
x -= GLOW_PADDING;
|
||||
}
|
||||
glow.set_size(width, height);
|
||||
glow.set_position(x, y);
|
||||
}));
|
||||
nameBox.add_actor(glow);
|
||||
glow.lower(this._name);
|
||||
}
|
||||
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
};
|
@ -4,8 +4,8 @@ const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
const DEFAULT_BUTTON_COLOR = new Clutter.Color();
|
||||
@ -22,12 +22,12 @@ const DEFAULT_FONT = 'Sans Bold 16px';
|
||||
// Padding on the left and right side of the button.
|
||||
const SIDE_PADDING = 14;
|
||||
|
||||
function Button(widget, buttonColor, pressedButtonColor, textColor, staysPressed, minWidth, minHeight, font) {
|
||||
this._init(widget, buttonColor, pressedButtonColor, textColor, staysPressed, minWidth, minHeight, font);
|
||||
function Button(widget, buttonColor, pressedButtonColor, textColor, staysPressed, font) {
|
||||
this._init(widget, buttonColor, pressedButtonColor, textColor, staysPressed, font);
|
||||
}
|
||||
|
||||
Button.prototype = {
|
||||
_init : function(widgetOrText, buttonColor, pressedButtonColor, textColor, staysPressed, minWidth, minHeight, font) {
|
||||
_init : function(widgetOrText, buttonColor, pressedButtonColor, textColor, staysPressed, font) {
|
||||
let me = this;
|
||||
|
||||
this._buttonColor = buttonColor
|
||||
@ -50,11 +50,6 @@ Button.prototype = {
|
||||
if (font == null)
|
||||
this._font = DEFAULT_FONT;
|
||||
|
||||
if (minWidth == null)
|
||||
minWidth = 0;
|
||||
if (minHeight == null)
|
||||
minHeight = 0;
|
||||
|
||||
// if this._staysPressed is true, this._active will be true past the first release of a button, until a subsequent one (the button
|
||||
// is unpressed) or until release() is called explicitly
|
||||
this._active = false;
|
||||
@ -78,9 +73,6 @@ Button.prototype = {
|
||||
|
||||
this.button.append(this._widget, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._minWidth = minWidth;
|
||||
this._minHeight = minHeight;
|
||||
|
||||
this.button.connect('button-press-event',
|
||||
function(o, event) {
|
||||
me._isBetweenPressAndRelease = true;
|
||||
@ -103,6 +95,7 @@ Button.prototype = {
|
||||
if (!me._active) {
|
||||
me.button.backgroundColor = me._buttonColor;
|
||||
}
|
||||
me.emit('enter-event');
|
||||
return false;
|
||||
});
|
||||
this.button.connect('leave-event',
|
||||
@ -112,6 +105,7 @@ Button.prototype = {
|
||||
if (!me._active) {
|
||||
me.button.backgroundColor = null;
|
||||
}
|
||||
me.emit('leave-event');
|
||||
return false;
|
||||
});
|
||||
},
|
||||
@ -135,6 +129,8 @@ Button.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Button.prototype);
|
||||
|
||||
/* Delay before the icon should appear, in seconds after the pointer has entered the parent */
|
||||
const ANIMATION_TIME = 0.25;
|
||||
|
||||
|
@ -9,7 +9,7 @@ const Shell = imports.gi.Shell;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
// This manages the shell "chrome"; the UI that's visible in the
|
||||
// normal mode (ie, outside the overlay), that surrounds the main
|
||||
// normal mode (ie, outside the Overview), that surrounds the main
|
||||
// workspace content.
|
||||
|
||||
function Chrome() {
|
||||
@ -23,8 +23,8 @@ Chrome.prototype = {
|
||||
// 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.nonOverlayActor = new Clutter.Group();
|
||||
this.actor.add_actor(this.nonOverlayActor);
|
||||
this.nonOverviewActor = new Clutter.Group();
|
||||
this.actor.add_actor(this.nonOverviewActor);
|
||||
|
||||
this._obscuredByFullscreen = false;
|
||||
|
||||
@ -37,10 +37,10 @@ Chrome.prototype = {
|
||||
global.screen.connect('notify::n-workspaces',
|
||||
Lang.bind(this, this._queueUpdateRegions));
|
||||
|
||||
Main.overlay.connect('showing',
|
||||
Lang.bind(this, this._overlayShowing));
|
||||
Main.overlay.connect('hidden',
|
||||
Lang.bind(this, this._overlayHidden));
|
||||
Main.overview.connect('showing',
|
||||
Lang.bind(this, this._overviewShowing));
|
||||
Main.overview.connect('hidden',
|
||||
Lang.bind(this, this._overviewHidden));
|
||||
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
@ -78,27 +78,27 @@ Chrome.prototype = {
|
||||
else if (shapeActor && !this._verifyAncestry(shapeActor, actor))
|
||||
throw new Error('shapeActor is not a descendent of actor');
|
||||
|
||||
this.nonOverlayActor.add_actor(actor);
|
||||
this.nonOverviewActor.add_actor(actor);
|
||||
|
||||
if (shapeActor)
|
||||
this._trackActor(shapeActor, true, true);
|
||||
},
|
||||
|
||||
// setVisibleInOverlay:
|
||||
// setVisibleInOverview:
|
||||
// @actor: an actor in the chrome layer
|
||||
// @visible: overlay visibility
|
||||
// @visible: Overview visibility
|
||||
//
|
||||
// By default, actors in the chrome layer are automatically hidden
|
||||
// when the overlay is shown. This can be used to override that
|
||||
// when the Overview is shown. This can be used to override that
|
||||
// behavior
|
||||
setVisibleInOverlay: function(actor, visible) {
|
||||
setVisibleInOverview: function(actor, visible) {
|
||||
if (!this._verifyAncestry(actor, this.actor))
|
||||
throw new Error('actor is not a descendent of the chrome layer');
|
||||
|
||||
if (visible)
|
||||
actor.reparent(this.actor);
|
||||
else
|
||||
actor.reparent(this.nonOverlayActor);
|
||||
actor.reparent(this.nonOverviewActor);
|
||||
},
|
||||
|
||||
// addInputRegionActor:
|
||||
@ -126,8 +126,8 @@ Chrome.prototype = {
|
||||
//
|
||||
// Removes @actor from the chrome layer
|
||||
removeActor: function(actor) {
|
||||
if (actor.get_parent() == this.nonOverlayActor)
|
||||
this.nonOverlayActor.remove_actor(actor);
|
||||
if (actor.get_parent() == this.nonOverviewActor)
|
||||
this.nonOverviewActor.remove_actor(actor);
|
||||
else
|
||||
this.actor.remove_actor(actor);
|
||||
this._untrackActor(actor, true, true);
|
||||
@ -172,7 +172,7 @@ Chrome.prototype = {
|
||||
this._trackedActors.push(actorData);
|
||||
|
||||
actor = actor.get_parent();
|
||||
if (actor != this.actor && actor != this.nonOverlayActor)
|
||||
if (actor != this.actor && actor != this.nonOverviewActor)
|
||||
this._trackActor(actor, false, false);
|
||||
|
||||
if (inputRegion || strut)
|
||||
@ -200,7 +200,7 @@ Chrome.prototype = {
|
||||
actor.disconnect(actorData.parentSetId);
|
||||
|
||||
actor = actor.get_parent();
|
||||
if (actor && actor != this.actor && actor != this.nonOverlayActor)
|
||||
if (actor && actor != this.actor && actor != this.nonOverviewActor)
|
||||
this._untrackActor(actor, false, false);
|
||||
}
|
||||
|
||||
@ -211,23 +211,23 @@ Chrome.prototype = {
|
||||
_actorReparented: function(actor, oldParent) {
|
||||
if (this._verifyAncestry(actor, this.actor)) {
|
||||
let newParent = actor.get_parent();
|
||||
if (newParent != this.actor && newParent != this.nonOverlayActor)
|
||||
if (newParent != this.actor && newParent != this.nonOverviewActor)
|
||||
this._trackActor(newParent, false, false);
|
||||
}
|
||||
if (oldParent != this.actor && oldParent != this.nonOverlayActor)
|
||||
if (oldParent != this.actor && oldParent != this.nonOverviewActor)
|
||||
this._untrackActor(oldParent, false, false);
|
||||
},
|
||||
|
||||
_overlayShowing: function() {
|
||||
_overviewShowing: function() {
|
||||
this.actor.show();
|
||||
this.nonOverlayActor.hide();
|
||||
this.nonOverviewActor.hide();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
_overlayHidden: function() {
|
||||
_overviewHidden: function() {
|
||||
if (this._obscuredByFullscreen)
|
||||
this.actor.hide();
|
||||
this.nonOverlayActor.show();
|
||||
this.nonOverviewActor.show();
|
||||
this._queueUpdateRegions();
|
||||
},
|
||||
|
||||
@ -272,7 +272,7 @@ Chrome.prototype = {
|
||||
break;
|
||||
}
|
||||
|
||||
let shouldBeVisible = !this._obscuredByFullscreen || Main.overlay.visible;
|
||||
let shouldBeVisible = !this._obscuredByFullscreen || Main.overview.visible;
|
||||
if (this.actor.visible != shouldBeVisible) {
|
||||
this.actor.visible = shouldBeVisible;
|
||||
this._queueUpdateRegions();
|
||||
|
629
js/ui/dash.js
629
js/ui/dash.js
@ -2,12 +2,14 @@
|
||||
|
||||
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 Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const DocDisplay = imports.ui.docDisplay;
|
||||
@ -17,15 +19,49 @@ const Button = imports.ui.button;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const DEFAULT_PADDING = 4;
|
||||
const DEFAULT_SPACING = 4;
|
||||
const DASH_SECTION_PADDING = 6;
|
||||
const DASH_SECTION_SPACING = 12;
|
||||
const DASH_SECTION_SPACING = 40;
|
||||
const DASH_CORNER_RADIUS = 5;
|
||||
const DASH_SEARCH_BG_COLOR = new Clutter.Color();
|
||||
DASH_SEARCH_BG_COLOR.from_pixel(0xffffffff);
|
||||
const DASH_SECTION_COLOR = new Clutter.Color();
|
||||
DASH_SECTION_COLOR.from_pixel(0x846c3dff);
|
||||
const DASH_TEXT_COLOR = new Clutter.Color();
|
||||
DASH_TEXT_COLOR.from_pixel(0xffffffff);
|
||||
const DASH_PADDING_SIDE = 14;
|
||||
|
||||
const BACKGROUND_COLOR = new Clutter.Color();
|
||||
BACKGROUND_COLOR.from_pixel(0x000000c0);
|
||||
|
||||
const PRELIGHT_COLOR = new Clutter.Color();
|
||||
PRELIGHT_COLOR.from_pixel(0x4f6fadaa);
|
||||
|
||||
const TEXT_COLOR = new Clutter.Color();
|
||||
TEXT_COLOR.from_pixel(0x5f5f5fff);
|
||||
const BRIGHTER_TEXT_COLOR = new Clutter.Color();
|
||||
BRIGHTER_TEXT_COLOR.from_pixel(0xbbbbbbff);
|
||||
const BRIGHT_TEXT_COLOR = new Clutter.Color();
|
||||
BRIGHT_TEXT_COLOR.from_pixel(0xffffffff);
|
||||
const SEARCH_TEXT_COLOR = new Clutter.Color();
|
||||
SEARCH_TEXT_COLOR.from_pixel(0x333333ff);
|
||||
|
||||
const SEARCH_CURSOR_COLOR = BRIGHT_TEXT_COLOR;
|
||||
const HIGHLIGHTED_SEARCH_CURSOR_COLOR = SEARCH_TEXT_COLOR;
|
||||
|
||||
const HIGHLIGHTED_SEARCH_BACKGROUND_COLOR = new Clutter.Color();
|
||||
HIGHLIGHTED_SEARCH_BACKGROUND_COLOR.from_pixel(0xc4c4c4ff);
|
||||
|
||||
const SEARCH_BORDER_BOTTOM_COLOR = new Clutter.Color();
|
||||
SEARCH_BORDER_BOTTOM_COLOR.from_pixel(0x191919ff);
|
||||
|
||||
const SECTION_BORDER_COLOR = new Clutter.Color();
|
||||
SECTION_BORDER_COLOR.from_pixel(0x262626ff);
|
||||
const SECTION_BORDER = 1;
|
||||
const SECTION_INNER_BORDER_COLOR = new Clutter.Color();
|
||||
SECTION_INNER_BORDER_COLOR.from_pixel(0x000000ff);
|
||||
const SECTION_BACKGROUND_TOP_COLOR = new Clutter.Color();
|
||||
SECTION_BACKGROUND_TOP_COLOR.from_pixel(0x161616ff);
|
||||
const SECTION_BACKGROUND_BOTTOM_COLOR = new Clutter.Color();
|
||||
SECTION_BACKGROUND_BOTTOM_COLOR.from_pixel(0x000000ff);
|
||||
const SECTION_INNER_SPACING = 8;
|
||||
|
||||
const BROWSE_ACTIVATED_BG = new Clutter.Color();
|
||||
BROWSE_ACTIVATED_BG.from_pixel(0x303030f0);
|
||||
|
||||
const PANE_BORDER_COLOR = new Clutter.Color();
|
||||
PANE_BORDER_COLOR.from_pixel(0x101d3cfa);
|
||||
@ -34,7 +70,6 @@ const PANE_BORDER_WIDTH = 2;
|
||||
const PANE_BACKGROUND_COLOR = new Clutter.Color();
|
||||
PANE_BACKGROUND_COLOR.from_pixel(0x000000f4);
|
||||
|
||||
|
||||
function Pane() {
|
||||
this._init();
|
||||
}
|
||||
@ -135,7 +170,7 @@ ResultArea.prototype = {
|
||||
|
||||
this.controlBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER });
|
||||
this.controlBox.append(this.display.displayControl, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(this.controlBox, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.append(this.controlBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this.display.load();
|
||||
}
|
||||
@ -144,7 +179,7 @@ ResultArea.prototype = {
|
||||
// Utility function shared between ResultPane and the DocDisplay in the main dash.
|
||||
// Connects to the detail signal of the display, and on-demand creates a new
|
||||
// pane.
|
||||
function createPaneForDetails(dash, display, detailsWidth) {
|
||||
function createPaneForDetails(dash, display) {
|
||||
let detailPane = null;
|
||||
display.connect('show-details', Lang.bind(this, function(display, index) {
|
||||
if (detailPane == null) {
|
||||
@ -160,7 +195,7 @@ function createPaneForDetails(dash, display, detailsWidth) {
|
||||
|
||||
if (index >= 0) {
|
||||
detailPane.destroyContent();
|
||||
let details = display.createDetailsForIndex(index, detailsWidth, -1);
|
||||
let details = display.createDetailsForIndex(index);
|
||||
detailPane.content.append(details, Big.BoxPackFlags.EXPAND);
|
||||
detailPane.open();
|
||||
} else {
|
||||
@ -170,17 +205,16 @@ function createPaneForDetails(dash, display, detailsWidth) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function ResultPane(dash, detailsWidth) {
|
||||
this._init(dash, detailsWidth);
|
||||
function ResultPane(dash) {
|
||||
this._init(dash);
|
||||
}
|
||||
|
||||
ResultPane.prototype = {
|
||||
__proto__: Pane.prototype,
|
||||
|
||||
_init: function(dash, detailsWidth) {
|
||||
_init: function(dash) {
|
||||
Pane.prototype._init.call(this);
|
||||
this._dash = dash;
|
||||
this._detailsWidth = detailsWidth;
|
||||
},
|
||||
|
||||
// Create an instance of displayClass and pack it into this pane's
|
||||
@ -188,7 +222,7 @@ ResultPane.prototype = {
|
||||
packResults: function(displayClass, enableNavigation) {
|
||||
let resultArea = new ResultArea(displayClass, enableNavigation);
|
||||
|
||||
createPaneForDetails(this._dash, resultArea.display, this._detailsWidth);
|
||||
createPaneForDetails(this._dash, resultArea.display);
|
||||
|
||||
this.content.append(resultArea.actor, Big.BoxPackFlags.EXPAND);
|
||||
this.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||
@ -204,33 +238,117 @@ function SearchEntry() {
|
||||
|
||||
SearchEntry.prototype = {
|
||||
_init : function() {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
background_color: DASH_SEARCH_BG_COLOR,
|
||||
corner_radius: 4,
|
||||
spacing: DEFAULT_PADDING,
|
||||
padding: DEFAULT_PADDING
|
||||
});
|
||||
|
||||
let icon = new Gio.ThemedIcon({ name: 'gtk-find' });
|
||||
let searchIconTexture = Shell.TextureCache.get_default().load_gicon(icon, 16);
|
||||
this.actor.append(searchIconTexture, Big.BoxPackFlags.NONE);
|
||||
this.actor = new Big.Box({ padding: DEFAULT_PADDING,
|
||||
border_bottom: SECTION_BORDER,
|
||||
border_color: SEARCH_BORDER_BOTTOM_COLOR,
|
||||
corner_radius: DASH_CORNER_RADIUS,
|
||||
reactive: true });
|
||||
let box = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.append(box, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.connect('button-press-event', Lang.bind(this, function () {
|
||||
this._resetTextState(true);
|
||||
return false;
|
||||
}));
|
||||
|
||||
this.pane = null;
|
||||
|
||||
// We need to initialize the text for the entry to have the cursor displayed
|
||||
// in it. See http://bugzilla.openedhand.com/show_bug.cgi?id=1365
|
||||
this.entry = new Clutter.Text({ font_name: "Sans 14px",
|
||||
editable: true,
|
||||
activatable: true,
|
||||
singleLineMode: true,
|
||||
text: ""
|
||||
});
|
||||
this.actor.append(this.entry, Big.BoxPackFlags.EXPAND);
|
||||
this._defaultText = _("Find...");
|
||||
|
||||
let textProperties = { font_name: "Sans 16px" };
|
||||
let entryProperties = { editable: true,
|
||||
activatable: true,
|
||||
single_line_mode: true,
|
||||
color: SEARCH_TEXT_COLOR,
|
||||
cursor_color: SEARCH_CURSOR_COLOR };
|
||||
Lang.copyProperties(textProperties, entryProperties);
|
||||
this.entry = new Clutter.Text(entryProperties);
|
||||
|
||||
this.entry.connect('notify::text', Lang.bind(this, function () {
|
||||
this._resetTextState(false);
|
||||
}));
|
||||
box.append(this.entry, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
// Mark as editable just to get a cursor
|
||||
let defaultTextProperties = { ellipsize: Pango.EllipsizeMode.END,
|
||||
text: this._defaultText,
|
||||
editable: true,
|
||||
color: TEXT_COLOR,
|
||||
cursor_visible: false,
|
||||
single_line_mode: true };
|
||||
Lang.copyProperties(textProperties, defaultTextProperties);
|
||||
this._defaultText = new Clutter.Text(defaultTextProperties);
|
||||
box.add_actor(this._defaultText);
|
||||
this.entry.connect('notify::allocation', Lang.bind(this, function () {
|
||||
this._repositionDefaultText();
|
||||
}));
|
||||
|
||||
this._iconBox = new Big.Box({ x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
padding_right: 4 });
|
||||
box.append(this._iconBox, Big.BoxPackFlags.END);
|
||||
|
||||
let global = Shell.Global.get();
|
||||
let magnifierUri = "file://" + global.imagedir + "magnifier.svg";
|
||||
this._magnifierIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
magnifierUri, 18, 18);
|
||||
let closeUri = "file://" + global.imagedir + "close-black.svg";
|
||||
this._closeIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
closeUri, 18, 18);
|
||||
this._closeIcon.reactive = true;
|
||||
this._closeIcon.connect('button-press-event', Lang.bind(this, function () {
|
||||
// Resetting this.entry.text will trigger notify::text signal which will
|
||||
// result in this._resetTextState() being called, but we should not rely
|
||||
// on that not short-circuiting if the text was already empty, so we call
|
||||
// this._resetTextState() explicitly in that case.
|
||||
if (this.entry.text == '')
|
||||
this._resetTextState(false);
|
||||
else
|
||||
this.entry.text = '';
|
||||
|
||||
// Return true to stop the signal emission, so that this.actor doesn't get
|
||||
// the button-press-event and re-highlight itself.
|
||||
return true;
|
||||
}));
|
||||
this._repositionDefaultText();
|
||||
this._resetTextState();
|
||||
},
|
||||
|
||||
setPane: function (pane) {
|
||||
this._pane = pane;
|
||||
},
|
||||
|
||||
reset: function () {
|
||||
this.entry.text = '';
|
||||
},
|
||||
|
||||
getText: function () {
|
||||
return this.entry.text;
|
||||
},
|
||||
|
||||
_resetTextState: function (searchEntryClicked) {
|
||||
let text = this.getText();
|
||||
this._iconBox.remove_all();
|
||||
// We highlight the search box if the user starts typing in it
|
||||
// or just clicks in it to indicate that the search is active.
|
||||
if (text != '' || searchEntryClicked) {
|
||||
if (!searchEntryClicked)
|
||||
this._defaultText.hide();
|
||||
this._iconBox.append(this._closeIcon, Big.BoxPackFlags.NONE);
|
||||
this.actor.background_color = HIGHLIGHTED_SEARCH_BACKGROUND_COLOR;
|
||||
this.entry.cursor_color = HIGHLIGHTED_SEARCH_CURSOR_COLOR;
|
||||
} else {
|
||||
this._defaultText.show();
|
||||
this._iconBox.append(this._magnifierIcon, Big.BoxPackFlags.NONE);
|
||||
this.actor.background_color = BACKGROUND_COLOR;
|
||||
this.entry.cursor_color = SEARCH_CURSOR_COLOR;
|
||||
}
|
||||
},
|
||||
|
||||
_repositionDefaultText: function () {
|
||||
// Offset a little to show the cursor
|
||||
this._defaultText.set_position(this.entry.x + 4, this.entry.y);
|
||||
this._defaultText.set_size(this.entry.width, this.entry.height);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(SearchEntry.prototype);
|
||||
@ -242,22 +360,21 @@ function MoreLink() {
|
||||
MoreLink.prototype = {
|
||||
_init : function () {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
padding_right: DEFAULT_PADDING,
|
||||
padding_left: DEFAULT_PADDING,
|
||||
padding_right: DEFAULT_PADDING });
|
||||
let global = Shell.Global.get();
|
||||
let inactiveUri = "file://" + global.imagedir + "view-more.svg";
|
||||
let activeUri = "file://" + global.imagedir + "view-more-activated.svg";
|
||||
this._inactiveIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
inactiveUri, 29, 18);
|
||||
this._activeIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||
activeUri, 29, 18);
|
||||
this._iconBox = new Big.Box({ reactive: true });
|
||||
this._iconBox.append(this._inactiveIcon, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(this._iconBox, Big.BoxPackFlags.END);
|
||||
|
||||
reactive: true,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
border_left: SECTION_BORDER,
|
||||
border_color: SECTION_BORDER_COLOR });
|
||||
this.pane = null;
|
||||
|
||||
this._iconBox.connect('button-press-event', Lang.bind(this, function (b, e) {
|
||||
let text = new Clutter.Text({ font_name: "Sans 12px",
|
||||
color: BRIGHT_TEXT_COLOR,
|
||||
text: _("Browse") });
|
||||
this.actor.append(text, Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.connect('button-press-event', Lang.bind(this, function (b, e) {
|
||||
if (this.pane == null) {
|
||||
// Ensure the pane is created; the activated handler will call setPane
|
||||
this.emit('activated');
|
||||
@ -270,41 +387,131 @@ MoreLink.prototype = {
|
||||
setPane: function (pane) {
|
||||
this._pane = pane;
|
||||
this._pane.connect('open-state-changed', Lang.bind(this, function(pane, isOpen) {
|
||||
this._iconBox.remove_all();
|
||||
this._iconBox.append(isOpen ? this._activeIcon : this._inactiveIcon,
|
||||
Big.BoxPackFlags.NONE);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Signals.addSignalMethods(MoreLink.prototype);
|
||||
|
||||
function SectionHeader(title) {
|
||||
this._init(title);
|
||||
function SectionHeader(title, suppressBrowse) {
|
||||
this._init(title, suppressBrowse);
|
||||
}
|
||||
|
||||
SectionHeader.prototype = {
|
||||
_init : function (title) {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
let text = new Clutter.Text({ color: DASH_SECTION_COLOR,
|
||||
font_name: "Sans Bold 10px",
|
||||
text: title });
|
||||
this.moreLink = new MoreLink();
|
||||
this.actor.append(text, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.append(this.moreLink.actor, Big.BoxPackFlags.END);
|
||||
_init : function (title, suppressBrowse) {
|
||||
this.actor = new Big.Box({ border: SECTION_BORDER,
|
||||
border_color: SECTION_BORDER_COLOR });
|
||||
this._innerBox = new Big.Box({ border: SECTION_BORDER,
|
||||
border_color: SECTION_INNER_BORDER_COLOR,
|
||||
padding_left: DEFAULT_PADDING,
|
||||
padding_right: DEFAULT_PADDING,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_SPACING });
|
||||
this.actor.append(this._innerBox, Big.BoxPackFlags.EXPAND);
|
||||
let backgroundGradient = Shell.create_vertical_gradient(SECTION_BACKGROUND_TOP_COLOR,
|
||||
SECTION_BACKGROUND_BOTTOM_COLOR);
|
||||
this._innerBox.add_actor(backgroundGradient);
|
||||
this._innerBox.connect('notify::allocation', Lang.bind(this, function (actor) {
|
||||
let [width, height] = actor.get_size();
|
||||
backgroundGradient.set_size(width, height);
|
||||
}));
|
||||
|
||||
let textBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
padding_top: DEFAULT_PADDING,
|
||||
padding_bottom: DEFAULT_PADDING });
|
||||
this.text = new Clutter.Text({ color: TEXT_COLOR,
|
||||
font_name: "Sans Bold 12px",
|
||||
text: title });
|
||||
textBox.append(this.text, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._innerBox.append(textBox, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
if (!suppressBrowse) {
|
||||
this.moreLink = new MoreLink();
|
||||
this._innerBox.append(this.moreLink.actor, Big.BoxPackFlags.END);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Dash(displayGridColumnWidth) {
|
||||
this._init(displayGridColumnWidth);
|
||||
function SearchSectionHeader(title, onClick) {
|
||||
this._init(title, onClick);
|
||||
}
|
||||
|
||||
SearchSectionHeader.prototype = {
|
||||
_init : function(title, onClick) {
|
||||
let box = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
padding_top: DASH_SECTION_PADDING,
|
||||
padding_bottom: DASH_SECTION_PADDING,
|
||||
spacing: DEFAULT_SPACING });
|
||||
let titleText = new Clutter.Text({ color: BRIGHTER_TEXT_COLOR,
|
||||
font_name: 'Sans Bold 12px',
|
||||
text: title });
|
||||
this.tooltip = new Clutter.Text({ color: BRIGHTER_TEXT_COLOR,
|
||||
font_name: 'Sans 12px',
|
||||
text: _("(see all)") });
|
||||
this.countText = new Clutter.Text({ color: BRIGHTER_TEXT_COLOR,
|
||||
font_name: 'Sans Bold 14px' });
|
||||
|
||||
box.append(titleText, Big.BoxPackFlags.NONE);
|
||||
box.append(this.tooltip, Big.BoxPackFlags.NONE);
|
||||
box.append(this.countText, Big.BoxPackFlags.END);
|
||||
|
||||
this.tooltip.hide();
|
||||
this._showTooltip = true;
|
||||
|
||||
let button = new Button.Button(box, PRELIGHT_COLOR, BACKGROUND_COLOR,
|
||||
TEXT_COLOR, false, null);
|
||||
button.button.height = box.height;
|
||||
button.button.padding_left = DEFAULT_PADDING;
|
||||
button.button.padding_right = DEFAULT_PADDING;
|
||||
|
||||
button.button.connect('button-release-event', onClick);
|
||||
button.connect('enter-event', Lang.bind(this, this._onButtonEntered));
|
||||
button.connect('leave-event', Lang.bind(this, this._onButtonLeft));
|
||||
this.actor = button.button;
|
||||
},
|
||||
|
||||
_onButtonEntered : function() {
|
||||
if (this._showTooltip)
|
||||
this.tooltip.show();
|
||||
},
|
||||
|
||||
_onButtonLeft : function() {
|
||||
this.tooltip.hide();
|
||||
},
|
||||
|
||||
setShowTooltip : function(showTooltip) {
|
||||
this._showTooltip = showTooltip;
|
||||
// Because we only show tooltip on mouse-over,
|
||||
// we should not just show it here if showTooltip is
|
||||
// set to true, but in the future we could check if
|
||||
// the mouse happens to be over the header and show it
|
||||
// in that case.
|
||||
if (!this._showTooltip)
|
||||
this.tooltip.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function Section(titleString, suppressBrowse) {
|
||||
this._init(titleString, suppressBrowse);
|
||||
}
|
||||
|
||||
Section.prototype = {
|
||||
_init: function(titleString, suppressBrowse) {
|
||||
this.actor = new Big.Box({ spacing: SECTION_INNER_SPACING });
|
||||
this.header = new SectionHeader(titleString, suppressBrowse);
|
||||
this.actor.append(this.header.actor, Big.BoxPackFlags.NONE);
|
||||
this.content = new Big.Box({spacing: SECTION_INNER_SPACING });
|
||||
this.actor.append(this.content, Big.BoxPackFlags.EXPAND);
|
||||
}
|
||||
}
|
||||
|
||||
function Dash() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Dash.prototype = {
|
||||
_init : function(displayGridColumnWidth) {
|
||||
this._width = displayGridColumnWidth;
|
||||
|
||||
this._detailsWidth = displayGridColumnWidth * 2;
|
||||
|
||||
_init : function() {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
// dash and the popup panes need to be reactive so that the clicks in unoccupied places on them
|
||||
@ -316,82 +523,83 @@ 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 Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
width: this._width,
|
||||
padding: DEFAULT_PADDING,
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
background_color: BACKGROUND_COLOR,
|
||||
corner_radius: DASH_CORNER_RADIUS,
|
||||
padding_left: DASH_PADDING_SIDE,
|
||||
padding_right: DASH_PADDING_SIDE,
|
||||
reactive: true });
|
||||
|
||||
this.dashContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: DASH_SECTION_SPACING });
|
||||
this.actor.append(this.dashContainer, Big.BoxPackFlags.EXPAND);
|
||||
// Size for this one explicitly set from overlay.js
|
||||
this.searchArea = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
||||
|
||||
this.sectionArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: DASH_SECTION_SPACING });
|
||||
|
||||
this.actor.append(this.searchArea, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(this.sectionArea, Big.BoxPackFlags.NONE);
|
||||
|
||||
// The currently active popup display
|
||||
this._activePane = null;
|
||||
|
||||
/***** Search *****/
|
||||
|
||||
this._searchPane = null;
|
||||
this._searchActive = false;
|
||||
this._searchEntry = new SearchEntry();
|
||||
this.dashContainer.append(this._searchEntry.actor, Big.BoxPackFlags.NONE);
|
||||
this.searchArea.append(this._searchEntry.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._searchAreaApps = null;
|
||||
this._searchAreaDocs = null;
|
||||
|
||||
this._searchQueued = false;
|
||||
this._searchTimeoutId = 0;
|
||||
this._searchEntry.entry.connect('text-changed', Lang.bind(this, function (se, prop) {
|
||||
this._searchActive = this._searchEntry.text != '';
|
||||
if (this._searchQueued)
|
||||
let text = this._searchEntry.getText();
|
||||
text = text.replace(/^\s+/g, "").replace(/\s+$/g, "")
|
||||
this._searchActive = text != '';
|
||||
this._updateDashActors();
|
||||
if (!this._searchActive) {
|
||||
if (this._searchTimeoutId > 0) {
|
||||
Mainloop.source_remove(this._searchTimeoutId);
|
||||
this._searchTimeoutId = 0;
|
||||
}
|
||||
return;
|
||||
if (this._searchPane == null) {
|
||||
this._searchPane = new ResultPane(this, this._detailsWidth);
|
||||
this._searchPane.content.append(new Clutter.Text({ color: DASH_SECTION_COLOR,
|
||||
font_name: 'Sans Bold 10px',
|
||||
text: "APPLICATIONS" }),
|
||||
Big.BoxPackFlags.NONE);
|
||||
this._searchAreaApps = this._searchPane.packResults(AppDisplay.AppDisplay, false);
|
||||
this._searchPane.content.append(new Clutter.Text({ color: DASH_SECTION_COLOR,
|
||||
font_name: 'Sans Bold 10px',
|
||||
text: "RECENT DOCUMENTS" }),
|
||||
Big.BoxPackFlags.NONE);
|
||||
this._searchAreaDocs = this._searchPane.packResults(DocDisplay.DocDisplay, false);
|
||||
this._addPane(this._searchPane);
|
||||
this._searchEntry.setPane(this._searchPane);
|
||||
}
|
||||
this._searchQueued = true;
|
||||
Mainloop.timeout_add(250, Lang.bind(this, function() {
|
||||
// Strip leading and trailing whitespace
|
||||
let text = this._searchEntry.entry.text.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
||||
this._searchQueued = false;
|
||||
this._searchAreaApps.setSearch(text);
|
||||
this._searchAreaDocs.setSearch(text);
|
||||
if (text == '')
|
||||
this._searchPane.close();
|
||||
else
|
||||
this._searchPane.open();
|
||||
if (this._searchTimeoutId > 0)
|
||||
return;
|
||||
this._searchTimeoutId = Mainloop.timeout_add(150, Lang.bind(this, function() {
|
||||
this._searchTimeoutId = 0;
|
||||
let text = this._searchEntry.getText();
|
||||
text = text.replace(/^\s+/g, "").replace(/\s+$/g, "");
|
||||
this._appSearchResultArea.display.setSearch(text);
|
||||
this._docSearchResultArea.display.setSearch(text);
|
||||
|
||||
this._appSearchHeader.countText.text = this._appSearchResultArea.display.getMatchedItemsCount() + "";
|
||||
this._docSearchHeader.countText.text = this._docSearchResultArea.display.getMatchedItemsCount() + "";
|
||||
|
||||
return false;
|
||||
}));
|
||||
}));
|
||||
this._searchEntry.entry.connect('activate', Lang.bind(this, function (se) {
|
||||
// only one of the displays will have an item selected, so it's ok to
|
||||
// call activateSelected() on all of them
|
||||
this._searchAreaApps.activateSelected();
|
||||
this._searchAreaDocs.activateSelected();
|
||||
this._appSearchResultArea.display.activateSelected();
|
||||
this._docSearchResultArea.display.activateSelected();
|
||||
return true;
|
||||
}));
|
||||
this._searchEntry.entry.connect('key-press-event', Lang.bind(this, function (se, e) {
|
||||
let text = this._searchEntry.getText();
|
||||
let symbol = Shell.get_event_key_symbol(e);
|
||||
if (symbol == Clutter.Escape) {
|
||||
// Escape will keep clearing things back to the desktop. First, if
|
||||
// we have active text, we remove it.
|
||||
if (this._searchEntry.entry.text != '')
|
||||
this._searchEntry.entry.text = '';
|
||||
// Escape will keep clearing things back to the desktop.
|
||||
// If we are showing a particular section of search, go back to all sections.
|
||||
if (this._getOnlyAppSearchShown() || this._getOnlyDocSearchShown())
|
||||
this._showAllSearchSections();
|
||||
// If we have an active search, we remove it.
|
||||
else if (this._searchActive)
|
||||
this._searchEntry.reset();
|
||||
// Next, if we're in one of the "more" modes or showing the details pane, close them
|
||||
else if (this._activePane != null)
|
||||
this._activePane.close();
|
||||
// Finally, just close the overlay entirely
|
||||
// Finally, just close the Overview entirely
|
||||
else
|
||||
Main.overlay.hide();
|
||||
Main.overview.hide();
|
||||
return true;
|
||||
} else if (symbol == Clutter.Up) {
|
||||
if (!this._searchActive)
|
||||
@ -400,22 +608,22 @@ Dash.prototype = {
|
||||
// too, but there doesn't seem to be any flickering if we first select
|
||||
// something in one display, but then unset the selection, and move
|
||||
// it to the other display, so it's ok to do that.
|
||||
if (this._searchAreaDocs.hasSelected())
|
||||
this._searchAreaDocs.selectUp();
|
||||
else if (this._searchAreaApps.hasItems())
|
||||
this._searchAreaApps.selectUp();
|
||||
if (this._docSearchResultArea.display.hasSelected())
|
||||
this._docSearchResultArea.display.selectUp();
|
||||
else if (this._appSearchResultArea.display.hasItems())
|
||||
this._appSearchResultArea.display.selectUp();
|
||||
else
|
||||
this._searchAreaDocs.selectUp();
|
||||
this._docSearchResultArea.display.selectUp();
|
||||
return true;
|
||||
} else if (symbol == Clutter.Down) {
|
||||
if (!this._searchActive)
|
||||
return true;
|
||||
if (this._searchAreaDocs.hasSelected())
|
||||
this._searchAreaDocs.selectDown();
|
||||
else if (this._searchAreaApps.hasItems())
|
||||
this._searchAreaApps.selectDown();
|
||||
if (this._docSearchResultArea.display.hasSelected())
|
||||
this._docSearchResultArea.display.selectDown();
|
||||
else if (this._appSearchResultArea.display.hasItems())
|
||||
this._appSearchResultArea.display.selectDown();
|
||||
else
|
||||
this._searchAreaDocs.selectDown();
|
||||
this._docSearchResultArea.display.selectDown();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -423,64 +631,80 @@ Dash.prototype = {
|
||||
|
||||
/***** Applications *****/
|
||||
|
||||
let appsHeader = new SectionHeader("APPLICATIONS");
|
||||
this._appsSection = new Big.Box({ spacing: DEFAULT_PADDING });
|
||||
this._appsSection.append(appsHeader.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._appsContent = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
|
||||
this._appsSection.append(this._appsContent, Big.BoxPackFlags.EXPAND);
|
||||
this._appWell = new AppDisplay.AppWell();
|
||||
this._appsContent.append(this._appWell.actor, Big.BoxPackFlags.EXPAND);
|
||||
this._appsSection = new Section(_("APPLICATIONS"));
|
||||
let appWell = new AppDisplay.AppWell();
|
||||
this._appsSection.content.append(appWell.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._moreAppsPane = null;
|
||||
appsHeader.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||
this._appsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||
if (this._moreAppsPane == null) {
|
||||
this._moreAppsPane = new ResultPane(this, this._detailsWidth);
|
||||
this._moreAppsPane = new ResultPane(this);
|
||||
this._moreAppsPane.packResults(AppDisplay.AppDisplay, true);
|
||||
this._addPane(this._moreAppsPane);
|
||||
link.setPane(this._moreAppsPane);
|
||||
}
|
||||
}));
|
||||
|
||||
this.dashContainer.append(this._appsSection, Big.BoxPackFlags.NONE);
|
||||
this.sectionArea.append(this._appsSection.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
/***** Places *****/
|
||||
|
||||
let placesSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: DEFAULT_PADDING });
|
||||
let placesHeader = new SectionHeader("PLACES");
|
||||
placesSection.append(placesHeader.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
/* Translators: This is in the sense of locations for documents,
|
||||
network locations, etc. */
|
||||
this._placesSection = new Section(_("PLACES"), true);
|
||||
let placesDisplay = new Places.Places();
|
||||
placesSection.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this.dashContainer.append(placesSection, Big.BoxPackFlags.NONE);
|
||||
this._placesSection.content.append(placesDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||
this.sectionArea.append(this._placesSection.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
/***** Documents *****/
|
||||
|
||||
this._docsSection = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: DEFAULT_PADDING });
|
||||
this._docsSection = new Section(_("RECENT DOCUMENTS"));
|
||||
|
||||
let docDisplay = new DocDisplay.DashDocDisplay();
|
||||
this._docsSection.content.append(docDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._moreDocsPane = null;
|
||||
|
||||
let docsHeader = new SectionHeader("RECENT DOCUMENTS");
|
||||
this._docsSection.append(docsHeader.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._docDisplay = new DocDisplay.DocDisplay();
|
||||
this._docDisplay.load();
|
||||
this._docsSection.append(this._docDisplay.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
createPaneForDetails(this, this._docDisplay, this._detailsWidth);
|
||||
|
||||
docsHeader.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||
this._docsSection.header.moreLink.connect('activated', Lang.bind(this, function (link) {
|
||||
if (this._moreDocsPane == null) {
|
||||
this._moreDocsPane = new ResultPane(this, this._detailsWidth);
|
||||
this._moreDocsPane = new ResultPane(this);
|
||||
this._moreDocsPane.packResults(DocDisplay.DocDisplay, true);
|
||||
this._addPane(this._moreDocsPane);
|
||||
link.setPane(this._moreDocsPane);
|
||||
}
|
||||
}));
|
||||
|
||||
this.dashContainer.append(this._docsSection, Big.BoxPackFlags.EXPAND);
|
||||
this.sectionArea.append(this._docsSection.actor, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
/***** Search Results *****/
|
||||
|
||||
this._searchResultsSection = new Section(_("SEARCH RESULTS"), true);
|
||||
|
||||
this._appSearchHeader = new SearchSectionHeader(_("APPLICATIONS"),
|
||||
Lang.bind(this,
|
||||
function () {
|
||||
this._toggleOnlyAppSearchShown();
|
||||
return true;
|
||||
}));
|
||||
this._searchResultsSection.content.append(this._appSearchHeader.actor, Big.BoxPackFlags.NONE);
|
||||
this._appSearchResultArea = new ResultArea(AppDisplay.AppDisplay, false);
|
||||
this._appSearchResultArea.controlBox.hide();
|
||||
this._searchResultsSection.content.append(this._appSearchResultArea.actor, Big.BoxPackFlags.EXPAND);
|
||||
createPaneForDetails(this, this._appSearchResultArea.display);
|
||||
|
||||
this._docSearchHeader = new SearchSectionHeader(_("RECENT DOCUMENTS"),
|
||||
Lang.bind(this,
|
||||
function () {
|
||||
this._toggleOnlyDocSearchShown();
|
||||
return true;
|
||||
}));
|
||||
this._searchResultsSection.content.append(this._docSearchHeader.actor, Big.BoxPackFlags.NONE);
|
||||
this._docSearchResultArea = new ResultArea(DocDisplay.DocDisplay, false);
|
||||
this._docSearchResultArea.controlBox.hide();
|
||||
this._searchResultsSection.content.append(this._docSearchResultArea.actor, Big.BoxPackFlags.EXPAND);
|
||||
createPaneForDetails(this, this._docSearchResultArea.display);
|
||||
|
||||
this.sectionArea.append(this._searchResultsSection.actor, Big.BoxPackFlags.EXPAND);
|
||||
this._searchResultsSection.actor.hide();
|
||||
},
|
||||
|
||||
show: function() {
|
||||
@ -490,8 +714,7 @@ Dash.prototype = {
|
||||
|
||||
hide: function() {
|
||||
this._firstSelectAfterOverlayShow = true;
|
||||
if (this._searchEntry.entry.text != '')
|
||||
this._searchEntry.entry.text = '';
|
||||
this._searchEntry.reset();
|
||||
if (this._activePane != null)
|
||||
this._activePane.close();
|
||||
},
|
||||
@ -512,7 +735,85 @@ Dash.prototype = {
|
||||
this._activePane = null;
|
||||
}
|
||||
}));
|
||||
Main.overlay.addPane(pane);
|
||||
Main.overview.addPane(pane);
|
||||
},
|
||||
|
||||
_updateDashActors: function() {
|
||||
if (!this._searchActive && this._searchResultsSection.actor.visible) {
|
||||
this._showAllSearchSections();
|
||||
this._searchResultsSection.actor.hide();
|
||||
this._appsSection.actor.show();
|
||||
this._placesSection.actor.show();
|
||||
this._docsSection.actor.show();
|
||||
} else if (this._searchActive && !this._searchResultsSection.actor.visible) {
|
||||
this._searchResultsSection.actor.show();
|
||||
this._appsSection.actor.hide();
|
||||
this._placesSection.actor.hide();
|
||||
this._docsSection.actor.hide();
|
||||
}
|
||||
},
|
||||
|
||||
_toggleOnlyAppSearchShown: function() {
|
||||
if (this._getOnlyAppSearchShown()) {
|
||||
this._setDocSearchShown(true);
|
||||
} else {
|
||||
this._setDocSearchShown(false);
|
||||
}
|
||||
},
|
||||
|
||||
_toggleOnlyDocSearchShown: function() {
|
||||
if (this._getOnlyDocSearchShown()) {
|
||||
this._setAppSearchShown(true);
|
||||
} else {
|
||||
this._setAppSearchShown(false);
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: the following two functions currently rely on us showing the
|
||||
// section header even if there are no results in that section. We'll need
|
||||
// to change the check if we update that behavior. We'll also need to change
|
||||
// the check if we add more sections to search results.
|
||||
_getOnlyAppSearchShown: function() {
|
||||
return this._searchActive && !this._docSearchHeader.actor.visible;
|
||||
},
|
||||
|
||||
_getOnlyDocSearchShown: function() {
|
||||
return this._searchActive && !this._appSearchHeader.actor.visible;
|
||||
},
|
||||
|
||||
_setAppSearchShown: function(show) {
|
||||
if (show) {
|
||||
this._appSearchHeader.actor.show();
|
||||
this._appSearchResultArea.actor.show();
|
||||
this._docSearchResultArea.display.displayPage(0);
|
||||
this._docSearchResultArea.controlBox.hide();
|
||||
this._docSearchHeader.setShowTooltip(true);
|
||||
} else {
|
||||
this._appSearchHeader.actor.hide();
|
||||
this._appSearchResultArea.actor.hide();
|
||||
this._docSearchResultArea.controlBox.show();
|
||||
this._docSearchHeader.setShowTooltip(false);
|
||||
}
|
||||
},
|
||||
|
||||
_setDocSearchShown: function(show) {
|
||||
if (show) {
|
||||
this._docSearchHeader.actor.show();
|
||||
this._docSearchResultArea.actor.show();
|
||||
this._appSearchResultArea.display.displayPage(0);
|
||||
this._appSearchResultArea.controlBox.hide();
|
||||
this._appSearchHeader.setShowTooltip(true);
|
||||
} else {
|
||||
this._docSearchHeader.actor.hide();
|
||||
this._docSearchResultArea.actor.hide();
|
||||
this._appSearchResultArea.controlBox.show();
|
||||
this._appSearchHeader.setShowTooltip(false);
|
||||
}
|
||||
},
|
||||
|
||||
_showAllSearchSections: function() {
|
||||
this._setAppSearchShown(true);
|
||||
this._setDocSearchShown(true);
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Dash.prototype);
|
||||
|
15
js/ui/dnd.js
15
js/ui/dnd.js
@ -82,10 +82,21 @@ _Draggable.prototype = {
|
||||
// Drag actor does not always have to be the same as actor. For example drag actor
|
||||
// can be an image that's part of the actor. So to perform "snap back" correctly we need
|
||||
// to know what was the drag actor source.
|
||||
if (this.actor._delegate.getDragActorSource)
|
||||
if (this.actor._delegate.getDragActorSource) {
|
||||
this._dragActorSource = this.actor._delegate.getDragActorSource();
|
||||
else
|
||||
// If the user dragged from the source, then position
|
||||
// the dragActor over it. Otherwise, center it
|
||||
// around the pointer
|
||||
let [sourceX, sourceY] = this._dragActorSource.get_transformed_position();
|
||||
let [sourceWidth, sourceHeight] = this._dragActorSource.get_transformed_size();
|
||||
if (stageX > sourceX && stageX <= sourceX + sourceWidth &&
|
||||
stageY > sourceY && stageY <= sourceY + sourceHeight)
|
||||
this._dragActor.set_position(sourceX, sourceY);
|
||||
else
|
||||
this._dragActor.set_position(stageX - this._dragActor.width / 2, stageY - this._dragActor.height / 2);
|
||||
} else {
|
||||
this._dragActorSource = this.actor;
|
||||
}
|
||||
this._dragOrigParent = undefined;
|
||||
this._ungrabActor(actor);
|
||||
this._grabActor(this._dragActor);
|
||||
|
@ -1,17 +1,24 @@
|
||||
/* -*- 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 Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Mainloop = imports.mainloop;
|
||||
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
const DND = imports.ui.dnd;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
const DASH_DOCS_ICON_SIZE = 16;
|
||||
|
||||
const DEFAULT_SPACING = 4;
|
||||
|
||||
/* This class represents a single display item containing information about a document.
|
||||
* We take the current number of seconds in the constructor to avoid looking up the current
|
||||
* time for every item when they are created in a batch.
|
||||
@ -68,17 +75,30 @@ 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(availableWidth, availableHeight) {
|
||||
_createLargePreviewIcon : function() {
|
||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
|
||||
return null;
|
||||
|
||||
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
|
||||
this._docInfo.uri, availableWidth, availableHeight);
|
||||
try {
|
||||
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
|
||||
this._docInfo.uri, -1, -1);
|
||||
} catch (e) {
|
||||
// An exception will be raised when the image format isn't know
|
||||
/* FIXME: http://bugzilla.gnome.org/show_bug.cgi?id=591480: should
|
||||
* only ignore GDK_PIXBUF_ERROR_UNKNOWN_TYPE. */
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
//// Drag and Drop ////
|
||||
|
||||
shellWorkspaceLaunch: function() {
|
||||
this.launch();
|
||||
},
|
||||
|
||||
//// Private Methods ////
|
||||
|
||||
// Updates the last visited time displayed in the description text for the item.
|
||||
// Updates the last visited time displayed in the description text for the item.
|
||||
_resetTimeDisplay: function(currentSecs) {
|
||||
let lastSecs = this._docInfo.timestamp;
|
||||
let timeDelta = currentSecs - lastSecs;
|
||||
@ -110,11 +130,11 @@ DocDisplay.prototype = {
|
||||
this._updateTimeoutTargetTime = -1;
|
||||
this._updateTimeoutId = 0;
|
||||
|
||||
this._docManager = DocInfo.getDocManager(GenericDisplay.ITEM_DISPLAY_ICON_SIZE);
|
||||
this._docManager = DocInfo.getDocManager();
|
||||
this._docsStale = true;
|
||||
this._docManager.connect('changed', function(mgr, userData) {
|
||||
me._docsStale = true;
|
||||
// Changes in local recent files should not happen when we are in the overlay mode,
|
||||
// Changes in local recent files should not happen when we are in the Overview mode,
|
||||
// but redisplaying right away is cool when we use Zephyr.
|
||||
// Also, we might be displaying remote documents, like Google Docs, in the future
|
||||
// which might be edited by someone else.
|
||||
@ -148,7 +168,7 @@ DocDisplay.prototype = {
|
||||
// we should do the sorting manually because we want the order to be based on last visited.
|
||||
//
|
||||
// This function is called each time the search string is set back to '' or we display
|
||||
// the overlay, so we are doing the sorting over the same items multiple times if the list
|
||||
// the Overview, so we are doing the sorting over the same items multiple times if the list
|
||||
// of recent items didn't change. We could store an additional array of doc ids and sort
|
||||
// them once when they are returned by this._recentManager.get_items() to avoid having to do
|
||||
// this sorting each time, but the sorting seems to be very fast anyway, so there is no need
|
||||
@ -236,3 +256,183 @@ DocDisplay.prototype = {
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(DocDisplay.prototype);
|
||||
|
||||
function DashDocDisplayItem(docInfo) {
|
||||
this._init(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 () {
|
||||
docInfo.launch();
|
||||
Main.overview.hide();
|
||||
}));
|
||||
|
||||
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 Clutter.Text({ font_name: "Sans 14px",
|
||||
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: docInfo.name });
|
||||
this.actor.append(name, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
this.actor._delegate = this;
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._icon;
|
||||
},
|
||||
|
||||
getDragActor: function(stageX, stageY) {
|
||||
this.dragActor = this._info.createIcon(DASH_DOCS_ICON_SIZE);
|
||||
return this.dragActor;
|
||||
},
|
||||
|
||||
//// Drag and drop functions ////
|
||||
|
||||
shellWorkspaceLaunch: function () {
|
||||
this._info.launch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to display two column recent documents in the dash
|
||||
*/
|
||||
function DashDocDisplay() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
DashDocDisplay.prototype = {
|
||||
_init: function() {
|
||||
this.actor = new Shell.GenericContainer();
|
||||
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._docManager = DocInfo.getDocManager();
|
||||
this._docManager.connect('changed', Lang.bind(this, function(mgr) {
|
||||
this._redisplay();
|
||||
}));
|
||||
this._redisplay();
|
||||
},
|
||||
|
||||
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||
let children = actor.get_children();
|
||||
|
||||
// We use two columns maximum. Just take the min and natural size of the
|
||||
// first two items, even though strictly speaking it's not correct; we'd
|
||||
// need to calculate how many items we could fit for the height, then
|
||||
// take the biggest preferred width for each column.
|
||||
// In practice the dash gets a fixed width anyways.
|
||||
|
||||
// If we have one child, add its minimum and natural size
|
||||
if (children.length > 0) {
|
||||
let [minSize, naturalSize] = children[0].get_preferred_width(forHeight);
|
||||
alloc.min_size += minSize;
|
||||
alloc.natural_size += naturalSize;
|
||||
}
|
||||
// If we have two, add its size, plus DEFAULT_SPACING
|
||||
if (children.length > 1) {
|
||||
let [minSize, naturalSize] = children[1].get_preferred_width(forHeight);
|
||||
alloc.min_size += DEFAULT_SPACING + minSize;
|
||||
alloc.natural_size += DEFAULT_SPACING + naturalSize;
|
||||
}
|
||||
},
|
||||
|
||||
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||
let children = actor.get_children();
|
||||
|
||||
// Two columns, where we go vertically down first. So just take
|
||||
// the height of half of the children as our preferred height.
|
||||
|
||||
let firstColumnChildren = children.length / 2;
|
||||
|
||||
alloc.min_size = 0;
|
||||
for (let i = 0; i < firstColumnChildren; i++) {
|
||||
let child = children[i];
|
||||
let [minSize, naturalSize] = child.get_preferred_height(forWidth);
|
||||
alloc.natural_size += naturalSize;
|
||||
|
||||
if (i > 0 && i < children.length - 1) {
|
||||
alloc.min_size += DEFAULT_SPACING;
|
||||
alloc.natural_size += DEFAULT_SPACING;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_allocate: function(actor, box, flags) {
|
||||
let width = box.x2 - box.x1;
|
||||
let height = box.y2 - box.y1;
|
||||
|
||||
let children = actor.get_children();
|
||||
|
||||
// The width of an item is our allocated width, minus spacing, divided in half.
|
||||
let itemWidth = Math.floor((width - DEFAULT_SPACING) / 2);
|
||||
let x = box.x1;
|
||||
let y = box.y1;
|
||||
let columnIndex = 0;
|
||||
let i = 0;
|
||||
// Loop over the children, going vertically down first. When we run
|
||||
// out of vertical space (our y variable is bigger than box.y2), switch
|
||||
// to the second column.
|
||||
for (; i < children.length; i++) {
|
||||
let child = children[i];
|
||||
|
||||
let [minSize, naturalSize] = child.get_preferred_height(-1);
|
||||
|
||||
if (y + naturalSize > box.y2) {
|
||||
// Is this the second column? Ok, break.
|
||||
if (columnIndex == 1) {
|
||||
break;
|
||||
}
|
||||
// Set x to the halfway point.
|
||||
columnIndex += 1;
|
||||
x = x + itemWidth + DEFAULT_SPACING;
|
||||
// And y is back to the top.
|
||||
y = box.y1;
|
||||
}
|
||||
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = y;
|
||||
childBox.x2 = childBox.x1 + itemWidth;
|
||||
childBox.y2 = y + naturalSize;
|
||||
|
||||
y = childBox.y2 + DEFAULT_SPACING;
|
||||
|
||||
child.show();
|
||||
child.allocate(childBox, flags);
|
||||
}
|
||||
|
||||
// Everything else didn't fit, just hide it.
|
||||
for (; i < children.length; i++) {
|
||||
children[i].hide();
|
||||
}
|
||||
},
|
||||
|
||||
_redisplay: function() {
|
||||
this.actor.remove_all();
|
||||
|
||||
let docs = this._docManager.getItems();
|
||||
let docUrls = [];
|
||||
for (let url in docs) {
|
||||
docUrls.push(url);
|
||||
}
|
||||
docUrls.sort(function (urlA, urlB) { return docs[urlB].timestamp - docs[urlA].timestamp; });
|
||||
let textureCache = Shell.TextureCache.get_default();
|
||||
|
||||
for (let i = 0; i < docUrls.length; i++) {
|
||||
let url = docUrls[i];
|
||||
let docInfo = docs[url];
|
||||
let display = new DashDocDisplayItem(docInfo);
|
||||
this.actor.add_actor(display.actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ const Mainloop = imports.mainloop;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Signals = imports.signals;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Tidy = imports.gi.Tidy;
|
||||
|
||||
const Button = imports.ui.button;
|
||||
const DND = imports.ui.dnd;
|
||||
@ -126,8 +125,6 @@ GenericDisplayItem.prototype = {
|
||||
// It is used for updating the description text inside the details actor when
|
||||
// the description text for the item is updated.
|
||||
this._detailsDescriptions = [];
|
||||
|
||||
this.dragActor = null;
|
||||
},
|
||||
|
||||
//// Draggable object interface ////
|
||||
@ -135,21 +132,9 @@ GenericDisplayItem.prototype = {
|
||||
// Returns a cloned texture of the item's icon to represent the item as it
|
||||
// is being dragged.
|
||||
getDragActor: function(stageX, stageY) {
|
||||
this.dragActor = this._createIcon();
|
||||
|
||||
// If the user dragged from the icon itself, then position
|
||||
// the dragActor over the original icon. Otherwise center it
|
||||
// around the pointer
|
||||
let [iconX, iconY] = this._icon.get_transformed_position();
|
||||
let [iconWidth, iconHeight] = this._icon.get_transformed_size();
|
||||
if (stageX > iconX && stageX <= iconX + iconWidth &&
|
||||
stageY > iconY && stageY <= iconY + iconHeight)
|
||||
this.dragActor.set_position(iconX, iconY);
|
||||
else
|
||||
this.dragActor.set_position(stageX - this.dragActor.width / 2, stageY - this.dragActor.height / 2);
|
||||
return this.dragActor;
|
||||
return this._createIcon();
|
||||
},
|
||||
|
||||
|
||||
// Returns the item icon, a separate copy of which is used to
|
||||
// represent the item as it is being dragged. This is used to
|
||||
// determine a snap-back location for the drag icon if it does
|
||||
@ -183,18 +168,14 @@ GenericDisplayItem.prototype = {
|
||||
/*
|
||||
* Returns an actor containing item details. In the future details can have more information than what
|
||||
* the preview pop-up has and be item-type specific.
|
||||
*
|
||||
* availableWidth - width available for displaying details
|
||||
*/
|
||||
createDetailsActor: function(availableWidth) {
|
||||
createDetailsActor: function() {
|
||||
|
||||
let details = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
spacing: PREVIEW_BOX_SPACING,
|
||||
width: availableWidth });
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
|
||||
let mainDetails = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: PREVIEW_BOX_SPACING,
|
||||
width: availableWidth });
|
||||
spacing: PREVIEW_BOX_SPACING });
|
||||
|
||||
// Inner box with name and description
|
||||
let textDetails = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
@ -216,7 +197,7 @@ GenericDisplayItem.prototype = {
|
||||
mainDetails.append(textDetails, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
let previewIcon = this._createPreviewIcon();
|
||||
let largePreviewIcon = this._createLargePreviewIcon(availableWidth, -1);
|
||||
let largePreviewIcon = this._createLargePreviewIcon();
|
||||
|
||||
if (previewIcon != null && largePreviewIcon == null) {
|
||||
mainDetails.prepend(previewIcon, Big.BoxPackFlags.NONE);
|
||||
@ -303,7 +284,7 @@ GenericDisplayItem.prototype = {
|
||||
//// Virtual protected methods ////
|
||||
|
||||
// Creates and returns a large preview icon, but only if we have a detailed image.
|
||||
_createLargePreviewIcon : function(availableWidth, availableHeight) {
|
||||
_createLargePreviewIcon : function() {
|
||||
return null;
|
||||
},
|
||||
|
||||
@ -380,13 +361,13 @@ GenericDisplay.prototype = {
|
||||
this._redisplay(true);
|
||||
},
|
||||
|
||||
// Launches the item that is currently selected, closing the overlay
|
||||
// Launches the item that is currently selected, closing the Overview
|
||||
activateSelected: function() {
|
||||
if (this._selectedIndex != -1) {
|
||||
let selected = this._findDisplayedByIndex(this._selectedIndex);
|
||||
selected.launch();
|
||||
this.unsetSelected();
|
||||
Main.overlay.hide();
|
||||
Main.overview.hide();
|
||||
}
|
||||
},
|
||||
|
||||
@ -448,6 +429,10 @@ GenericDisplay.prototype = {
|
||||
return this._list.displayedCount > 0;
|
||||
},
|
||||
|
||||
getMatchedItemsCount: function() {
|
||||
return this._matchedItems.length;
|
||||
},
|
||||
|
||||
// Load the initial state
|
||||
load: function() {
|
||||
this._redisplay(true);
|
||||
@ -465,9 +450,14 @@ GenericDisplay.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
createDetailsForIndex: function(index, width, height) {
|
||||
createDetailsForIndex: function(index) {
|
||||
let item = this._findDisplayedByIndex(index);
|
||||
return item.createDetailsActor(width, height);
|
||||
return item.createDetailsActor();
|
||||
},
|
||||
|
||||
// Displays the page specified by the pageNumber argument.
|
||||
displayPage: function(pageNumber) {
|
||||
this._list.page = pageNumber;
|
||||
},
|
||||
|
||||
//// Protected methods ////
|
||||
@ -698,11 +688,6 @@ GenericDisplay.prototype = {
|
||||
}));
|
||||
},
|
||||
|
||||
// Displays the page specified by the pageNumber argument.
|
||||
_displayPage: function(pageNumber) {
|
||||
this._list.page = pageNumber;
|
||||
},
|
||||
|
||||
/*
|
||||
* Updates the display control to reflect the matched items set and the page selected.
|
||||
*
|
||||
@ -729,7 +714,7 @@ GenericDisplay.prototype = {
|
||||
pageControl.connect('clicked',
|
||||
Lang.bind(this,
|
||||
function(o, event) {
|
||||
this._displayPage(pageNumberLocalScope);
|
||||
this.displayPage(pageNumberLocalScope);
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
|
@ -555,7 +555,7 @@ LookingGlass.prototype = {
|
||||
|
||||
Tweener.removeTweens(this.actor);
|
||||
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
let global = Shell.Global.get();
|
||||
|
@ -3,6 +3,7 @@
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gdk = imports.gi.Gdk;
|
||||
const Gio = imports.gi.Gio;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
@ -10,7 +11,7 @@ const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const Chrome = imports.ui.chrome;
|
||||
const Overlay = imports.ui.overlay;
|
||||
const Overview = imports.ui.overview;
|
||||
const Panel = imports.ui.panel;
|
||||
const RunDialog = imports.ui.runDialog;
|
||||
const LookingGlass = imports.ui.lookingGlass;
|
||||
@ -24,7 +25,7 @@ DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
||||
let chrome = null;
|
||||
let panel = null;
|
||||
let sidebar = null;
|
||||
let overlay = null;
|
||||
let overview = null;
|
||||
let runDialog = null;
|
||||
let lookingGlass = null;
|
||||
let wm = null;
|
||||
@ -40,13 +41,23 @@ function start() {
|
||||
|
||||
Tweener.init();
|
||||
|
||||
// Ensure ShellAppMonitor is initialized; this will
|
||||
// also initialize ShellAppSystem first. ShellAppSystem
|
||||
// needs to load all the .desktop files, and ShellAppMonitor
|
||||
// will use those to associate with windows. Right now
|
||||
// the Monitor doesn't listen for installed app changes
|
||||
// and recalculate application associations, so to avoid
|
||||
// races for now we initialize it here. It's better to
|
||||
// be predictable anyways.
|
||||
Shell.AppMonitor.get_default();
|
||||
|
||||
// The background color really only matters if there is no desktop
|
||||
// window (say, nautilus) running. We set it mostly so things look good
|
||||
// when we are running inside Xephyr.
|
||||
global.stage.color = DEFAULT_BACKGROUND_COLOR;
|
||||
|
||||
// Mutter currently hardcodes putting "Yessir. The compositor is running""
|
||||
// in the overlay. Clear that out.
|
||||
// in the Overview. Clear that out.
|
||||
let children = global.overlay_group.get_children();
|
||||
for (let i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
@ -59,12 +70,12 @@ function start() {
|
||||
runDialog.open();
|
||||
});
|
||||
|
||||
overlay = new Overlay.Overlay();
|
||||
overview = new Overview.Overview();
|
||||
chrome = new Chrome.Chrome();
|
||||
panel = new Panel.Panel();
|
||||
sidebar = new Sidebar.Sidebar();
|
||||
wm = new WindowManager.WindowManager();
|
||||
|
||||
|
||||
global.screen.connect('toggle-recording', function() {
|
||||
if (recorder == null) {
|
||||
recorder = new Shell.Recorder({ stage: global.stage });
|
||||
@ -77,15 +88,25 @@ function start() {
|
||||
}
|
||||
});
|
||||
|
||||
_relayout();
|
||||
|
||||
panel.startupAnimation();
|
||||
|
||||
let display = global.screen.get_display();
|
||||
display.connect('overlay-key', Lang.bind(overlay, overlay.toggle));
|
||||
global.connect('panel-main-menu', Lang.bind(overlay, overlay.toggle));
|
||||
|
||||
display.connect('overlay-key', Lang.bind(overview, overview.toggle));
|
||||
global.connect('panel-main-menu', Lang.bind(overview, overview.toggle));
|
||||
|
||||
global.stage.connect('captured-event', _globalKeyPressHandler);
|
||||
|
||||
Mainloop.idle_add(_removeUnusedWorkspaces);
|
||||
}
|
||||
|
||||
function _relayout() {
|
||||
let global = Shell.Global.get();
|
||||
panel.actor.set_size(global.screen_width, Panel.PANEL_HEIGHT);
|
||||
overview.relayout();
|
||||
}
|
||||
|
||||
// metacity-clutter currently uses the same prefs as plain metacity,
|
||||
// which probably means we'll be starting out with multiple workspaces;
|
||||
// remove any unused ones. (We do this from an idle handler, because
|
||||
@ -116,13 +137,60 @@ function _removeUnusedWorkspaces() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function encapsulates hacks to make certain global keybindings
|
||||
// work even when we are in one of our modes where global keybindings
|
||||
// are disabled with a global grab. (When there is a global grab, then
|
||||
// all key events will be delivered to the stage, so ::captured-event
|
||||
// on the stage can be used for global keybindings.)
|
||||
//
|
||||
// We expect to need to conditionally enable just a few keybindings
|
||||
// depending on circumstance; the main hackiness here is that we are
|
||||
// assuming that keybindings have their default values; really we
|
||||
// should be asking Mutter to resolve the key into an action and then
|
||||
// base our handling based on the action.
|
||||
function _globalKeyPressHandler(actor, event) {
|
||||
if (!inModal)
|
||||
return false;
|
||||
|
||||
let type = event.type();
|
||||
|
||||
if (type == Clutter.EventType.KEY_PRESS) {
|
||||
let symbol = Shell.get_event_key_symbol (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 [ok, len, args] = GLib.shell_parse_argv(command);
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (type == Clutter.EventType.KEY_RELEASE) {
|
||||
let symbol = Shell.get_event_key_symbol (event);
|
||||
if (symbol == Clutter.Super_L || symbol == Clutter.Super_R) {
|
||||
// The super key is the default for triggering the overview, and should
|
||||
// get us out of the overview when we are already in it.
|
||||
if (overview.visible)
|
||||
overview.hide();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used to go into a mode where all keyboard and mouse input goes to
|
||||
// the stage. Returns true if we successfully grabbed the keyboard and
|
||||
// went modal, false otherwise
|
||||
function startModal() {
|
||||
function beginModal() {
|
||||
let global = Shell.Global.get();
|
||||
let timestamp = global.screen.get_display().get_current_time();
|
||||
|
||||
if (!global.grab_keyboard())
|
||||
if (!global.begin_modal(timestamp))
|
||||
return false;
|
||||
global.set_stage_input_mode(Shell.StageInputMode.FULLSCREEN);
|
||||
|
||||
@ -133,8 +201,9 @@ function startModal() {
|
||||
|
||||
function endModal() {
|
||||
let global = Shell.Global.get();
|
||||
let timestamp = global.screen.get_display().get_current_time();
|
||||
|
||||
global.ungrab_keyboard();
|
||||
global.end_modal(timestamp);
|
||||
global.set_stage_input_mode(Shell.StageInputMode.NORMAL);
|
||||
inModal = false;
|
||||
}
|
||||
|
@ -19,14 +19,14 @@ const Dash = imports.ui.dash;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Workspaces = imports.ui.workspaces;
|
||||
|
||||
const ROOT_OVERLAY_COLOR = new Clutter.Color();
|
||||
ROOT_OVERLAY_COLOR.from_pixel(0x000000ff);
|
||||
const ROOT_OVERVIEW_COLOR = new Clutter.Color();
|
||||
ROOT_OVERVIEW_COLOR.from_pixel(0x000000ff);
|
||||
|
||||
// Time for initial animation going into overlay mode
|
||||
// Time for initial animation going into Overview mode
|
||||
const ANIMATION_TIME = 0.25;
|
||||
|
||||
// We divide the screen into a grid of rows and columns, which we use
|
||||
// to help us position the overlay components, such as the side panel
|
||||
// to help us position the Overview components, such as the side panel
|
||||
// that lists applications and documents, the workspaces display, and
|
||||
// the button for adding additional workspaces.
|
||||
// In the regular mode, the side panel takes up one column on the left,
|
||||
@ -74,11 +74,11 @@ let wideScreen = false;
|
||||
let displayGridColumnWidth = null;
|
||||
let displayGridRowHeight = null;
|
||||
|
||||
function Overlay() {
|
||||
function Overview() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Overlay.prototype = {
|
||||
Overview.prototype = {
|
||||
_init : function() {
|
||||
let me = this;
|
||||
|
||||
@ -101,15 +101,15 @@ Overlay.prototype = {
|
||||
reactive: true });
|
||||
this._group.add_actor(this._transparentBackground);
|
||||
|
||||
// Background color for the overlay
|
||||
this._backOver = new Clutter.Rectangle({ color: ROOT_OVERLAY_COLOR });
|
||||
// Background color for the Overview
|
||||
this._backOver = new Clutter.Rectangle({ color: ROOT_OVERVIEW_COLOR });
|
||||
this._group.add_actor(this._backOver);
|
||||
|
||||
this._group.hide();
|
||||
global.overlay_group.add_actor(this._group);
|
||||
|
||||
// TODO - recalculate everything when desktop size changes
|
||||
this._dash = new Dash.Dash(displayGridColumnWidth);
|
||||
this._dash = new Dash.Dash();
|
||||
this._group.add_actor(this._dash.actor);
|
||||
|
||||
// Container to hold popup pane chrome.
|
||||
@ -127,8 +127,6 @@ Overlay.prototype = {
|
||||
this._transparentBackground.lower_bottom();
|
||||
this._paneContainer.lower_bottom();
|
||||
|
||||
this._repositionChildren();
|
||||
|
||||
this._workspaces = null;
|
||||
},
|
||||
|
||||
@ -148,13 +146,37 @@ Overlay.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_repositionChildren: function () {
|
||||
relayout: function () {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
let contentHeight = global.screen_height - Panel.PANEL_HEIGHT;
|
||||
let screenHeight = global.screen_height;
|
||||
let screenWidth = global.screen_width;
|
||||
|
||||
this._dash.actor.set_position(0, Panel.PANEL_HEIGHT);
|
||||
this._dash.actor.set_size(displayGridColumnWidth, contentHeight);
|
||||
let contentHeight = screenHeight - Panel.PANEL_HEIGHT;
|
||||
|
||||
let workspaceColumnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
let workspaceRowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
|
||||
this._workspacesWidth = displayGridColumnWidth * workspaceColumnsUsed
|
||||
- WORKSPACE_GRID_PADDING * 2;
|
||||
// We scale the vertical padding by (screenHeight / screenWidth)
|
||||
// so that the workspace preserves its aspect ratio.
|
||||
this._workspacesHeight = displayGridRowHeight * workspaceRowsUsed
|
||||
- WORKSPACE_GRID_PADDING * (screenHeight / screenWidth) * 2;
|
||||
|
||||
this._workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
|
||||
this._workspacesY = displayGridRowHeight + WORKSPACE_GRID_PADDING * (screenHeight / screenWidth);
|
||||
|
||||
let dashY = Panel.PANEL_HEIGHT;
|
||||
this._dash.actor.set_position(0, dashY);
|
||||
this._dash.actor.set_size(displayGridColumnWidth, screenHeight - dashY);
|
||||
this._dash.searchArea.height = this._workspacesY - dashY;
|
||||
this._dash.sectionArea.height = this._workspacesHeight;
|
||||
|
||||
// place the 'Add Workspace' button in the bottom row of the grid
|
||||
this._addButtonSize = Math.floor(displayGridRowHeight * 3/5);
|
||||
this._addButtonX = this._workspacesX + this._workspacesWidth - this._addButtonSize;
|
||||
this._addButtonY = screenHeight - Math.floor(displayGridRowHeight * 4/5);
|
||||
|
||||
this._backOver.set_position(0, Panel.PANEL_HEIGHT);
|
||||
this._backOver.set_size(global.screen_width, contentHeight);
|
||||
@ -167,10 +189,12 @@ Overlay.prototype = {
|
||||
this._transparentBackground.set_position(this._paneContainer.x, this._paneContainer.y);
|
||||
this._transparentBackground.set_size(global.screen_width - this._paneContainer.x,
|
||||
this._paneContainer.height);
|
||||
|
||||
if (this._activeDisplayPane != null)
|
||||
this._activeDisplayPane.actor.width = displayGridColumnWidth * 2;
|
||||
},
|
||||
|
||||
addPane: function (pane) {
|
||||
pane.actor.width = displayGridColumnWidth * 2;
|
||||
this._paneContainer.append(pane.actor, Big.BoxPackFlags.NONE);
|
||||
// When a pane is displayed, we raise the transparent background to the top
|
||||
// and connect to button-release-event on it, then raise the pane above that.
|
||||
@ -179,6 +203,7 @@ Overlay.prototype = {
|
||||
let backgroundEventId = null;
|
||||
pane.connect('open-state-changed', Lang.bind(this, function (pane, isOpen) {
|
||||
if (isOpen) {
|
||||
pane.actor.width = displayGridColumnWidth * 2;
|
||||
this._activeDisplayPane = pane;
|
||||
this._transparentBackground.raise_top();
|
||||
this._paneContainer.raise_top();
|
||||
@ -203,7 +228,7 @@ Overlay.prototype = {
|
||||
//// Draggable target interface ////
|
||||
|
||||
// Closes any active panes if a GenericDisplayItem is being
|
||||
// dragged over the overlay, i.e. as soon as it starts being dragged.
|
||||
// dragged over the Overview, i.e. as soon as it starts being dragged.
|
||||
// This allows the user to place the item on any workspace.
|
||||
handleDragOver : function(source, actor, x, y, time) {
|
||||
if (source instanceof GenericDisplay.GenericDisplayItem
|
||||
@ -218,70 +243,88 @@ Overlay.prototype = {
|
||||
|
||||
//// Public methods ////
|
||||
|
||||
// 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();
|
||||
},
|
||||
|
||||
// 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 scale = this.getZoomedInScale();
|
||||
|
||||
return [- posX * scale, - posY * scale];
|
||||
},
|
||||
|
||||
// Returns the current scale of the Overview.
|
||||
getScale : function() {
|
||||
return this._group.scaleX;
|
||||
},
|
||||
|
||||
// Returns the current position of the Overview.
|
||||
getPosition : function() {
|
||||
return [this._group.x, this._group.y];
|
||||
},
|
||||
|
||||
show : function() {
|
||||
if (this.visible)
|
||||
return;
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
this.visible = true;
|
||||
this.animationInProgress = true;
|
||||
|
||||
let global = Shell.Global.get();
|
||||
let screenWidth = global.screen_width;
|
||||
let screenHeight = global.screen_height;
|
||||
|
||||
this._dash.show();
|
||||
|
||||
let columnsUsed = wideScreen ? COLUMNS_FOR_WORKSPACES_WIDE_SCREEN : COLUMNS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
let rowsUsed = wideScreen ? ROWS_FOR_WORKSPACES_WIDE_SCREEN : ROWS_FOR_WORKSPACES_REGULAR_SCREEN;
|
||||
|
||||
let workspacesWidth = displayGridColumnWidth * columnsUsed - WORKSPACE_GRID_PADDING * 2;
|
||||
// We scale the vertical padding by (screenHeight / screenWidth) so that the workspace preserves its aspect ratio.
|
||||
let workspacesHeight = displayGridRowHeight * rowsUsed - WORKSPACE_GRID_PADDING * (screenHeight / screenWidth) * 2;
|
||||
|
||||
let workspacesX = displayGridColumnWidth + WORKSPACE_GRID_PADDING;
|
||||
let workspacesY = displayGridRowHeight + WORKSPACE_GRID_PADDING * (screenHeight / screenWidth);
|
||||
|
||||
// place the 'Add Workspace' button in the bottom row of the grid
|
||||
let addButtonSize = Math.floor(displayGridRowHeight * 3/5);
|
||||
let addButtonX = workspacesX + workspacesWidth - addButtonSize;
|
||||
let addButtonY = screenHeight - Math.floor(displayGridRowHeight * 4/5);
|
||||
|
||||
this._workspaces = new Workspaces.Workspaces(workspacesWidth, workspacesHeight, workspacesX, workspacesY,
|
||||
addButtonSize, addButtonX, addButtonY);
|
||||
/* TODO: make this stuff dynamic */
|
||||
this._workspaces = new Workspaces.Workspaces(this._workspacesWidth, this._workspacesHeight,
|
||||
this._workspacesX, this._workspacesY,
|
||||
this._addButtonSize, this._addButtonX, this._addButtonY);
|
||||
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);
|
||||
|
||||
// All the the actors in the window group are completely obscured,
|
||||
// hiding the group holding them while the overlay is displayed greatly
|
||||
// increases performance of the overlay especially when there are many
|
||||
// hiding the group holding them while the Overview is displayed greatly
|
||||
// increases performance of the Overview especially when there are many
|
||||
// windows visible.
|
||||
//
|
||||
// If we switched to displaying the actors in the overlay rather than
|
||||
// If we switched to displaying the actors in the Overview rather than
|
||||
// clones of them, this would obviously no longer be necessary.
|
||||
global.window_group.hide();
|
||||
this._group.show();
|
||||
|
||||
// Try to make the menu not too visible behind the empty space between
|
||||
// the workspace previews by sliding in its clipping rectangle.
|
||||
// We want to finish drawing the Dash just before the top workspace fully
|
||||
// slides in on the top. Which means that we have more time to wait before
|
||||
// drawing the dash if the active workspace is displayed on the bottom of
|
||||
// the workspaces grid, and almost no time to wait if it is displayed in the top
|
||||
// row of the workspaces grid. The calculations used below try to roughly
|
||||
// capture the animation ratio for when workspaces are covering the top of the overlay
|
||||
// vs. when workspaces are already below the top of the overlay, and apply it
|
||||
// to clipping the dash. The clipping is removed in this._showDone().
|
||||
this._dash.actor.set_clip(0, 0,
|
||||
this._workspaces.getFullSizeX(),
|
||||
this._dash.actor.height);
|
||||
Tweener.addTween(this._dash.actor,
|
||||
{ clipWidthRight: this._dash._width + WORKSPACE_GRID_PADDING + this._workspaces.getWidthToTopActiveWorkspace(),
|
||||
// Create a zoom out effect. First scale the Overview group up and
|
||||
// position it so that the active workspace fills up the whole screen,
|
||||
// then transform the group to its normal dimensions and position.
|
||||
// The opposite transition is used in hide().
|
||||
this._group.scaleX = this._group.scaleY = this.getZoomedInScale();
|
||||
[this._group.x, this._group.y] = this.getZoomedInPosition();
|
||||
Tweener.addTween(this._group,
|
||||
{ x: 0,
|
||||
y: 0,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._showDone,
|
||||
onCompleteScope: this
|
||||
});
|
||||
|
||||
// Make Dash fade in so that it doesn't appear to big.
|
||||
this._dash.actor.opacity = 0;
|
||||
Tweener.addTween(this._dash.actor,
|
||||
{ opacity: 255,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME
|
||||
});
|
||||
|
||||
this.emit('showing');
|
||||
@ -297,27 +340,29 @@ Overlay.prototype = {
|
||||
this._hideInProgress = true;
|
||||
if (this._activeDisplayPane != null)
|
||||
this._activeDisplayPane.close();
|
||||
// lower the panes, so that workspaces display is on top while sliding out
|
||||
this._dash.actor.lower(this._workspaces.actor);
|
||||
this._workspaces.hide();
|
||||
|
||||
// Try to make the menu not too visible behind the empty space between
|
||||
// the workspace previews by sliding in its clipping rectangle.
|
||||
// The logic used is the same as described in this.show(). If the active workspace
|
||||
// is displayed in the top row, than almost full animation time is needed for it
|
||||
// to reach the top of the overlay and cover the Dash fully, while if the
|
||||
// active workspace is in the lower row, than the top left workspace reaches the
|
||||
// top of the overlay sooner as it is moving out of the way.
|
||||
// The clipping is removed in this._hideDone().
|
||||
this._dash.actor.set_clip(0, 0,
|
||||
this._dash.actor.width + WORKSPACE_GRID_PADDING + this._workspaces.getWidthToTopActiveWorkspace(),
|
||||
this._dash.actor.height);
|
||||
Tweener.addTween(this._dash.actor,
|
||||
{ clipWidthRight: this._workspaces.getFullSizeX() + this._workspaces.getWidthToTopActiveWorkspace() - global.screen_width,
|
||||
// Create a zoom in effect by transforming the Overview group so that
|
||||
// the active workspace fills up the whole screen. The opposite
|
||||
// transition is used in show().
|
||||
let scale = this.getZoomedInScale();
|
||||
let [posX, posY] = this.getZoomedInPosition();
|
||||
Tweener.addTween(this._group,
|
||||
{ x: posX,
|
||||
y: posY,
|
||||
scaleX: scale,
|
||||
scaleY: scale,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._hideDone,
|
||||
onCompleteScope: this
|
||||
});
|
||||
|
||||
// Make Dash fade out so that it doesn't appear to big.
|
||||
Tweener.addTween(this._dash.actor,
|
||||
{ opacity: 0,
|
||||
transition: 'easeOutQuad',
|
||||
time: ANIMATION_TIME
|
||||
});
|
||||
|
||||
this.emit('hiding');
|
||||
@ -337,31 +382,20 @@ Overlay.prototype = {
|
||||
*
|
||||
* Make the given MetaWindow be the focus window, switching
|
||||
* to the workspace it's on if necessary. This function
|
||||
* should only be used when the overlay is currently active;
|
||||
* should only be used when the Overview is currently active;
|
||||
* outside of that, use the relevant methods on MetaDisplay.
|
||||
*/
|
||||
activateWindow: function (metaWindow, time) {
|
||||
this._workspaces.activateWindowFromOverlay(metaWindow, time);
|
||||
this._workspaces.activateWindowFromOverview(metaWindow, time);
|
||||
this.hide();
|
||||
},
|
||||
|
||||
//// Private methods ////
|
||||
|
||||
// Raises the Dash to the top, so that we can tell if the pointer is above one of its items.
|
||||
// We need to do this once the workspaces are shown because the workspaces actor currently covers
|
||||
// the whole screen, regardless of where the workspaces are actually displayed.
|
||||
//
|
||||
// Once we rework the workspaces actor to only cover the area it actually needs, we can
|
||||
// remove this workaround. Also http://bugzilla.openedhand.com/show_bug.cgi?id=1513 requests being
|
||||
// able to pick only a reactive actor at a certain position, rather than any actor. Being able
|
||||
// to do that would allow us to not have to raise the Dash.
|
||||
_showDone: function() {
|
||||
if (this._hideInProgress)
|
||||
return;
|
||||
|
||||
this._dash.actor.raise_top();
|
||||
this._dash.actor.remove_clip();
|
||||
|
||||
this.animationInProgress = false;
|
||||
|
||||
this.emit('shown');
|
||||
@ -375,7 +409,6 @@ Overlay.prototype = {
|
||||
this._workspaces.destroy();
|
||||
this._workspaces = null;
|
||||
|
||||
this._dash.actor.remove_clip();
|
||||
this._dash.hide();
|
||||
this._group.hide();
|
||||
|
||||
@ -387,37 +420,4 @@ Overlay.prototype = {
|
||||
this.emit('hidden');
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(Overlay.prototype);
|
||||
|
||||
Tweener.registerSpecialProperty("clipHeightBottom", _clipHeightBottomGet, _clipHeightBottomSet);
|
||||
|
||||
function _clipHeightBottomGet(actor) {
|
||||
let [xOffset, yOffset, clipWidth, clipHeight] = actor.get_clip();
|
||||
return clipHeight;
|
||||
}
|
||||
|
||||
function _clipHeightBottomSet(actor, clipHeight) {
|
||||
actor.set_clip(0, 0, actor.width, clipHeight);
|
||||
}
|
||||
|
||||
Tweener.registerSpecialProperty("clipHeightTop", _clipHeightTopGet, _clipHeightTopSet);
|
||||
|
||||
function _clipHeightTopGet(actor) {
|
||||
let [xOffset, yOffset, clipWidth, clipHeight] = actor.get_clip();
|
||||
return clipHeight;
|
||||
}
|
||||
|
||||
function _clipHeightTopSet(actor, clipHeight) {
|
||||
actor.set_clip(0, actor.height - clipHeight, actor.width, clipHeight);
|
||||
}
|
||||
|
||||
Tweener.registerSpecialProperty("clipWidthRight", _clipWidthRightGet, _clipWidthRightSet);
|
||||
|
||||
function _clipWidthRightGet(actor) {
|
||||
let [xOffset, yOffset, clipWidth, clipHeight] = actor.get_clip();
|
||||
return clipWidth;
|
||||
}
|
||||
|
||||
function _clipWidthRightSet(actor, clipWidth) {
|
||||
actor.set_clip(0, 0, clipWidth, actor.height);
|
||||
}
|
||||
Signals.addSignalMethods(Overview.prototype);
|
399
js/ui/panel.js
399
js/ui/panel.js
@ -8,6 +8,9 @@ const Mainloop = imports.mainloop;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Button = imports.ui.button;
|
||||
const Main = imports.ui.main;
|
||||
@ -15,10 +18,19 @@ const Main = imports.ui.main;
|
||||
const PANEL_HEIGHT = 26;
|
||||
const TRAY_HEIGHT = PANEL_HEIGHT - 1;
|
||||
|
||||
const PANEL_BACKGROUND_COLOR = new Clutter.Color();
|
||||
PANEL_BACKGROUND_COLOR.from_pixel(0x000000ff);
|
||||
const DEFAULT_PADDING = 4;
|
||||
|
||||
const PANEL_ICON_SIZE = 24;
|
||||
|
||||
const BACKGROUND_TOP = new Clutter.Color();
|
||||
BACKGROUND_TOP.from_pixel(0x161616ff);
|
||||
const BACKGROUND_BOTTOM = new Clutter.Color();
|
||||
BACKGROUND_BOTTOM.from_pixel(0x000000ff);
|
||||
|
||||
const PANEL_FOREGROUND_COLOR = new Clutter.Color();
|
||||
PANEL_FOREGROUND_COLOR.from_pixel(0xffffffff);
|
||||
const SN_BACKGROUND_COLOR = new Clutter.Color();
|
||||
SN_BACKGROUND_COLOR.from_pixel(0xffff00a0);
|
||||
|
||||
const TRANSPARENT_COLOR = new Clutter.Color();
|
||||
TRANSPARENT_COLOR.from_pixel(0x00000000);
|
||||
@ -47,6 +59,109 @@ TRAY_BORDER_COLOR.from_pixel(0x00000033);
|
||||
const TRAY_CORNER_RADIUS = 5;
|
||||
const TRAY_BORDER_WIDTH = 0;
|
||||
|
||||
|
||||
function AppPanelMenu() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
AppPanelMenu.prototype = {
|
||||
_init: function() {
|
||||
this._metaDisplay = Shell.Global.get().screen.get_display();
|
||||
|
||||
this._focusedApp = null;
|
||||
this._activeSequence = null;
|
||||
this._startupSequences = {};
|
||||
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: DEFAULT_PADDING,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._iconBox = new Big.Box({ width: PANEL_ICON_SIZE, height: PANEL_ICON_SIZE,
|
||||
x_align: Big.BoxAlignment.CENTER,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.append(this._iconBox, Big.BoxPackFlags.NONE);
|
||||
let labelBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._label = new Clutter.Text({ font_name: DEFAULT_FONT,
|
||||
color: PANEL_FOREGROUND_COLOR,
|
||||
text: "" });
|
||||
labelBox.append(this._label, Big.BoxPackFlags.EXPAND);
|
||||
this.actor.append(labelBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._startupBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.append(this._startupBox, Big.BoxPackFlags.NONE);
|
||||
|
||||
Main.overview.connect('hiding', Lang.bind(this, function () {
|
||||
this.actor.opacity = 255;
|
||||
}));
|
||||
Main.overview.connect('showing', Lang.bind(this, function () {
|
||||
this.actor.opacity = 192;
|
||||
}));
|
||||
|
||||
this._metaDisplay.connect('notify::focus-window', Lang.bind(this, this._sync));
|
||||
|
||||
let appMonitor = Shell.AppMonitor.get_default();
|
||||
appMonitor.connect('startup-sequence-changed', Lang.bind(this, this._sync));
|
||||
// For now just resync on application add/remove; this is mainly to handle
|
||||
// cases where the focused window's application changes without the focus
|
||||
// changing. An example case is how we map Firefox based on the window
|
||||
// title which is a dynamic property.
|
||||
appMonitor.connect('app-added', Lang.bind(this, this._sync));
|
||||
appMonitor.connect('app-removed', Lang.bind(this, this._sync));
|
||||
|
||||
this._sync();
|
||||
},
|
||||
|
||||
_sync: function() {
|
||||
let appMonitor = Shell.AppMonitor.get_default();
|
||||
|
||||
let focusWindow = this._metaDisplay.get_focus_window();
|
||||
let focusedApp;
|
||||
if (focusWindow == null) {
|
||||
focusedApp = null;
|
||||
} else {
|
||||
focusedApp = appMonitor.get_window_app(focusWindow);
|
||||
}
|
||||
|
||||
let lastSequence = null;
|
||||
if (focusedApp == null) {
|
||||
let sequences = appMonitor.get_startup_sequences();
|
||||
if (sequences.length > 0)
|
||||
lastSequence = sequences[sequences.length - 1];
|
||||
}
|
||||
|
||||
// If the currently focused app hasn't changed and the current
|
||||
// startup sequence hasn't changed, we have nothing to do
|
||||
if (focusedApp == this._focusedApp
|
||||
&& ((lastSequence == null && this._activeSequence == null)
|
||||
|| (lastSequence != null && this._activeSequence != null
|
||||
&& lastSequence.get_id() == this._activeSequence.get_id())))
|
||||
return;
|
||||
|
||||
this._focusedApp = focusedApp;
|
||||
this._activeSequence = lastSequence;
|
||||
|
||||
this._iconBox.remove_all();
|
||||
this._iconBox.hide();
|
||||
this._label.text = '';
|
||||
if (this._focusedApp != null) {
|
||||
let icon = focusedApp.create_icon_texture(PANEL_ICON_SIZE);
|
||||
this._iconBox.append(icon, Big.BoxPackFlags.NONE);
|
||||
this._iconBox.show();
|
||||
this._label.text = focusedApp.get_name();
|
||||
} else if (this._activeSequence != null) {
|
||||
let icon = this._activeSequence.create_icon(PANEL_ICON_SIZE);
|
||||
this._iconBox.append(icon, Big.BoxPackFlags.NONE);
|
||||
this._iconBox.show();
|
||||
this._label.text = this._activeSequence.get_name();
|
||||
}
|
||||
|
||||
this.emit('changed');
|
||||
}
|
||||
}
|
||||
|
||||
Signals.addSignalMethods(AppPanelMenu.prototype);
|
||||
|
||||
function Panel() {
|
||||
this._init();
|
||||
}
|
||||
@ -55,77 +170,163 @@ Panel.prototype = {
|
||||
_init : function() {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
// Put the background under the panel within a group.
|
||||
this.actor = new Clutter.Group();
|
||||
|
||||
// backBox contains the panel background and the clock.
|
||||
let backBox = new Big.Box({ width: global.screen_width,
|
||||
height: PANEL_HEIGHT,
|
||||
backgroundColor: PANEL_BACKGROUND_COLOR,
|
||||
x_align: Big.BoxAlignment.CENTER });
|
||||
this.actor.add_actor(backBox);
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL
|
||||
});
|
||||
let backgroundGradient = Shell.create_vertical_gradient(BACKGROUND_TOP,
|
||||
BACKGROUND_BOTTOM);
|
||||
this.actor.connect('notify::allocation', Lang.bind(this, function () {
|
||||
let [width, height] = this.actor.get_size();
|
||||
backgroundGradient.set_size(width, height);
|
||||
}));
|
||||
this.actor.add_actor(backgroundGradient);
|
||||
|
||||
let box = new Big.Box({ x: 0,
|
||||
y: 0,
|
||||
height: PANEL_HEIGHT,
|
||||
width: global.screen_width,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
spacing: 4 });
|
||||
this._leftBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
spacing: DEFAULT_PADDING,
|
||||
padding_right: DEFAULT_PADDING });
|
||||
this._centerBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER });
|
||||
this._rightBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
y_align: Big.BoxAlignment.CENTER,
|
||||
padding_left: DEFAULT_PADDING });
|
||||
|
||||
this.button = new Button.Button("Activities", PANEL_BUTTON_COLOR, PRESSED_BUTTON_BACKGROUND_COLOR, PANEL_FOREGROUND_COLOR, true, null, PANEL_HEIGHT, DEFAULT_FONT);
|
||||
/* This box container ensures that the centerBox is positioned in the *absolute*
|
||||
* center, but can be pushed aside if necessary. */
|
||||
this._boxContainer = new Shell.GenericContainer();
|
||||
this.actor.append(this._boxContainer, Big.BoxPackFlags.EXPAND);
|
||||
this._boxContainer.add_actor(this._leftBox);
|
||||
this._boxContainer.add_actor(this._centerBox);
|
||||
this._boxContainer.add_actor(this._rightBox);
|
||||
this._boxContainer.connect('get-preferred-width', Lang.bind(this, function(box, forHeight, alloc) {
|
||||
let children = box.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let [childMin, childNatural] = children[i].get_preferred_width(forHeight);
|
||||
alloc.min_size += childMin;
|
||||
alloc.natural_size += childNatural;
|
||||
}
|
||||
}));
|
||||
this._boxContainer.connect('get-preferred-height', Lang.bind(this, function(box, forWidth, alloc) {
|
||||
let children = box.get_children();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
let [childMin, childNatural] = children[i].get_preferred_height(forWidth);
|
||||
if (childMin > alloc.min_size)
|
||||
alloc.min_size = childMin;
|
||||
if (childNatural > alloc.natural_size)
|
||||
alloc.natural_size = childNatural;
|
||||
}
|
||||
}));
|
||||
this._boxContainer.connect('allocate', Lang.bind(this, function(container, box, flags) {
|
||||
let allocWidth = box.x2 - box.x1;
|
||||
let allocHeight = box.y2 - box.y1;
|
||||
let [leftMinWidth, leftNaturalWidth] = this._leftBox.get_preferred_width(-1);
|
||||
let [centerMinWidth, centerNaturalWidth] = this._centerBox.get_preferred_width(-1);
|
||||
let [rightMinWidth, rightNaturalWidth] = this._rightBox.get_preferred_width(-1);
|
||||
let leftWidth, centerWidth, rightWidth;
|
||||
if (allocWidth < (leftNaturalWidth + centerNaturalWidth + rightNaturalWidth)) {
|
||||
leftWidth = leftMinWidth;
|
||||
centerWidth = centerMinWidth;
|
||||
rightWidth = rightMinWidth;
|
||||
} else {
|
||||
leftWidth = leftNaturalWidth;
|
||||
centerWidth = centerNaturalWidth;
|
||||
rightWidth = rightNaturalWidth;
|
||||
}
|
||||
|
||||
box.append(this.button.button, Big.BoxPackFlags.NONE);
|
||||
let x;
|
||||
let childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = box.x1;
|
||||
childBox.y1 = box.y1;
|
||||
childBox.x2 = x = childBox.x1 + leftWidth;
|
||||
childBox.y2 = box.y2;
|
||||
this._leftBox.allocate(childBox, flags);
|
||||
|
||||
let hotCorner = new Clutter.Rectangle({ width: 1,
|
||||
height: 1,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
let centerNaturalX = Math.floor((box.x2 - box.x1) / 2 - (centerWidth / 2));
|
||||
/* Check left side */
|
||||
if (x < centerNaturalX) {
|
||||
/* We didn't overflow the left, use the natural. */
|
||||
x = centerNaturalX;
|
||||
}
|
||||
/* Check right side */
|
||||
if (x + centerWidth > (box.x2 - rightWidth)) {
|
||||
x = box.x2 - rightWidth - centerWidth;
|
||||
}
|
||||
childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = x;
|
||||
childBox.y1 = box.y1;
|
||||
childBox.x2 = x = childBox.x1 + centerWidth;
|
||||
childBox.y2 = box.y2;
|
||||
this._centerBox.allocate(childBox, flags);
|
||||
|
||||
childBox = new Clutter.ActorBox();
|
||||
childBox.x1 = box.x2 - rightWidth;
|
||||
childBox.y1 = box.y1;
|
||||
childBox.x2 = box.x2;
|
||||
childBox.y2 = box.y2;
|
||||
this._rightBox.allocate(childBox, flags);
|
||||
}));
|
||||
|
||||
/* left side */
|
||||
|
||||
this.button = new Button.Button(_("Activities"), PANEL_BUTTON_COLOR, PRESSED_BUTTON_BACKGROUND_COLOR,
|
||||
PANEL_FOREGROUND_COLOR, true, DEFAULT_FONT);
|
||||
this.button.button.height = PANEL_HEIGHT;
|
||||
|
||||
this._leftBox.append(this.button.button, Big.BoxPackFlags.NONE);
|
||||
|
||||
// We use this flag to mark the case where the user has entered the
|
||||
// hot corner and has not left both the hot corner and a surrounding
|
||||
// guard area (the "environs"). This avoids triggering the hot corner
|
||||
// multiple times due to an accidental jitter.
|
||||
this._hotCornerEntered = false;
|
||||
|
||||
this._hotCornerEnvirons = new Clutter.Rectangle({ width: 3,
|
||||
height: 3,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
|
||||
this._hotCorner = new Clutter.Rectangle({ width: 1,
|
||||
height: 1,
|
||||
opacity: 0,
|
||||
reactive: true });
|
||||
|
||||
this._hotCornerEnvirons.connect('leave-event',
|
||||
Lang.bind(this, this._onHotCornerEnvironsLeft));
|
||||
// Clicking on the hot corner environs should result in the same bahavior
|
||||
// as clicking on the hot corner.
|
||||
this._hotCornerEnvirons.connect('button-release-event',
|
||||
Lang.bind(this, this._onHotCornerClicked));
|
||||
|
||||
// In addition to being triggered by the mouse enter event, the hot corner
|
||||
// can be triggered by clicking on it. This is useful if the user wants to
|
||||
// undo the effect of triggering the hot corner once in the hot corner.
|
||||
hotCorner.connect('enter-event',
|
||||
Lang.bind(this, this._onHotCornerTriggered));
|
||||
hotCorner.connect('button-release-event',
|
||||
Lang.bind(this, this._onHotCornerTriggered));
|
||||
this._hotCorner.connect('enter-event',
|
||||
Lang.bind(this, this._onHotCornerEntered));
|
||||
this._hotCorner.connect('button-release-event',
|
||||
Lang.bind(this, this._onHotCornerClicked));
|
||||
this._hotCorner.connect('leave-event',
|
||||
Lang.bind(this, this._onHotCornerLeft));
|
||||
|
||||
box.add_actor(hotCorner);
|
||||
this._leftBox.append(this._hotCornerEnvirons, Big.BoxPackFlags.FIXED);
|
||||
this._leftBox.append(this._hotCorner, Big.BoxPackFlags.FIXED);
|
||||
|
||||
let statusbox = new Big.Box();
|
||||
let statusmenu = this._statusmenu = new Shell.StatusMenu();
|
||||
statusmenu.get_icon().hide();
|
||||
statusmenu.get_name().fontName = DEFAULT_FONT;
|
||||
statusmenu.get_name().color = PANEL_FOREGROUND_COLOR;
|
||||
statusbox.append(this._statusmenu, Big.BoxPackFlags.NONE);
|
||||
let statusbutton = new Button.Button(statusbox,
|
||||
PANEL_BUTTON_COLOR,
|
||||
PRESSED_BUTTON_BACKGROUND_COLOR,
|
||||
PANEL_FOREGROUND_COLOR,
|
||||
true, null, PANEL_HEIGHT);
|
||||
statusbutton.button.connect('button-press-event', function (b, e) {
|
||||
statusmenu.toggle(e);
|
||||
return false;
|
||||
});
|
||||
box.append(statusbutton.button, Big.BoxPackFlags.END);
|
||||
// We get a deactivated event when the popup disappears
|
||||
this._statusmenu.connect('deactivated', function (sm) {
|
||||
statusbutton.release();
|
||||
});
|
||||
let appMenu = new AppPanelMenu();
|
||||
this._leftBox.append(appMenu.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
/* center */
|
||||
|
||||
this._clock = new Clutter.Text({ font_name: DEFAULT_FONT,
|
||||
color: PANEL_FOREGROUND_COLOR,
|
||||
text: "" });
|
||||
let clockbox = new Big.Box({ y_align: Big.BoxAlignment.CENTER,
|
||||
padding_left: 4,
|
||||
padding_right: 4 });
|
||||
clockbox.append(this._clock, Big.BoxPackFlags.NONE);
|
||||
backBox.append(clockbox, Big.BoxPackFlags.EXPAND);
|
||||
this._centerBox.append(this._clock, Big.BoxPackFlags.NONE);
|
||||
|
||||
/* right */
|
||||
|
||||
// The tray icons live in trayBox within trayContainer.
|
||||
// The trayBox is hidden when there are no tray icons.
|
||||
let trayContainer = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
||||
y_align: Big.BoxAlignment.START });
|
||||
box.append(trayContainer, Big.BoxPackFlags.END);
|
||||
this._rightBox.append(trayContainer, Big.BoxPackFlags.NONE);
|
||||
let trayBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
height: TRAY_HEIGHT,
|
||||
padding: TRAY_PADDING,
|
||||
@ -164,22 +365,55 @@ Panel.prototype = {
|
||||
}));
|
||||
this._traymanager.manage_stage(global.stage);
|
||||
|
||||
// TODO: decide what to do with the rest of the panel in the overlay mode (make it fade-out, become non-reactive, etc.)
|
||||
// We get into the overlay mode on button-press-event as opposed to button-release-event because eventually we'll probably
|
||||
// have the overlay act like a menu that allows the user to release the mouse on the activity the user wants
|
||||
let statusbox = new Big.Box();
|
||||
let statusmenu = this._statusmenu = new Shell.StatusMenu();
|
||||
statusmenu.get_icon().hide();
|
||||
statusmenu.get_name().fontName = DEFAULT_FONT;
|
||||
statusmenu.get_name().color = PANEL_FOREGROUND_COLOR;
|
||||
statusbox.append(this._statusmenu, Big.BoxPackFlags.NONE);
|
||||
let statusbutton = new Button.Button(statusbox,
|
||||
PANEL_BUTTON_COLOR,
|
||||
PRESSED_BUTTON_BACKGROUND_COLOR,
|
||||
PANEL_FOREGROUND_COLOR,
|
||||
true);
|
||||
statusbutton.button.height = PANEL_HEIGHT;
|
||||
statusbutton.button.connect('button-press-event', function (b, e) {
|
||||
statusmenu.toggle(e);
|
||||
return false;
|
||||
});
|
||||
// If popping up the menu failed (because there was already a grab in
|
||||
// effect from Mutter or another app), then we'll never get a ::deactivated
|
||||
// signal because the menu was never activated, so we need to unhighlight
|
||||
// separately when the user releases the mouse button.
|
||||
//
|
||||
// We depend on connection ordering; this needs to be called after Button's
|
||||
// ::button-release-event handler; that will set the active flag for this
|
||||
// stays-pressed button, then we unset the active flag by calling release().
|
||||
statusbutton.button.connect('button-release-event', function (b, e) {
|
||||
if (!statusmenu.is_active())
|
||||
statusbutton.release();
|
||||
return false;
|
||||
});
|
||||
this._rightBox.append(statusbutton.button, Big.BoxPackFlags.NONE);
|
||||
// We get a deactivated event when the popup disappears
|
||||
this._statusmenu.connect('deactivated', function (sm) {
|
||||
statusbutton.release();
|
||||
});
|
||||
|
||||
// TODO: decide what to do with the rest of the panel in the Overview mode (make it fade-out, become non-reactive, etc.)
|
||||
// We get into the Overview mode on button-press-event as opposed to button-release-event because eventually we'll probably
|
||||
// have the Overview act like a menu that allows the user to release the mouse on the activity the user wants
|
||||
// to switch to.
|
||||
this.button.button.connect('button-press-event',
|
||||
Lang.bind(Main.overlay, Main.overlay.toggle));
|
||||
// In addition to pressing the button, the overlay can be entered and exited by other means, such as
|
||||
// pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the overlay is entered
|
||||
Lang.bind(Main.overview, Main.overview.toggle));
|
||||
// In addition to pressing the button, the Overview can be entered and exited by other means, such as
|
||||
// pressing the System key, Alt+F1 or Esc. We want the button to be pressed in when the Overview is entered
|
||||
// and to be released when it is exited regardless of how it was triggered.
|
||||
Main.overlay.connect('showing', Lang.bind(this.button, this.button.pressIn));
|
||||
Main.overlay.connect('hiding', Lang.bind(this.button, this.button.release));
|
||||
Main.overview.connect('showing', Lang.bind(this.button, this.button.pressIn));
|
||||
Main.overview.connect('hiding', Lang.bind(this.button, this.button.release));
|
||||
|
||||
this.actor.add_actor(box);
|
||||
|
||||
Main.chrome.addActor(this.actor, box);
|
||||
Main.chrome.setVisibleInOverlay(this.actor, true);
|
||||
Main.chrome.addActor(this.actor);
|
||||
Main.chrome.setVisibleInOverview(this.actor, true);
|
||||
|
||||
// Start the clock
|
||||
this._updateClock();
|
||||
@ -213,15 +447,40 @@ Panel.prototype = {
|
||||
displayDate.setMinutes(displayDate.getMinutes() + 1);
|
||||
msecRemaining += 60000;
|
||||
}
|
||||
this._clock.set_text(displayDate.toLocaleFormat("%a %l:%M %p"));
|
||||
/* Translators: This is a time format. */
|
||||
this._clock.set_text(displayDate.toLocaleFormat(_("%a %l:%M %p")));
|
||||
Mainloop.timeout_add(msecRemaining, Lang.bind(this, this._updateClock));
|
||||
return false;
|
||||
},
|
||||
|
||||
_onHotCornerTriggered : function() {
|
||||
if (!Main.overlay.animationInProgress) {
|
||||
Main.overlay.toggle();
|
||||
_onHotCornerEntered : function() {
|
||||
if (!this._hotCornerEntered) {
|
||||
this._hotCornerEntered = true;
|
||||
if (!Main.overview.animationInProgress) {
|
||||
Main.overview.toggle();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
_onHotCornerClicked : function() {
|
||||
if (!Main.overview.animationInProgress) {
|
||||
Main.overview.toggle();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_onHotCornerLeft : function(actor, event) {
|
||||
if (Shell.get_event_related(event) != this._hotCornerEnvirons) {
|
||||
this._hotCornerEntered = false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_onHotCornerEnvironsLeft : function(actor, event) {
|
||||
if (Shell.get_event_related(event) != this._hotCorner) {
|
||||
this._hotCornerEntered = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -10,30 +10,61 @@ const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
|
||||
const PLACES_VSPACING = 8;
|
||||
const PLACES_ICON_SIZE = 16;
|
||||
|
||||
function PlaceDisplay(name, icon, onActivate) {
|
||||
this._init(name, icon, onActivate);
|
||||
/**
|
||||
* An entry in the places menu.
|
||||
* @name: String title
|
||||
* @iconFactory: A JavaScript callback which will create an icon texture
|
||||
* @onActivate: A JavaScript callback to launch the entry
|
||||
*/
|
||||
function PlaceDisplay(name, iconFactory, onActivate) {
|
||||
this._init(name, iconFactory, onActivate);
|
||||
}
|
||||
|
||||
PlaceDisplay.prototype = {
|
||||
_init : function(name, iconTexture, onActivate) {
|
||||
_init : function(name, iconFactory, onActivate) {
|
||||
this.actor = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
reactive: true,
|
||||
spacing: 4 });
|
||||
this.actor.connect('button-press-event', Lang.bind(this, function (b, e) {
|
||||
this.actor.connect('button-release-event', Lang.bind(this, function (b, e) {
|
||||
onActivate(this);
|
||||
Main.overview.hide();
|
||||
}));
|
||||
let text = new Clutter.Text({ font_name: "Sans 14px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||
text: name });
|
||||
this.actor.append(iconTexture, Big.BoxPackFlags.NONE);
|
||||
let iconBox = new Big.Box({ y_align: Big.BoxAlignment.CENTER });
|
||||
this._icon = iconFactory();
|
||||
iconBox.append(this._icon, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(iconBox, Big.BoxPackFlags.NONE);
|
||||
this.actor.append(text, Big.BoxPackFlags.EXPAND);
|
||||
|
||||
this._iconFactory = iconFactory;
|
||||
this._onActivate = onActivate;
|
||||
|
||||
this.actor._delegate = this;
|
||||
let draggable = DND.makeDraggable(this.actor);
|
||||
},
|
||||
|
||||
getDragActorSource: function() {
|
||||
return this._icon;
|
||||
},
|
||||
|
||||
getDragActor: function(stageX, stageY) {
|
||||
return this._iconFactory();
|
||||
},
|
||||
|
||||
//// Drag and drop methods ////
|
||||
|
||||
shellWorkspaceLaunch : function() {
|
||||
this._onActivate();
|
||||
}
|
||||
};
|
||||
Signals.addSignalMethods(PlaceDisplay.prototype);
|
||||
@ -57,11 +88,13 @@ Places.prototype = {
|
||||
let homeUri = homeFile.get_uri();
|
||||
let homeLabel = Shell.util_get_label_for_uri (homeUri);
|
||||
let homeIcon = Shell.util_get_icon_for_uri (homeUri);
|
||||
let homeTexture = Shell.TextureCache.get_default().load_gicon(homeIcon, PLACES_ICON_SIZE);
|
||||
let home = new PlaceDisplay(homeLabel, homeTexture, Lang.bind(this, function() {
|
||||
Main.overlay.hide();
|
||||
Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext());
|
||||
}));
|
||||
let home = new PlaceDisplay(homeLabel,
|
||||
function() {
|
||||
return Shell.TextureCache.get_default().load_gicon(homeIcon, PLACES_ICON_SIZE);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(homeUri, Main.createAppLaunchContext());
|
||||
});
|
||||
|
||||
this._menuBox.append(home.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
@ -77,31 +110,35 @@ Places.prototype = {
|
||||
}
|
||||
|
||||
if (networkApp != null) {
|
||||
let networkIcon = networkApp.create_icon_texture(PLACES_ICON_SIZE);
|
||||
let network = new PlaceDisplay(networkApp.get_name(), networkIcon, Lang.bind(this, function () {
|
||||
Main.overlay.hide();
|
||||
networkApp.launch();
|
||||
}));
|
||||
let network = new PlaceDisplay(networkApp.get_name(),
|
||||
function() {
|
||||
return networkApp.create_icon_texture(PLACES_ICON_SIZE);
|
||||
},
|
||||
function () {
|
||||
networkApp.launch();
|
||||
});
|
||||
this._menuBox.append(network.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
let connectIcon = Shell.TextureCache.get_default().load_icon_name("applications-internet", PLACES_ICON_SIZE);
|
||||
let connect = new PlaceDisplay('Connect to...', connectIcon, Lang.bind(this, function () {
|
||||
Main.overlay.hide();
|
||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||
}));
|
||||
let connect = new PlaceDisplay('Connect to...',
|
||||
function () {
|
||||
return Shell.TextureCache.get_default().load_icon_name("applications-internet", PLACES_ICON_SIZE);
|
||||
},
|
||||
function () {
|
||||
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
|
||||
});
|
||||
this._menuBox.append(connect.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
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);
|
||||
let timeoutId = 0;
|
||||
this._bookmarkTimeoutId = 0;
|
||||
monitor.connect('changed', Lang.bind(this, function () {
|
||||
if (timeoutId > 0)
|
||||
if (this._bookmarkTimeoutId > 0)
|
||||
return;
|
||||
/* Defensive event compression */
|
||||
timeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () {
|
||||
this._timeoutId = 0;
|
||||
this._bookmarkTimeoutId = Mainloop.timeout_add(100, Lang.bind(this, function () {
|
||||
this._bookmarkTimeoutId = 0;
|
||||
this._reloadBookmarks();
|
||||
return false;
|
||||
}));
|
||||
@ -147,11 +184,14 @@ Places.prototype = {
|
||||
if (label == null)
|
||||
continue;
|
||||
let icon = Shell.util_get_icon_for_uri(bookmark);
|
||||
let iconTexture = Shell.TextureCache.get_default().load_gicon(icon, PLACES_ICON_SIZE);
|
||||
let item = new PlaceDisplay(label, iconTexture, Lang.bind(this, function() {
|
||||
Main.overlay.hide();
|
||||
Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext());
|
||||
}));
|
||||
|
||||
let item = new PlaceDisplay(label,
|
||||
function() {
|
||||
return Shell.TextureCache.get_default().load_gicon(icon, PLACES_ICON_SIZE);
|
||||
},
|
||||
function() {
|
||||
Gio.app_info_launch_default_for_uri(bookmark, Main.createAppLaunchContext());
|
||||
});
|
||||
this._dirsBox.append(item.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,13 @@
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const GLib = imports.gi.GLib;
|
||||
const Lang = imports.lang;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
@ -33,9 +36,16 @@ RunDialog.prototype = {
|
||||
|
||||
this._internalCommands = { 'lg':
|
||||
Lang.bind(this, function() {
|
||||
// Run in an idle to avoid recursive key grab problems
|
||||
Mainloop.idle_add(function() { Main.createLookingGlass().open(); });
|
||||
}),
|
||||
|
||||
|
||||
'r': Lang.bind(this, function() {
|
||||
let global = Shell.Global.get();
|
||||
global.reexec_self();
|
||||
}),
|
||||
|
||||
// Developer brain backwards compatibility
|
||||
'restart': Lang.bind(this, function() {
|
||||
let global = Shell.Global.get();
|
||||
global.reexec_self();
|
||||
@ -69,7 +79,7 @@ RunDialog.prototype = {
|
||||
|
||||
let label = new Clutter.Text({ color: BOX_TEXT_COLOR,
|
||||
font_name: '18px Sans',
|
||||
text: 'Please enter a command:' });
|
||||
text: _("Please enter a command:") });
|
||||
label.set_position(6, 6);
|
||||
boxGroup.add_actor(label);
|
||||
|
||||
@ -106,12 +116,13 @@ RunDialog.prototype = {
|
||||
if (f) {
|
||||
f();
|
||||
} else if (command) {
|
||||
var p = new Shell.Process({'args' : [command]});
|
||||
try {
|
||||
let [ok, len, args] = GLib.shell_parse_argv(command);
|
||||
let p = new Shell.Process({'args' : args});
|
||||
p.run();
|
||||
} catch (e) {
|
||||
// TODO: Give the user direct feedback.
|
||||
log('Could not run command ' + command + '.');
|
||||
log('Could not run command ' + command + ': ' + e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -120,7 +131,7 @@ RunDialog.prototype = {
|
||||
if (this._isOpen) // Already shown
|
||||
return;
|
||||
|
||||
if (!Main.startModal())
|
||||
if (!Main.beginModal())
|
||||
return;
|
||||
|
||||
this._isOpen = true;
|
||||
|
@ -9,6 +9,8 @@ const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
|
||||
@ -156,7 +158,8 @@ ClockWidget.prototype = {
|
||||
},
|
||||
|
||||
_updateText: function(time) {
|
||||
this.actor.set_text(time.toLocaleFormat("%H:%M"));
|
||||
// Translators: This is a time format.
|
||||
this.actor.set_text(time.toLocaleFormat(_("%H:%M")));
|
||||
},
|
||||
|
||||
_updateCairo: function(time) {
|
||||
@ -311,7 +314,7 @@ AppsWidget.prototype = {
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = "Applications";
|
||||
this.title = _("Applications");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
this.collapsedActor = new Big.Box({ spacing: 2});
|
||||
|
||||
@ -336,7 +339,7 @@ RecentDocsWidget.prototype = {
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = "Recent Documents";
|
||||
this.title = _("Recent Documents");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
|
||||
this._recentManager = Gtk.RecentManager.get_default();
|
||||
|
@ -85,7 +85,7 @@ WindowManager.prototype = {
|
||||
},
|
||||
|
||||
_shouldAnimate : function(actor) {
|
||||
if (Main.overlay.visible)
|
||||
if (Main.overview.visible)
|
||||
return false;
|
||||
if (actor && (actor.get_window_type() != Meta.CompWindowType.NORMAL))
|
||||
return false;
|
||||
@ -145,50 +145,13 @@ WindowManager.prototype = {
|
||||
},
|
||||
|
||||
_maximizeWindow : function(actor, targetX, targetY, targetWidth, targetHeight) {
|
||||
if (!this._shouldAnimate(actor)) {
|
||||
this._shellwm.completed_maximize(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this doesn't work very well, as simply scaling up the existing
|
||||
* window contents doesn't produce anything like the same results as
|
||||
* actually maximizing the window.
|
||||
*/
|
||||
let scaleX = targetWidth / actor.width;
|
||||
let scaleY = targetHeight / actor.height;
|
||||
let anchorX = (actor.x - targetX) * actor.width/(targetWidth - actor.width);
|
||||
let anchorY = (actor.y - targetY) * actor.height/(targetHeight - actor.height);
|
||||
|
||||
actor.move_anchor_point(anchorX, anchorY);
|
||||
|
||||
this._maximizing.push(actor);
|
||||
Tweener.addTween(actor,
|
||||
{ scale_x: scaleX,
|
||||
scale_y: scaleY,
|
||||
time: WINDOW_ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._maximizeWindowDone,
|
||||
onCompleteScope: this,
|
||||
onCompleteParams: [actor],
|
||||
onOverwrite: this._maximizeWindowOverwrite,
|
||||
onOverwriteScope: this,
|
||||
onOverwriteParams: [actor]
|
||||
});
|
||||
this._shellwm.completed_maximize(actor);
|
||||
},
|
||||
|
||||
_maximizeWindowDone : function(actor) {
|
||||
if (this._removeEffect(this._maximizing, actor)) {
|
||||
Tweener.removeTweens(actor);
|
||||
actor.set_scale(1.0, 1.0);
|
||||
actor.move_anchor_point_from_gravity(Clutter.Gravity.NORTH_WEST);
|
||||
this._shellwm.completed_maximize(actor);
|
||||
}
|
||||
},
|
||||
|
||||
_maximizeWindowOverwrite : function(actor) {
|
||||
if (this._removeEffect(this._maximizing, actor)) {
|
||||
this._shellwm.completed_maximize(actor);
|
||||
}
|
||||
},
|
||||
|
||||
_unmaximizeWindow : function(actor, targetX, targetY, targetWidth, targetHeight) {
|
||||
|
@ -11,11 +11,9 @@ const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const DND = imports.ui.dnd;
|
||||
const GenericDisplay = imports.ui.genericDisplay;
|
||||
const Main = imports.ui.main;
|
||||
const Overlay = imports.ui.overlay;
|
||||
const Overview = imports.ui.overview;
|
||||
const Panel = imports.ui.panel;
|
||||
const Tweener = imports.ui.tweener;
|
||||
|
||||
@ -274,6 +272,12 @@ Workspace.prototype = {
|
||||
|
||||
this.actor = new Clutter.Group();
|
||||
this.actor._delegate = this;
|
||||
// Auto-sizing is unreliable in the presence of ClutterClone, so rather than
|
||||
// implicitly counting on the workspace actor to be sized to the size of the
|
||||
// included desktop actor clone, set the size explicitly to the screen size.
|
||||
// See http://bugzilla.openedhand.com/show_bug.cgi?id=1755
|
||||
this.actor.width = global.screen_width;
|
||||
this.actor.height = global.screen_height;
|
||||
this.scale = 1.0;
|
||||
|
||||
let windows = global.get_windows().filter(this._isMyWindow, this);
|
||||
@ -293,16 +297,16 @@ Workspace.prototype = {
|
||||
Lang.bind(this,
|
||||
function(clone, time) {
|
||||
this._metaWorkspace.activate(time);
|
||||
Main.overlay.hide();
|
||||
Main.overview.hide();
|
||||
}));
|
||||
this.actor.add_actor(this._desktop.actor);
|
||||
|
||||
// Create clones for remaining windows that should be
|
||||
// visible in the overlay
|
||||
// visible in the Overview
|
||||
this._windows = [this._desktop];
|
||||
this._windowIcons = [ null ];
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (this._isOverlayWindow(windows[i])) {
|
||||
if (this._isOverviewWindow(windows[i])) {
|
||||
this._addWindowClone(windows[i]);
|
||||
}
|
||||
}
|
||||
@ -318,7 +322,7 @@ Workspace.prototype = {
|
||||
|
||||
this._frame = null;
|
||||
|
||||
this.leavingOverlay = false;
|
||||
this.leavingOverview = false;
|
||||
},
|
||||
|
||||
updateRemovable : function() {
|
||||
@ -346,7 +350,7 @@ Workspace.prototype = {
|
||||
this._removeButton.set_opacity(0);
|
||||
Tweener.addTween(this._removeButton,
|
||||
{ opacity: 255,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
}
|
||||
@ -357,7 +361,7 @@ Workspace.prototype = {
|
||||
if (this._visible) {
|
||||
Tweener.addTween(this._removeButton,
|
||||
{ opacity: 0,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._removeRemoveButton,
|
||||
onCompleteScope: this
|
||||
@ -398,7 +402,9 @@ Workspace.prototype = {
|
||||
|
||||
// Mark the workspace selected/not-selected
|
||||
setSelected : function(selected) {
|
||||
if (selected) {
|
||||
let global = Shell.Global.get();
|
||||
// Don't draw a frame if we only have one workspace
|
||||
if (selected && global.screen.n_workspaces > 1) {
|
||||
if (this._frame)
|
||||
return;
|
||||
|
||||
@ -428,7 +434,7 @@ Workspace.prototype = {
|
||||
this._desktop.actor.height + 2 * FRAME_SIZE / this.actor.scale_y);
|
||||
},
|
||||
|
||||
// Reposition all windows in their zoomed-to-overlay position. if workspaceZooming
|
||||
// Reposition all windows in their zoomed-to-Overview position. if workspaceZooming
|
||||
// is true, then the workspace is moving at the same time and we need to take
|
||||
// that into account
|
||||
positionWindows : function(workspaceZooming) {
|
||||
@ -460,7 +466,7 @@ Workspace.prototype = {
|
||||
scale_x: scale,
|
||||
scale_y: scale,
|
||||
workspace_relative: workspaceZooming ? this : null,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: Lang.bind(this, function() {
|
||||
this._fadeInWindowIcon(clone, icon);
|
||||
@ -494,7 +500,7 @@ Workspace.prototype = {
|
||||
icon.raise(this.actor);
|
||||
Tweener.addTween(icon,
|
||||
{ opacity: 255,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
@ -531,14 +537,14 @@ Workspace.prototype = {
|
||||
|
||||
// If metaWin.get_compositor_private() returned non-NULL, that
|
||||
// means the window still exists (and is just being moved to
|
||||
// another workspace or something), so set its overlayHint
|
||||
// another workspace or something), so set its overviewHint
|
||||
// accordingly. (If it returned NULL, then the window is being
|
||||
// destroyed; we'd like to animate this, but it's too late at
|
||||
// this point.)
|
||||
if (win) {
|
||||
let [stageX, stageY] = clone.actor.get_transformed_position();
|
||||
let [stageWidth, stageHeight] = clone.actor.get_transformed_size();
|
||||
win._overlayHint = {
|
||||
win._overviewHint = {
|
||||
x: stageX,
|
||||
y: stageY,
|
||||
scale: stageWidth / clone.actor.width
|
||||
@ -552,7 +558,7 @@ Workspace.prototype = {
|
||||
},
|
||||
|
||||
_windowAdded : function(metaWorkspace, metaWin) {
|
||||
if (this.leavingOverlay)
|
||||
if (this.leavingOverview)
|
||||
return;
|
||||
|
||||
let win = metaWin.get_compositor_private();
|
||||
@ -569,16 +575,16 @@ Workspace.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._isOverlayWindow(win))
|
||||
if (!this._isOverviewWindow(win))
|
||||
return;
|
||||
|
||||
let clone = this._addWindowClone(win);
|
||||
|
||||
if (win._overlayHint) {
|
||||
let x = (win._overlayHint.x - this.actor.x) / this.scale;
|
||||
let y = (win._overlayHint.y - this.actor.y) / this.scale;
|
||||
let scale = win._overlayHint.scale / this.scale;
|
||||
delete win._overlayHint;
|
||||
if (win._overviewHint) {
|
||||
let x = (win._overviewHint.x - this.actor.x) / this.scale;
|
||||
let y = (win._overviewHint.y - this.actor.y) / this.scale;
|
||||
let scale = win._overviewHint.scale / this.scale;
|
||||
delete win._overviewHint;
|
||||
|
||||
clone.actor.set_position (x, y);
|
||||
clone.actor.set_scale (scale, scale);
|
||||
@ -588,48 +594,50 @@ Workspace.prototype = {
|
||||
this.updateRemovable();
|
||||
},
|
||||
|
||||
// Animate the full-screen to overlay transition.
|
||||
zoomToOverlay : function() {
|
||||
// Move the workspace into size/position
|
||||
this.actor.set_position(this.fullSizeX, this.fullSizeY);
|
||||
|
||||
this.updateInOverlay();
|
||||
// Animate the full-screen to Overview transition.
|
||||
zoomToOverview : function() {
|
||||
this.actor.set_position(this.gridX, this.gridY);
|
||||
this.actor.set_scale(this.scale, this.scale);
|
||||
|
||||
// Position and scale the windows.
|
||||
this.positionWindows(true);
|
||||
|
||||
// Fade in the remove button if available, so that it doesn't appear
|
||||
// too abrubtly and doesn't start at a too big size.
|
||||
if (this._removeButton) {
|
||||
Tweener.removeTweens(this._removeButton);
|
||||
this._removeButton.opacity = 0;
|
||||
Tweener.addTween(this._removeButton,
|
||||
{ opacity: 255,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
|
||||
this._visible = true;
|
||||
},
|
||||
|
||||
// Animates the display of a workspace and its windows to have the current dimensions and position.
|
||||
updateInOverlay : function() {
|
||||
Tweener.addTween(this.actor,
|
||||
{ x: this.gridX,
|
||||
y: this.gridY,
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
|
||||
// Likewise for each of the windows in the workspace.
|
||||
this.positionWindows(true);
|
||||
},
|
||||
|
||||
// Animates the return from overlay mode
|
||||
zoomFromOverlay : function() {
|
||||
this.leavingOverlay = true;
|
||||
// Animates the return from Overview mode
|
||||
zoomFromOverview : function() {
|
||||
this.leavingOverview = true;
|
||||
|
||||
this._hideAllIcons();
|
||||
|
||||
Tweener.addTween(this.actor,
|
||||
{ x: this.fullSizeX,
|
||||
y: this.fullSizeY,
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._doneLeavingOverlay,
|
||||
onCompleteScope: this
|
||||
});
|
||||
Main.overview.connect('hidden', Lang.bind(this,
|
||||
this._doneLeavingOverview));
|
||||
|
||||
// Fade out the remove button if available, so that it doesn't
|
||||
// disappear too abrubtly and doesn't become too big.
|
||||
if (this._removeButton) {
|
||||
Tweener.removeTweens(this._removeButton);
|
||||
Tweener.addTween(this._removeButton,
|
||||
{ opacity: 0,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: 'easeOutQuad'
|
||||
});
|
||||
}
|
||||
|
||||
// Position and scale the windows.
|
||||
for (let i = 1; i < this._windows.length; i++) {
|
||||
let clone = this._windows[i];
|
||||
Tweener.addTween(clone.actor,
|
||||
@ -638,7 +646,7 @@ Workspace.prototype = {
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
workspace_relative: this,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
opacity: 255,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
@ -656,7 +664,7 @@ Workspace.prototype = {
|
||||
y: this.gridY,
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: Lang.bind(this, this._fadeInAllIcons)
|
||||
});
|
||||
@ -678,7 +686,7 @@ Workspace.prototype = {
|
||||
y: this.gridY,
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad"
|
||||
});
|
||||
|
||||
@ -701,7 +709,7 @@ Workspace.prototype = {
|
||||
y: destY,
|
||||
scale_x: this.scale,
|
||||
scale_y: this.scale,
|
||||
time: Overlay.ANIMATION_TIME,
|
||||
time: Overview.ANIMATION_TIME,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: onComplete
|
||||
});
|
||||
@ -724,9 +732,9 @@ Workspace.prototype = {
|
||||
this._metaWorkspace.disconnect(this._windowRemovedId);
|
||||
},
|
||||
|
||||
// Sets this.leavingOverlay flag to false.
|
||||
_doneLeavingOverlay : function() {
|
||||
this.leavingOverlay = false;
|
||||
// Sets this.leavingOverview flag to false.
|
||||
_doneLeavingOverview : function() {
|
||||
this.leavingOverview = false;
|
||||
},
|
||||
|
||||
// Tests if @win belongs to this workspaces
|
||||
@ -735,8 +743,8 @@ Workspace.prototype = {
|
||||
(win.get_meta_window() && win.get_meta_window().is_on_all_workspaces());
|
||||
},
|
||||
|
||||
// Tests if @win should be shown in the overlay
|
||||
_isOverlayWindow : function (win) {
|
||||
// Tests if @win should be shown in the Overview
|
||||
_isOverviewWindow : function (win) {
|
||||
let wintype = win.get_window_type();
|
||||
if (wintype == Meta.WindowType.DESKTOP ||
|
||||
wintype == Meta.WindowType.DOCK)
|
||||
@ -811,7 +819,7 @@ Workspace.prototype = {
|
||||
},
|
||||
|
||||
_onCloneSelected : function (clone, time) {
|
||||
Main.overlay.activateWindow(clone.metaWindow, time);
|
||||
Main.overview.activateWindow(clone.metaWindow, time);
|
||||
},
|
||||
|
||||
_removeSelf : function(actor, event) {
|
||||
@ -834,7 +842,7 @@ Workspace.prototype = {
|
||||
|
||||
// Set a hint on the Mutter.Window so its initial position
|
||||
// in the new workspace will be correct
|
||||
win._overlayHint = {
|
||||
win._overviewHint = {
|
||||
x: actor.x,
|
||||
y: actor.y,
|
||||
scale: actor.scale_x
|
||||
@ -845,9 +853,9 @@ Workspace.prototype = {
|
||||
false, // don't create workspace
|
||||
time);
|
||||
return true;
|
||||
} else if (source instanceof GenericDisplay.GenericDisplayItem || source instanceof AppDisplay.WellDisplayItem) {
|
||||
} else if (source.shellWorkspaceLaunch) {
|
||||
this._metaWorkspace.activate(time);
|
||||
source.launch();
|
||||
source.shellWorkspaceLaunch();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -890,25 +898,28 @@ Workspaces.prototype = {
|
||||
activeWorkspace.actor.raise_top();
|
||||
this._positionWorkspaces(global, activeWorkspace);
|
||||
|
||||
// Create (+) button
|
||||
// Save the button size as a global variable so we can us it to create
|
||||
// matching button sizes for workspace remove buttons.
|
||||
buttonSize = addButtonSize;
|
||||
this.addButton = new Clutter.Texture({ x: addButtonX,
|
||||
y: addButtonY,
|
||||
width: buttonSize,
|
||||
height: buttonSize,
|
||||
reactive: true
|
||||
});
|
||||
this.addButton.set_from_file(global.imagedir + "add-workspace.svg");
|
||||
this.addButton.connect('button-release-event', this._appendNewWorkspace);
|
||||
this.actor.add_actor(this.addButton);
|
||||
this.addButton.lower_bottom();
|
||||
|
||||
// Create (+) button
|
||||
this.addButton = new AddWorkspaceButton(addButtonSize, addButtonX, addButtonY, Lang.bind(this, this._addWorkspaceAcceptDrop));
|
||||
this.addButton.actor.connect('button-release-event', Lang.bind(this, this._appendNewWorkspace));
|
||||
this.actor.add_actor(this.addButton.actor);
|
||||
this.addButton.actor.lower_bottom();
|
||||
|
||||
let lastWorkspace = this._workspaces[this._workspaces.length - 1];
|
||||
lastWorkspace.updateRemovable(true);
|
||||
|
||||
// Position/scale the desktop windows and their children
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomToOverlay();
|
||||
// Position/scale the desktop windows and their children after the
|
||||
// workspaces have been created. This cannot be done first because
|
||||
// window movement depends on the Workspaces object being accessible
|
||||
// as an Overview member.
|
||||
Main.overview.connect('showing',
|
||||
Lang.bind(this, function() {
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomToOverview();
|
||||
}));
|
||||
|
||||
// Track changes to the number of workspaces
|
||||
this._nWorkspacesNotifyId =
|
||||
@ -928,8 +939,8 @@ Workspaces.prototype = {
|
||||
return null;
|
||||
},
|
||||
|
||||
// Should only be called from active overlay context
|
||||
activateWindowFromOverlay: function (metaWindow, time) {
|
||||
// Should only be called from active Overview context
|
||||
activateWindowFromOverview: function (metaWindow, time) {
|
||||
let global = Shell.Global.get();
|
||||
let activeWorkspaceNum = global.screen.get_active_workspace_index();
|
||||
let windowWorkspaceNum = metaWindow.get_workspace().index();
|
||||
@ -945,17 +956,6 @@ Workspaces.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
// Updates position of the workspaces display based on the new coordinates.
|
||||
// Preserves the old value for the coordinate, if the passed value is null.
|
||||
updatePosition : function(x, y) {
|
||||
if (x != null)
|
||||
this._x = x;
|
||||
if (y != null)
|
||||
this._y = y;
|
||||
|
||||
this._updateInOverlay();
|
||||
},
|
||||
|
||||
hide : function() {
|
||||
let global = Shell.Global.get();
|
||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
@ -965,7 +965,7 @@ Workspaces.prototype = {
|
||||
activeWorkspace.actor.raise_top();
|
||||
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].zoomFromOverlay();
|
||||
this._workspaces[w].zoomFromOverview();
|
||||
},
|
||||
|
||||
destroy : function() {
|
||||
@ -982,35 +982,17 @@ Workspaces.prototype = {
|
||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||
},
|
||||
|
||||
getFullSizeX : function() {
|
||||
return this._workspaces[0].fullSizeX;
|
||||
getScale : function() {
|
||||
return this._workspaces[0].scale;
|
||||
},
|
||||
|
||||
// If j-th workspace in the i-th row is active, returns the full width
|
||||
// of j workspaces including empty space if i = 1, or the width of one
|
||||
// workspace.
|
||||
// Used in overlay.js to determine when it is ok to remove the sideshow
|
||||
// during animations for entering and leaving the overlay.
|
||||
getWidthToTopActiveWorkspace : function() {
|
||||
// Get the grid position of the active workspace.
|
||||
getActiveWorkspacePosition : function() {
|
||||
let global = Shell.Global.get();
|
||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
||||
let activeWorkspace = this._workspaces[activeWorkspaceIndex];
|
||||
|
||||
if (activeWorkspace.gridRow == 0)
|
||||
return (activeWorkspace.gridCol + 1) * global.screen_width + activeWorkspace.gridCol * GRID_SPACING;
|
||||
else
|
||||
return global.screen_width;
|
||||
},
|
||||
|
||||
// Updates the workspaces display based on the current dimensions and position.
|
||||
_updateInOverlay : function() {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
this._positionWorkspaces(global);
|
||||
|
||||
// Position/scale the desktop windows and their children
|
||||
for (let w = 0; w < this._workspaces.length; w++)
|
||||
this._workspaces[w].updateInOverlay();
|
||||
return [activeWorkspace.gridX, activeWorkspace.gridY];
|
||||
},
|
||||
|
||||
// Assign grid positions to workspaces. We can't just do a simple
|
||||
@ -1063,14 +1045,6 @@ Workspaces.prototype = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now figure out their full-size coordinates
|
||||
for (let w = 0; w < this._workspaces.length; w++) {
|
||||
let workspace = this._workspaces[w];
|
||||
|
||||
workspace.fullSizeX = (workspace.gridCol - activeWorkspace.gridCol) * (global.screen_width + GRID_SPACING);
|
||||
workspace.fullSizeY = (workspace.gridRow - activeWorkspace.gridRow) * (global.screen_height + GRID_SPACING);
|
||||
}
|
||||
},
|
||||
|
||||
_workspacesChanged : function() {
|
||||
@ -1141,6 +1115,11 @@ Workspaces.prototype = {
|
||||
|
||||
// FIXME: deal with windows on the lost workspaces
|
||||
}
|
||||
|
||||
// Reset the selection state; if we went from > 1 workspace to 1,
|
||||
// this has the side effect of removing the frame border
|
||||
let activeIndex = global.screen.get_active_workspace_index();
|
||||
this._workspaces[activeIndex].setSelected(true);
|
||||
},
|
||||
|
||||
_activeWorkspaceChanged : function(wm, from, to, direction) {
|
||||
@ -1154,10 +1133,39 @@ Workspaces.prototype = {
|
||||
this.actor.add_actor(workspace.actor);
|
||||
},
|
||||
|
||||
_appendNewWorkspace : function(actor, event) {
|
||||
_appendNewWorkspace : function() {
|
||||
let global = Shell.Global.get();
|
||||
|
||||
global.screen.append_new_workspace(false, event.get_time());
|
||||
global.screen.append_new_workspace(false, global.screen.get_display().get_current_time());
|
||||
},
|
||||
|
||||
// Creates a new workspace and drops the dropActor there
|
||||
_addWorkspaceAcceptDrop : function(source, dropActor, x, y, time) {
|
||||
this._appendNewWorkspace();
|
||||
return this._workspaces[this._workspaces.length - 1].acceptDrop(source, dropActor, x, y, time);
|
||||
}
|
||||
};
|
||||
|
||||
function AddWorkspaceButton(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
||||
this._init(buttonSize, buttonX, buttonY, acceptDropCallback);
|
||||
}
|
||||
|
||||
AddWorkspaceButton.prototype = {
|
||||
_init : function(buttonSize, buttonX, buttonY, acceptDropCallback) {
|
||||
this.actor = new Clutter.Texture({ x: buttonX,
|
||||
y: buttonY,
|
||||
width: buttonSize,
|
||||
height: buttonSize,
|
||||
reactive: true });
|
||||
this._acceptDropCallback = acceptDropCallback;
|
||||
let global = Shell.Global.get();
|
||||
this.actor._delegate = this;
|
||||
this.actor.set_from_file(global.imagedir + 'add-workspace.svg');
|
||||
},
|
||||
|
||||
// Draggable target interface
|
||||
acceptDrop : function(source, actor, x, y, time) {
|
||||
return this._acceptDropCallback(source, actor, x, y, time);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1167,28 +1175,49 @@ Workspaces.prototype = {
|
||||
Tweener.registerSpecialPropertyModifier("workspace_relative", _workspaceRelativeModifier, _workspaceRelativeGet);
|
||||
|
||||
function _workspaceRelativeModifier(workspace) {
|
||||
let endX, endY;
|
||||
let [startX, startY] = Main.overview.getPosition();
|
||||
let overviewPosX, overviewPosY, overviewScale;
|
||||
|
||||
if (!workspace)
|
||||
return [];
|
||||
|
||||
if (workspace.leavingOverlay) {
|
||||
endX = workspace.fullSizeX;
|
||||
endY = workspace.fullSizeY;
|
||||
if (workspace.leavingOverview) {
|
||||
let [zoomedInX, zoomedInY] = Main.overview.getZoomedInPosition();
|
||||
overviewPosX = { begin: startX, end: zoomedInX };
|
||||
overviewPosY = { begin: startY, end: zoomedInY };
|
||||
overviewScale = { begin: Main.overview.getScale(),
|
||||
end: Main.overview.getZoomedInScale() };
|
||||
} else {
|
||||
endX = workspace.gridX;
|
||||
endY = workspace.gridY;
|
||||
overviewPosX = { begin: startX, end: 0 };
|
||||
overviewPosY = { begin: startY, end: 0 };
|
||||
overviewScale = { begin: Main.overview.getScale(), end: 1 };
|
||||
}
|
||||
|
||||
return [ { name: "x",
|
||||
parameters: { begin: workspace.actor.x, end: endX,
|
||||
cur: function() { return workspace.actor.x; } } },
|
||||
parameters: { workspacePos: workspace.gridX,
|
||||
overviewPos: overviewPosX,
|
||||
overviewScale: overviewScale } },
|
||||
{ name: "y",
|
||||
parameters: { begin: workspace.actor.y, end: endY,
|
||||
cur: function() { return workspace.actor.y; } } }
|
||||
parameters: { workspacePos: workspace.gridY,
|
||||
overviewPos: overviewPosY,
|
||||
overviewScale: overviewScale } }
|
||||
];
|
||||
}
|
||||
|
||||
function _workspaceRelativeGet(begin, end, time, params) {
|
||||
return (begin + params.begin) + time * (end + params.end - (begin + params.begin)) - params.cur();
|
||||
let curOverviewPos = (1 - time) * params.overviewPos.begin +
|
||||
time * params.overviewPos.end;
|
||||
let curOverviewScale = (1 - time) * params.overviewScale.begin +
|
||||
time * params.overviewScale.end;
|
||||
|
||||
// Calculate the screen position of the window.
|
||||
let screen = (1 - time) *
|
||||
((begin + params.workspacePos) * params.overviewScale.begin +
|
||||
params.overviewPos.begin) +
|
||||
time *
|
||||
((end + params.workspacePos) * params.overviewScale.end +
|
||||
params.overviewPos.end);
|
||||
|
||||
// Return the workspace coordinates.
|
||||
return (screen - curOverviewPos) / curOverviewScale - params.workspacePos;
|
||||
}
|
||||
|
16
po/LINGUAS
Normal file
16
po/LINGUAS
Normal file
@ -0,0 +1,16 @@
|
||||
ca
|
||||
cs
|
||||
de
|
||||
es
|
||||
fr
|
||||
ga
|
||||
gl
|
||||
hu
|
||||
it
|
||||
ko
|
||||
nb
|
||||
nl
|
||||
pl
|
||||
pt_BR
|
||||
sv
|
||||
tr
|
9
po/POTFILES.in
Normal file
9
po/POTFILES.in
Normal file
@ -0,0 +1,9 @@
|
||||
data/gnome-shell.desktop.in.in
|
||||
js/ui/panel.js
|
||||
js/ui/dash.js
|
||||
js/ui/overview.js
|
||||
js/ui/runDialog.js
|
||||
src/gdmuser/gdm-user.c
|
||||
src/shell-global.c
|
||||
src/shell-status-menu.c
|
||||
src/shell-uri-util.c
|
1
po/POTFILES.skip
Normal file
1
po/POTFILES.skip
Normal file
@ -0,0 +1 @@
|
||||
data/gnome-shell.desktop.in
|
147
po/ca.po
Normal file
147
po/ca.po
Normal file
@ -0,0 +1,147 @@
|
||||
# Catalan gnome-shell translation.
|
||||
# Copyright (C) 2009 Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-14 20:38+0200\n"
|
||||
"PO-Revision-Date: 2009-08-14 23:59+0100\n"
|
||||
"Last-Translator: Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language-Team: \n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Activitats"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Cerca aplicacions o documents"
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Navega"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472
|
||||
#: ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477
|
||||
#: ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTS RECENTS"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "LLOCS"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduïu una ordre:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Gestor"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "L'objecte gestor d'usuaris que controla a aquest usuari."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Fa menys d'un minut"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "Fa %d minut"
|
||||
msgstr[1] "Fa %d minuts"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "Fa %d hora"
|
||||
msgstr[1] "Fa %d hores"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "Fa %d dia"
|
||||
msgstr[1] "Fa %d dies"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Fa %d setmana"
|
||||
msgstr[1] "Fa %d setmanes"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Desconegut"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "No es pot blocar la pantalla: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "No es pot establir temporalment l'estalviador de pantalles a pantalla negra: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "No es pot sortir: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informació del compte..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferències del sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloca la pantalla"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Canvia d'usuari"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Surt..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Atura..."
|
||||
|
184
po/cs.po
Normal file
184
po/cs.po
Normal file
@ -0,0 +1,184 @@
|
||||
# Czech translation of gnome-shell.
|
||||
# Copyright (C) 2009 gnome-shell's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Andre Klapper <ak-47@gmx.net>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-15 15:25+0200\n"
|
||||
"PO-Revision-Date: 2009-08-15 13:23+0000\n"
|
||||
"Last-Translator: Andre Klapper <ak-47@gmx.net>\n"
|
||||
"Language-Team: Czech <gnome-cs-list@gnome.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==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr ""
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
#, fuzzy
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Správa oken"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
#, fuzzy
|
||||
msgid "Browse"
|
||||
msgstr "Procházet"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLIKACE"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "NEDÁVNÉ DOKUMENTY"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "MÍSTA"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr ""
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Správce"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "Objekt správce uživatele, kterým je tento uživatel ovládán."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
#, fuzzy
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Dříve než před minutou"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuta nazpět"
|
||||
msgstr[1] "%d minuty nazpět"
|
||||
msgstr[2] "%d minut nazpět"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d hodina nazpět"
|
||||
msgstr[1] "%d hodiny nazpět"
|
||||
msgstr[2] "%d hodin nazpět"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d den nazpět"
|
||||
msgstr[1] "%d dny nazpět"
|
||||
msgstr[2] "%d dnů nazpět"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d týden nazpět"
|
||||
msgstr[1] "%d týdny nazpět"
|
||||
msgstr[2] "%d týdnů nazpět"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Neznámé"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nelze uzamknout obrazovku: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Šetřič obrazovky nelze dočasně nastavit na prázdnou obrazovku: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nelze se odhlásit: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informace o účtu..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
#, fuzzy
|
||||
msgid "Sidebar"
|
||||
msgstr "Boční panel"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Předvolby systému..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Uzamknout obrazovku"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Přepnout uživatele"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Odhlásit..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Vypnout..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Domovská složka"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Systém souborů"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Hledat"
|
||||
|
||||
#. 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
|
||||
#, fuzzy, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
182
po/de.po
Normal file
182
po/de.po
Normal file
@ -0,0 +1,182 @@
|
||||
# German gnome-shell translation.
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Hendrik Brandt <heb@gnome-de.org>, 2009.
|
||||
# Hendrik Richter <hendrikr@gnome.org>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: HEAD\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-20 16:47+0200\n"
|
||||
"PO-Revision-Date: 2009-08-20 16:49+0200\n"
|
||||
"Last-Translator: Hendrik Richter <hendrikr@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: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\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 "Fenster verwalten und Anwendungen starten"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Aktivitäten"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:251
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Anwendungen oder Dokumente suchen"
|
||||
|
||||
#: ../js/ui/dash.js:369
|
||||
msgid "Browse"
|
||||
msgstr "Durchsuchen"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:505 ../js/ui/dash.js:578
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ANWENDUNGEN"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:510 ../js/ui/dash.js:605
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "ZULETZT GEÖFFNETE DOKUMENTE"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:598
|
||||
msgid "PLACES"
|
||||
msgstr "ORTE"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Bitte geben Sie einen Befehl ein:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "Manager"
|
||||
msgstr "Verwaltung"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:244
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "Das Benutzerverwaltungsobjekt welches diesen Benutzer überwacht."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Vor weniger als einer Minute"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Vor %d Woche"
|
||||
msgstr[1] "Vor %d Wochen"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Unbekannt"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Bildschirm kann nicht gesperrt werden: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Der Bildschirmschoner kann vorübergehend nicht auf einen leeren Schirm "
|
||||
"gesetzt werden: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Abmelden ist nicht möglich: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Benutzerinformationen …"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Seitenleiste"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systemeinstellungen …"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bildschirm sperren"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Benutzer wechseln"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Abmelden …"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Ausschalten …"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Persönlicher Ordner"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Dateisystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Suchen"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
189
po/es.po
Normal file
189
po/es.po
Normal file
@ -0,0 +1,189 @@
|
||||
# Spanish translation of gnome-shell.
|
||||
# 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.
|
||||
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-08-21 22:23+0000\n"
|
||||
"PO-Revision-Date: 2009-08-22 12:21+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"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\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 "Gestión de ventanas e inicio de aplicaciones"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Encuentre aplicaciones o documentos"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Examine"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:556 ../js/ui/dash.js:606
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICACIONES"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:576
|
||||
msgid "PLACES"
|
||||
msgstr "LUGARES"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:583
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECIENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:602
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "RESULTADOS DE LA BÚSQUEDA"
|
||||
|
||||
#: ../js/ui/dash.js:615
|
||||
#| msgid "RECENT DOCUMENTS"
|
||||
msgid "DOCUMENTS"
|
||||
msgstr "DOCUMENTOS"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Introduzca un comando:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Hace menos de un minuto"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "Hace %d semana"
|
||||
msgstr[1] "Hace %d semanas"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Desconocido"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "No se puede bloquear la pantalla: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"No se puede establecer temporalmente el salvapantallas a oscurecer pantalla: "
|
||||
"%s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "No se puede salir de la sesión: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Información de la cuenta…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencias del sistema…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear la pantalla"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Salir…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar…"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Carpeta personal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Sistema de archivos"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Gestor"
|
||||
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "El objeto de gestión de usuarios que controla a este usuario."
|
21
po/fr.po
Normal file
21
po/fr.po
Normal file
@ -0,0 +1,21 @@
|
||||
# French translations for gnome-shell package.
|
||||
# Copyright (C) 2009 THE gnome-shell'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Colin Walters <walters@verbum.org>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-07-27 15:09-0400\n"
|
||||
"PO-Revision-Date: 2009-07-27 15:23-0400\n"
|
||||
"Last-Translator: Colin Walters <walters@verbum.org>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: ../js/ui/panel.js:74
|
||||
msgid "Activities"
|
||||
msgstr "Activités"
|
181
po/ga.po
Normal file
181
po/ga.po
Normal file
@ -0,0 +1,181 @@
|
||||
# Irish translations for gnome-shell package.
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Seán de Búrca <leftmostcat@gmail.com>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell.master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-15 06:01-0600\n"
|
||||
"PO-Revision-Date: 2009-08-15 06:01-0600\n"
|
||||
"Last-Translator: Seán de Búrca <leftmostcat@gmail.com>\n"
|
||||
"Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=5; plural=n==1 ? 0 : (n%10==1 || n%10==2) ? 1 : (n%"
|
||||
"10>=3 && n%10<= 6) ? 2 : ((n%10>=7 && n%10<=9) || n==10) ? 3 : 4;\n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Gníomhartha"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Aimsigh feidhmchláir nó cáipéisí"
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Brabhsáil"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "FEIDHMCHLÁIR"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "CÁIPÉISÍ IS DÉANAÍ"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "ÁITEANNA"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Iontráil ordú, le do thoil:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Bainisteoir"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "An réad bhainisteoir úsáideoirí a rialaíonn an t-úsáideoir seo."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Níos lú ná nóiméad ó shin"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d nóiméad ó shin"
|
||||
msgstr[1] "%d nóiméad ó shin"
|
||||
msgstr[2] "%d nóiméad ó shin"
|
||||
msgstr[3] "%d nóiméad ó shin"
|
||||
msgstr[4] "%d nóiméad ó shin"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d uair ó shin"
|
||||
msgstr[1] "%d uair ó shin"
|
||||
msgstr[2] "%d uaire ó shin"
|
||||
msgstr[3] "%d n-uaire ó shin"
|
||||
msgstr[4] "%d uair ó shin"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d lá ó shin"
|
||||
msgstr[1] "%d lá ó shin"
|
||||
msgstr[2] "%d lá ó shin"
|
||||
msgstr[3] "%d lá ó shin"
|
||||
msgstr[4] "%d lá ó shin"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d seachtain ó shin"
|
||||
msgstr[1] "%d sheachtain ó shin"
|
||||
msgstr[2] "%d sheachtain ó shin"
|
||||
msgstr[3] "%d seachtain ó shin"
|
||||
msgstr[4] "%d seachtain ó shin"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Anaithnid"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Ní féidir scáileán a chur faoi ghlas: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Ní féidir spárálaí scáileáin a shocrú chun scáileán a bhánú: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Ní féidir logáil amach: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Eolas Cuntais..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra Taoibh"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Sainroghanna an Chórais..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Cuir Scáileán Faoi Ghlas"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Athraigh Úsáideoir"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Logáil Amach..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Múch..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Fillteán Baile"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Córas Comhad"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Cuardaigh"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
184
po/gl.po
Normal file
184
po/gl.po
Normal file
@ -0,0 +1,184 @@
|
||||
# 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.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-22 16:39+0200\n"
|
||||
"PO-Revision-Date: 2009-08-18 21:20+0100\n"
|
||||
"Last-Translator: Fran Diéguez <fran.dieguez@glug.es>\n"
|
||||
"Language-Team: Galician <gnome@mancomun.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../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 "Xestor de xanelas e lanzado de aplicativos"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Actividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Atopar aplicativos ou documentos"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Explorar"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:556 ../js/ui/dash.js:606
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:576
|
||||
msgid "PLACES"
|
||||
msgstr "LUGARES"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:583
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:602
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr ""
|
||||
|
||||
#: ../js/ui/dash.js:615
|
||||
#, fuzzy
|
||||
msgid "DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Insira unha orde:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Menos de un minuto"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "fai %d minuto"
|
||||
msgstr[1] "fai %d minutos"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "fai %d hora"
|
||||
msgstr[1] "fai %d horas"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "fai %d día"
|
||||
msgstr[1] "fai %d días"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "fai %d semana"
|
||||
msgstr[1] "fai %d semanas"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Descoñecido"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Non foi posíbel bloquear a pantalla: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Non foi posíbel establecer o salvapantallas a unha pantalla en branco: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Non foi posíbel pechar a sesión: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Información da conta..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra lateral"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferenzas do sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Bloquear pantalla"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambiar de usuario"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Pechar sesión..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Apagar..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Cartafol persoal"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Sistema de ficheiros"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Xestor"
|
180
po/hu.po
Normal file
180
po/hu.po
Normal file
@ -0,0 +1,180 @@
|
||||
# Hungarian translation of gnome-shell
|
||||
# Copyright 2009. Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Gabor Kelemen <kelemeng at gnome dot hu>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-15 11:35+0200\n"
|
||||
"PO-Revision-Date: 2009-08-15 11:35+0200\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"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Tevékenységek"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a., %k.%M"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Alkalmazások vagy dokumentumok keresése"
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Tallózás"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "ALKALMAZÁSOK"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "LEGUTÓBBI DOKUMENTUMOK"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "HELYEK"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Adjon meg egy parancsot:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Kezelő"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "A felhasználót kezelő felhasználókezelő objektum."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Kevesebb, mint egy perce"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d perce"
|
||||
msgstr[1] "%d perce"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, 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:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d napja"
|
||||
msgstr[1] "%d napja"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d hete"
|
||||
msgstr[1] "%d hete"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Ismeretlen"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nem lehet zárolni a képernyőt: %s "
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Átmenetileg nem lehet beállítani a képernyővédőt a képernyő elsötétítésére: %"
|
||||
"s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nem lehet kijelentkezni: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Fiókinformációk…"
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Oldalsáv"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Rendszerbeállítások…"
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Képernyő zárolása"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Felhasználóváltás"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Kijelentkezés…"
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Leállítás…"
|
||||
|
||||
#: ../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 "Ablakkezelés és alkalmazásindítás"
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Saját mappa"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Fájlrendszer"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Oldalsáv"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
184
po/it.po
Normal file
184
po/it.po
Normal file
@ -0,0 +1,184 @@
|
||||
# Italian translations for gnome-shell package.
|
||||
# Copyright (C) 2009 the gnome-shell copyright holder
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Milo Casagrande <milo@ubuntu.com>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-20 23:25+0200\n"
|
||||
"PO-Revision-Date: 2009-08-20 23:26+0200\n"
|
||||
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
|
||||
"Language-Team: Italian <tp@lists.linux.it>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../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 "Gestione finestre e avvio applicazioni"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Attività"
|
||||
|
||||
# (ndt) proviamo col k, se non funge, sappiamo il perché...
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k.%M"
|
||||
|
||||
# (ndt) è da valutare se è troppo lunga, è in una casella di ricerca
|
||||
#: ../js/ui/dash.js:251
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Trova programmi e documenti"
|
||||
|
||||
#: ../js/ui/dash.js:369
|
||||
msgid "Browse"
|
||||
msgstr "Esplora"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:505 ../js/ui/dash.js:578
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Applicazioni"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:510 ../js/ui/dash.js:605
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "Documenti recenti"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:598
|
||||
msgid "PLACES"
|
||||
msgstr "Risorse"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Inserire un comando:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Meno di un minuto fa"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d settimana fa"
|
||||
msgstr[1] "%d settimane fa"
|
||||
|
||||
# (ndt) valutare se vada al femminile
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Sconosciuto"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Impossibile bloccare lo schermo: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Impossibile impostare temporaneamente il salva schermo a schermo nero: %s "
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Impossibile terminare la sessione: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informazioni account..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Barra laterale"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferenze di sistema..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Blocca schermo"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Cambia utente"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Termina sessione..."
|
||||
|
||||
# (ndt) da valutare... pare che ora anche Windows usi 'Arresta...'...
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Spegni..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Cartella home"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "File system"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Cerca"
|
||||
|
||||
# (ndt) valutare...
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
# (ndt) no idea...
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Manager"
|
||||
|
||||
# (ndt) no idea...
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "L'oggetto user manager che controlla questo utente."
|
166
po/ko.po
Normal file
166
po/ko.po
Normal file
@ -0,0 +1,166 @@
|
||||
# gnome-shell korean translation.
|
||||
# Copyright (C) 2009 THE gnome-shell'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Young-Ho Cha <ganadist@gmail.com>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-21 10:09+0900\n"
|
||||
"PO-Revision-Date: 2009-08-21 10:10+0900\n"
|
||||
"Last-Translator: Young-Ho Cha <ganadist@gmail.com>\n"
|
||||
"Language-Team: GNOME Korea <gnome-kr-hackers@lists.kldp.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "그놈 쉘"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "창 관리와 프로그램 시작"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%A %p %l:%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "프로그램과 문서를 찾습니다"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "찾아보기"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:504 ../js/ui/dash.js:577
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "프로그램"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:509 ../js/ui/dash.js:604
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "최근 문서"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:597
|
||||
msgid "PLACES"
|
||||
msgstr "위치"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "명령을 입력하십시오:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "1분 이내"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d분 전"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d시간 전"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d일 전"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%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
|
||||
msgid "Home Folder"
|
||||
msgstr "내 폴더"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "파일시스템"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
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:298
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%s: %s"
|
170
po/nb.po
Normal file
170
po/nb.po
Normal file
@ -0,0 +1,170 @@
|
||||
# Norwegian bokmål translation of gnome-shell.
|
||||
# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Kjartan Maraas <kmaraas@broadpark.no>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell 0.4\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-21 12:36+0200\n"
|
||||
"PO-Revision-Date: 2009-08-21 12:44+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"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\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 "Vindushåndtering og oppstart av programmer"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Finn programmer eller dokumenter"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Bla gjennom"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:504 ../js/ui/dash.js:577
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAMMER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:509 ../js/ui/dash.js:604
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SISTE DOKUMENTER"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:597
|
||||
msgid "PLACES"
|
||||
msgstr "STEDER"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Oppgi en kommando:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre enn ett minutt siden"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d uke siden"
|
||||
msgstr[1] "%d uker siden"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Ukjent"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Kan ikke låse skjermen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Kan ikke sette skjermsparer midlertidig til blank skjerm: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Kan ikke logge ut: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Kontoinformasjon..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Sidelinje"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Brukervalg for systemet..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lås skjerm"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Bytt bruker"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Logg ut..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Slå av..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Hjemmemappe"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Filsystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Søk"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
179
po/nl.po
Normal file
179
po/nl.po
Normal file
@ -0,0 +1,179 @@
|
||||
# Dutch translation for gnome-shell
|
||||
#
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Sander Dijkhuis <sander.dijkhuis@gmail.com>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-24 22:30+0200\n"
|
||||
"PO-Revision-Date: 2009-08-24 22:38+0200\n"
|
||||
"Last-Translator: Sander Dijkhuis <sander.dijkhuis@gmail.com>\n"
|
||||
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../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 "Vensterbeheer en toepassingen starten"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Activiteiten"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %k:%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Zoeken"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Bladeren"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:556 ../js/ui/dash.js:606
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "TOEPASSINGEN"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:576
|
||||
msgid "PLACES"
|
||||
msgstr "LOCATIES"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:583
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "RECENTE DOCUMENTEN"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:602
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "ZOEKRESULTATEN"
|
||||
|
||||
#: ../js/ui/dash.js:615
|
||||
msgid "DOCUMENTS"
|
||||
msgstr "DOCUMENTEN"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Voer een opdracht in:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Korter dan een minuut geleden"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, 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
|
||||
msgid "Home Folder"
|
||||
msgstr "Persoonlijke map"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Bestandssysteem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Zoeken"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
187
po/pl.po
Normal file
187
po/pl.po
Normal file
@ -0,0 +1,187 @@
|
||||
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
# Aviary.pl
|
||||
# Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz
|
||||
# pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas:
|
||||
# gnomepl@aviary.pl
|
||||
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-18 23:25+0200\n"
|
||||
"PO-Revision-Date: 2009-08-18 23:23+0100\n"
|
||||
"Last-Translator: Tomasz Dominikowski <dominikowski@gmail.com>\n"
|
||||
"Language-Team: Polish <gnomepl@aviary.pl>\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==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
"X-Poedit-Language: Polish\n"
|
||||
"X-Poedit-Country: Poland\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "Powłoka środowiska GNOME"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Zarządzanie oknami i uruchamianiem programów"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Czynności"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a, %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:251
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Wyszukuje programy lub dokumenty"
|
||||
|
||||
#: ../js/ui/dash.js:369
|
||||
msgid "Browse"
|
||||
msgstr "Przeglądaj"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:505 ../js/ui/dash.js:578
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "Programy"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:510 ../js/ui/dash.js:605
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "Ostatnie dokumenty"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:598
|
||||
msgid "PLACES"
|
||||
msgstr "Miejsca"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Proszę wprowadzić polecenie:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "Manager"
|
||||
msgstr "Menedżer"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:244
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "Obiekt menedżera użytkowników, który steruje tym użytkownikiem."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mniej niż minutę temu"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minuta temu"
|
||||
msgstr[1] "%d minuty temu"
|
||||
msgstr[2] "%d minut temu"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d godzina temu"
|
||||
msgstr[1] "%d godziny temu"
|
||||
msgstr[2] "%d godzin temu"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dzień temu"
|
||||
msgstr[1] "%d dni temu"
|
||||
msgstr[2] "%d dni temu"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d tydzień temu"
|
||||
msgstr[1] "%d tygodnie temu"
|
||||
msgstr[2] "%d tygodni temu"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznane"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Nie można zablokować ekranu: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr ""
|
||||
"Nie można tymczasowo ustawić wygaszacza ekranu na wygaszenie ekranu: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Nie można się wylogować: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Informacje o koncie..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Panel boczny"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Preferencje systemu..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Zablokuj ekran"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Przełącz użytkownika"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Wyloguj się..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Wyłącz komputer..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Katalog domowy"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "System plików"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Wyszukaj"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
144
po/pt_BR.po
Normal file
144
po/pt_BR.po
Normal file
@ -0,0 +1,144 @@
|
||||
# Portuguese translations for gnome-shell package.
|
||||
# Copyright (C) 2009 THE gnome-shell'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Og Maciel <ogmaciel@gnome.org>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-14 17:53-0400\n"
|
||||
"PO-Revision-Date: 2009-08-14 17:53-0400\n"
|
||||
"Last-Translator: Og Maciel <ogmaciel@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"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Atividades"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:412
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %l:%M %p"
|
||||
|
||||
#: ../js/ui/dash.js:235
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Localizar aplicativos ou documentos"
|
||||
|
||||
#: ../js/ui/dash.js:336
|
||||
msgid "Browse"
|
||||
msgstr "Navegar"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:472 ../js/ui/dash.js:545
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "APLICATIVOS"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:477 ../js/ui/dash.js:570
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "DOCUMENTOS RECENTES"
|
||||
|
||||
#. **** Places ****
|
||||
#: ../js/ui/dash.js:563
|
||||
msgid "PLACES"
|
||||
msgstr "LOCAIS"
|
||||
|
||||
#: ../js/ui/runDialog.js:74
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Por favor digite um comando:"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:242
|
||||
msgid "Manager"
|
||||
msgstr "Gerenciador"
|
||||
|
||||
#: ../src/gdmuser/gdm-user.c:243
|
||||
msgid "The user manager object this user is controlled by."
|
||||
msgstr "O objeto gerenciador de usuários que controla este usuário."
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Menos de um minuto atrás"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, 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:847
|
||||
#, 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:850
|
||||
#, 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:853
|
||||
#, 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..."
|
186
po/sv.po
Normal file
186
po/sv.po
Normal file
@ -0,0 +1,186 @@
|
||||
# Swedish translation for gnome-shell.
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
# Daniel Nylander <po@danielnylander.se>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-25 07:48+0200\n"
|
||||
"PO-Revision-Date: 2009-08-25 07:48+0100\n"
|
||||
"Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
|
||||
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME-skal"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Fönsterhantering och programstarter"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Aktiviteter"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H.%M"
|
||||
|
||||
#: ../js/ui/dash.js:250
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Hitta program eller dokument"
|
||||
|
||||
#: ../js/ui/dash.js:368
|
||||
msgid "Browse"
|
||||
msgstr "Bläddra"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:556
|
||||
#: ../js/ui/dash.js:606
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "PROGRAM"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:576
|
||||
msgid "PLACES"
|
||||
msgstr "PLATSER"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:583
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SENASTE DOKUMENT"
|
||||
|
||||
#. **** Search Results ****
|
||||
#: ../js/ui/dash.js:602
|
||||
msgid "SEARCH RESULTS"
|
||||
msgstr "SÖKRESULTAT"
|
||||
|
||||
#: ../js/ui/dash.js:615
|
||||
msgid "DOCUMENTS"
|
||||
msgstr "DOKUMENT"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Ange ett kommando:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Mindre än en minut sedan"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d minut sedan"
|
||||
msgstr[1] "%d minuter sedan"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d timme sedan"
|
||||
msgstr[1] "%d timmar sedan"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d dag sedan"
|
||||
msgstr[1] "%d dagar sedan"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d vecka sedan"
|
||||
msgstr[1] "%d veckor sedan"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Okänt"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Kan inte låsa skärmen: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Kan inte temporärt ställa in skärmsläckaren till blank skärm: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Kan inte logga ut: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Kontoinformation..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Sidopanel"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Systeminställningar..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Lås skärmen"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Växla användare"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Logga ut..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Stäng av..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Hemmapp"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Filsystem"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Sök"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
||||
|
||||
#~ msgid "Manager"
|
||||
#~ msgstr "Hanterare"
|
||||
#~ msgid "The user manager object this user is controlled by."
|
||||
#~ msgstr "Användarhanteringsobjektet som denna användare styrs av."
|
||||
|
166
po/tr.po
Normal file
166
po/tr.po
Normal file
@ -0,0 +1,166 @@
|
||||
# gnome-shell
|
||||
# Copyright (C) 2009
|
||||
# This file is distributed under the same license as the gnome-shell package.
|
||||
#
|
||||
# Baris Cicek <baris@teamforce.name.tr>, 2009.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gnome-shell\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-08-21 00:41+0300\n"
|
||||
"PO-Revision-Date: 2009-08-21 00:40+0300\n"
|
||||
"Last-Translator: Baris Cicek <baris@teamforce.name.tr>\n"
|
||||
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:1
|
||||
msgid "GNOME Shell"
|
||||
msgstr "GNOME Kabuğu"
|
||||
|
||||
#: ../data/gnome-shell.desktop.in.in.h:2
|
||||
msgid "Window management and application launching"
|
||||
msgstr "Pencere yönetimi ve uygulama başlatma"
|
||||
|
||||
#. left side
|
||||
#: ../js/ui/panel.js:266
|
||||
msgid "Activities"
|
||||
msgstr "Etkinlikler"
|
||||
|
||||
#. Translators: This is a time format.
|
||||
#: ../js/ui/panel.js:433
|
||||
msgid "%a %l:%M %p"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#: ../js/ui/dash.js:251
|
||||
msgid "Find apps or documents"
|
||||
msgstr "Uygulamalar ve belgeler bul"
|
||||
|
||||
#: ../js/ui/dash.js:369
|
||||
msgid "Browse"
|
||||
msgstr "Göz at"
|
||||
|
||||
#. **** Applications ****
|
||||
#: ../js/ui/dash.js:505 ../js/ui/dash.js:578
|
||||
msgid "APPLICATIONS"
|
||||
msgstr "UYGULAMALAR"
|
||||
|
||||
#. **** Documents ****
|
||||
#: ../js/ui/dash.js:510 ../js/ui/dash.js:605
|
||||
msgid "RECENT DOCUMENTS"
|
||||
msgstr "SON ERİŞİLEN BELGELER"
|
||||
|
||||
#. **** Places ****
|
||||
#. Translators: This is in the sense of locations for documents,
|
||||
#. network locations, etc.
|
||||
#: ../js/ui/dash.js:598
|
||||
msgid "PLACES"
|
||||
msgstr "YERLER"
|
||||
|
||||
#: ../js/ui/runDialog.js:75
|
||||
msgid "Please enter a command:"
|
||||
msgstr "Lütfen bir komut girin:"
|
||||
|
||||
#: ../src/shell-global.c:841
|
||||
msgid "Less than a minute ago"
|
||||
msgstr "Bir dakikadan daha az süre önce"
|
||||
|
||||
#: ../src/shell-global.c:844
|
||||
#, c-format
|
||||
msgid "%d minute ago"
|
||||
msgid_plural "%d minutes ago"
|
||||
msgstr[0] "%d dakika önce"
|
||||
|
||||
#: ../src/shell-global.c:847
|
||||
#, c-format
|
||||
msgid "%d hour ago"
|
||||
msgid_plural "%d hours ago"
|
||||
msgstr[0] "%d saat önce"
|
||||
|
||||
#: ../src/shell-global.c:850
|
||||
#, c-format
|
||||
msgid "%d day ago"
|
||||
msgid_plural "%d days ago"
|
||||
msgstr[0] "%d gün önce"
|
||||
|
||||
#: ../src/shell-global.c:853
|
||||
#, c-format
|
||||
msgid "%d week ago"
|
||||
msgid_plural "%d weeks ago"
|
||||
msgstr[0] "%d hafta önce"
|
||||
|
||||
#: ../src/shell-status-menu.c:156
|
||||
msgid "Unknown"
|
||||
msgstr "Bilinmeyen"
|
||||
|
||||
#: ../src/shell-status-menu.c:212
|
||||
#, c-format
|
||||
msgid "Can't lock screen: %s"
|
||||
msgstr "Ekran kilitlenemedi: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:227
|
||||
#, c-format
|
||||
msgid "Can't temporarily set screensaver to blank screen: %s"
|
||||
msgstr "Ekran koruyucu geçici olarak boş ekran olarak atanamadı: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:351
|
||||
#, c-format
|
||||
msgid "Can't logout: %s"
|
||||
msgstr "Çıkış yapılamadı: %s"
|
||||
|
||||
#: ../src/shell-status-menu.c:492
|
||||
msgid "Account Information..."
|
||||
msgstr "Hesap Bilgisi..."
|
||||
|
||||
#: ../src/shell-status-menu.c:502
|
||||
msgid "Sidebar"
|
||||
msgstr "Kenar Çubuğu"
|
||||
|
||||
#: ../src/shell-status-menu.c:510
|
||||
msgid "System Preferences..."
|
||||
msgstr "Sistem Tercihleri..."
|
||||
|
||||
#: ../src/shell-status-menu.c:525
|
||||
msgid "Lock Screen"
|
||||
msgstr "Ekrani Kilitle"
|
||||
|
||||
#: ../src/shell-status-menu.c:535
|
||||
msgid "Switch User"
|
||||
msgstr "Kullanıcı Değiştir"
|
||||
|
||||
#. Only show switch user if there are other users
|
||||
#. Log Out
|
||||
#: ../src/shell-status-menu.c:546
|
||||
msgid "Log Out..."
|
||||
msgstr "Çıkış..."
|
||||
|
||||
#. Shut down
|
||||
#: ../src/shell-status-menu.c:557
|
||||
msgid "Shut Down..."
|
||||
msgstr "Kapat..."
|
||||
|
||||
#: ../src/shell-uri-util.c:87
|
||||
msgid "Home Folder"
|
||||
msgstr "Ev Klasörü"
|
||||
|
||||
#. Translators: this is the same string as the one found in
|
||||
#. * nautilus
|
||||
#: ../src/shell-uri-util.c:102
|
||||
msgid "File System"
|
||||
msgstr "Dosya Sistemi"
|
||||
|
||||
#: ../src/shell-uri-util.c:248
|
||||
msgid "Search"
|
||||
msgstr "Arama"
|
||||
|
||||
#. 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
|
||||
#, c-format
|
||||
msgid "%1$s: %2$s"
|
||||
msgstr "%1$s: %2$s"
|
@ -36,18 +36,18 @@ 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-teth && \
|
||||
(cmp -s xgen-teth big-enum-types.h || cp xgen-teth big-enum-types.h) && \
|
||||
rm -f xgen-teth && \
|
||||
$(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-tetc && \
|
||||
cp xgen-tetc big-enum-types.c && \
|
||||
rm -f xgen-tetc
|
||||
$(big_source_h) ) >> xgen-betc && \
|
||||
cp xgen-betc big-enum-types.c && \
|
||||
rm -f xgen-betc
|
||||
|
||||
noinst_LTLIBRARIES += libbig-1.0.la
|
||||
|
||||
|
@ -1,89 +0,0 @@
|
||||
tidy_cflags = \
|
||||
-I$(top_srcdir)/src \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DG_LOG_DOMAIN=\"Tidy\" \
|
||||
$(MUTTER_PLUGIN_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
tidy_built_sources = \
|
||||
tidy-enum-types.h \
|
||||
tidy-enum-types.c \
|
||||
tidy-marshal.h \
|
||||
tidy-marshal.c
|
||||
|
||||
BUILT_SOURCES += $(tidy_built_sources)
|
||||
|
||||
TIDY_STAMP_FILES = stamp-tidy-marshal.h stamp-tidy-enum-types.h
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
tidy_source_h = \
|
||||
tidy/tidy-grid.h \
|
||||
$(NULL)
|
||||
|
||||
tidy_source_h_priv = \
|
||||
$(NULL)
|
||||
|
||||
# please, keep this sorted alphabetically
|
||||
tidy_source_c = \
|
||||
tidy/tidy-grid.c \
|
||||
$(NULL)
|
||||
|
||||
tidy-marshal.h: stamp-tidy-marshal.h
|
||||
@true
|
||||
stamp-tidy-marshal.h: Makefile tidy/tidy-marshal.list
|
||||
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
|
||||
--prefix=_tidy_marshal \
|
||||
--header \
|
||||
$(srcdir)/tidy/tidy-marshal.list > xgen-tmh && \
|
||||
(cmp -s xgen-tmh tidy-marshal.h || cp -f xgen-tmh tidy-marshal.h) && \
|
||||
rm -f xgen-tmh && \
|
||||
echo timestamp > $(@F)
|
||||
|
||||
tidy-marshal.c: Makefile tidy/tidy-marshal.list
|
||||
$(AM_V_GEN) (echo "#include \"tidy-marshal.h\"" ; \
|
||||
$(GLIB_GENMARSHAL) \
|
||||
--prefix=_tidy_marshal \
|
||||
--body \
|
||||
$(srcdir)/tidy/tidy-marshal.list ) > xgen-tmc && \
|
||||
cp -f xgen-tmc tidy-marshal.c && \
|
||||
rm -f xgen-tmc
|
||||
|
||||
tidy-enum-types.h: stamp-tidy-enum-types.h Makefile
|
||||
@true
|
||||
stamp-tidy-enum-types.h: $(tidy_source_h) tidy/tidy-enum-types.h.in
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/tidy/tidy-enum-types.h.in \
|
||||
$(tidy_source_h) ) >> xgen-teth && \
|
||||
(cmp -s xgen-teth tidy-enum-types.h || cp xgen-teth tidy-enum-types.h) && \
|
||||
rm -f xgen-teth && \
|
||||
echo timestamp > $(@F)
|
||||
|
||||
tidy-enum-types.c: stamp-tidy-enum-types.h tidy/tidy-enum-types.c.in
|
||||
$(AM_V_GEN) ( cd $(srcdir) && \
|
||||
$(GLIB_MKENUMS) \
|
||||
--template $(srcdir)/tidy/tidy-enum-types.c.in \
|
||||
$(tidy_source_h) ) >> xgen-tetc && \
|
||||
cp xgen-tetc tidy-enum-types.c && \
|
||||
rm -f xgen-tetc
|
||||
|
||||
noinst_LTLIBRARIES += libtidy-1.0.la
|
||||
|
||||
libtidy_1_0_la_LIBADD = $(TIDY_LIBS)
|
||||
libtidy_1_0_la_SOURCES = \
|
||||
$(tidy_source_c) \
|
||||
$(tidy_source_h) \
|
||||
$(tidy_source_h_priv) \
|
||||
$(tidy_built_sources) \
|
||||
$(NULL)
|
||||
libtidy_1_0_la_CPPFLAGS = $(tidy_cflags)
|
||||
libtidy_1_0_la_LDFLAGS = $(LDADD)
|
||||
|
||||
CLEANFILES += $(TIDY_STAMP_FILES) $(BUILT_SOURCES)
|
||||
|
||||
EXTRA_DIST += \
|
||||
tidy/tidy-enum-types.h.in \
|
||||
tidy/tidy-enum-types.c.in \
|
||||
tidy/tidy-marshal.list
|
@ -19,7 +19,6 @@ gnome-shell: gnome-shell.in
|
||||
CLEANFILES += gnome-shell
|
||||
EXTRA_DIST += gnome-shell.in
|
||||
|
||||
include Makefile-tidy.am
|
||||
include Makefile-big.am
|
||||
include Makefile-gdmuser.am
|
||||
include Makefile-tray.am
|
||||
@ -28,7 +27,8 @@ gnome_shell_cflags = \
|
||||
$(MUTTER_PLUGIN_CFLAGS) \
|
||||
$(LIBGNOMEUI_CFLAGS) \
|
||||
-I$(srcdir)/tray \
|
||||
-DGETTEXT_PACKAGE=gnome-shell \
|
||||
-DGETTEXT_PACKAGE=\"gnome-shell\" \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" \
|
||||
-DGNOME_SHELL_DATADIR=\"$(pkgdatadir)\" \
|
||||
-DGNOME_SHELL_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DJSDIR=\"$(pkgdatadir)/js\"
|
||||
@ -57,6 +57,8 @@ libgnome_shell_la_SOURCES = \
|
||||
shell-app-system.h \
|
||||
shell-arrow.c \
|
||||
shell-arrow.h \
|
||||
shell-button-box.c \
|
||||
shell-button-box.h \
|
||||
shell-drawing.c \
|
||||
shell-drawing.h \
|
||||
shell-drawing-area.c \
|
||||
@ -126,9 +128,9 @@ stamp-shell-marshal.h: Makefile shell-marshal.list
|
||||
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
|
||||
--prefix=_shell_marshal \
|
||||
--header \
|
||||
$(srcdir)/shell-marshal.list > xgen-tmh && \
|
||||
(cmp -s xgen-tmh shell-marshal.h || cp -f xgen-tmh shell-marshal.h) && \
|
||||
rm -f xgen-tmh && \
|
||||
$(srcdir)/shell-marshal.list > xgen-smh && \
|
||||
(cmp -s xgen-smh shell-marshal.h || cp -f xgen-smh shell-marshal.h) && \
|
||||
rm -f xgen-smh && \
|
||||
echo timestamp > $(@F)
|
||||
|
||||
shell-marshal.c: Makefile shell-marshal.list
|
||||
@ -136,9 +138,9 @@ shell-marshal.c: Makefile shell-marshal.list
|
||||
$(GLIB_GENMARSHAL) \
|
||||
--prefix=_shell_marshal \
|
||||
--body \
|
||||
$(srcdir)/shell-marshal.list ) > xgen-tmc && \
|
||||
cp -f xgen-tmc shell-marshal.c && \
|
||||
rm -f xgen-tmc
|
||||
$(srcdir)/shell-marshal.list ) > xgen-smc && \
|
||||
cp -f xgen-smc shell-marshal.c && \
|
||||
rm -f xgen-smc
|
||||
|
||||
libgnome_shell_la_LDFLAGS = -avoid-version -module
|
||||
libgnome_shell_la_LIBADD = \
|
||||
@ -146,12 +148,11 @@ libgnome_shell_la_LIBADD = \
|
||||
$(LIBGNOMEUI_LIBS) \
|
||||
libbig-1.0.la \
|
||||
libgdmuser-1.0.la \
|
||||
libtidy-1.0.la \
|
||||
libtray.la
|
||||
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
|
||||
|
||||
typelibdir = $(pkglibdir)
|
||||
typelib_DATA = Shell-0.1.typelib Tidy-1.0.typelib Big-1.0.typelib
|
||||
typelib_DATA = Shell-0.1.typelib Big-1.0.typelib
|
||||
|
||||
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) Big-1.0.gir libgnome-shell.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
@ -172,27 +173,13 @@ 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
|
||||
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler --includedir=$(builddir) --includedir=$(MUTTER_LIB_DIR)/mutter/ Shell-0.1.gir -o $@
|
||||
$(AM_V_GEN) LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
|
||||
$(G_IR_COMPILER) \
|
||||
--includedir=. \
|
||||
--includedir=$(MUTTER_LIB_DIR)/mutter/ \
|
||||
Shell-0.1.gir -o $@
|
||||
CLEANFILES += Shell-0.1.typelib
|
||||
|
||||
Tidy-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libtidy-1.0.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
--namespace=Tidy \
|
||||
--nsversion=1.0 \
|
||||
--include=Clutter-1.0 \
|
||||
--program=mutter \
|
||||
--program-arg=--mutter-plugins=$$(pwd)/libgnome-shell.la \
|
||||
$(addprefix $(srcdir)/,$(tidy_source_h)) \
|
||||
$(addprefix $(srcdir)/,$(tidy_source_c)) \
|
||||
$(srcdir)/tidy-enum-types.h \
|
||||
$(tidy_cflags) \
|
||||
-o $@
|
||||
CLEANFILES += Tidy-1.0.gir
|
||||
|
||||
Tidy-1.0.typelib: libtidy-1.0.la Tidy-1.0.gir
|
||||
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler Tidy-1.0.gir -o $@
|
||||
CLEANFILES += Tidy-1.0.typelib
|
||||
|
||||
Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libbig-1.0.la Makefile
|
||||
$(AM_V_GEN) $(G_IR_SCANNER) \
|
||||
--namespace=Big \
|
||||
@ -209,5 +196,6 @@ Big-1.0.gir: $(mutter) $(G_IR_SCANNER) libgnome-shell.la libbig-1.0.la Makefile
|
||||
CLEANFILES += Big-1.0.gir
|
||||
|
||||
Big-1.0.typelib: libbig-1.0.la Big-1.0.gir
|
||||
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. g-ir-compiler Big-1.0.gir -o $@
|
||||
$(AM_V_GEN) LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} \
|
||||
$(G_IR_COMPILER) Big-1.0.gir -o $@
|
||||
CLEANFILES += Big-1.0.typelib
|
||||
|
@ -35,7 +35,8 @@
|
||||
#endif /* HAVE_PATHS_H */
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
/* Note on sync with gdm; need to use -lib here */
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
@ -26,7 +26,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
/* Note on sync with gdm; need to use -lib here */
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@ -239,8 +240,8 @@ gdm_user_class_init (GdmUserClass *class)
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_MANAGER,
|
||||
g_param_spec_object ("manager",
|
||||
_("Manager"),
|
||||
_("The user manager object this user is controlled by."),
|
||||
"Manager",
|
||||
"The user manager object this user is controlled by.",
|
||||
GDM_TYPE_USER_MANAGER,
|
||||
(G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY)));
|
||||
|
@ -153,6 +153,9 @@ gnome_shell_plugin_constructed (GObject *object)
|
||||
ClutterBackend *backend;
|
||||
cairo_font_options_t *font_options;
|
||||
|
||||
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
/* Disable text mipmapping; it causes problems on pre-GEM Intel
|
||||
* drivers and we should just be rendering text at the right
|
||||
* size rather than scaling it. If we do effects where we dynamically
|
||||
|
@ -13,44 +13,6 @@ import tempfile
|
||||
import termios
|
||||
import time
|
||||
import errno
|
||||
import dbus
|
||||
|
||||
def find_cmd (cmd_list):
|
||||
"""
|
||||
Takes a list of command candidates and returns the first one that exists.
|
||||
Raises a system exit if none of the commands exist.
|
||||
"""
|
||||
for cmd in cmd_list:
|
||||
if os.path.exists(cmd):
|
||||
return cmd
|
||||
|
||||
raise SystemExit("None of the commands %s exist" % cmd_list)
|
||||
|
||||
def pidof(command):
|
||||
pidof_cmd = find_cmd(["/sbin/pidof", "/bin/pidof", "/usr/bin/pidof"])
|
||||
pidof = subprocess.Popen([pidof_cmd, command], stdout=subprocess.PIPE)
|
||||
pids = pidof.communicate()[0].split()
|
||||
pidof.wait()
|
||||
|
||||
# pidof doesn't have a "current user only" option, so we may have
|
||||
# gotten the pids of other users' processes. Fix that.
|
||||
for pid in pids:
|
||||
try:
|
||||
os.kill(int(pid), 0)
|
||||
return pid
|
||||
except Exception, e:
|
||||
pass
|
||||
return None
|
||||
|
||||
def kill_gnome_panel(pid):
|
||||
if options.verbose:
|
||||
print "Terminating panel process %s" % pid
|
||||
devnull = open("/dev/null", "w")
|
||||
subprocess.call(["gdb", "-batch-silent",
|
||||
"-ex", "call panel_session_do_not_restart()",
|
||||
"-ex", "call exit(0)",
|
||||
"-p", pid], stdout=devnull, stderr=devnull)
|
||||
devnull.close()
|
||||
|
||||
def start_xephyr():
|
||||
tmpdir = tempfile.mkdtemp("", "gnome-shell.")
|
||||
@ -190,11 +152,47 @@ def start_shell():
|
||||
else:
|
||||
args = []
|
||||
|
||||
args.extend(['mutter', '--mutter-plugins=' + plugin, '--replace'])
|
||||
args.extend(['mutter', '--mutter-plugins=' + plugin])
|
||||
if options.replace:
|
||||
args.append('--replace')
|
||||
if options.sync:
|
||||
args.append('--sync')
|
||||
return subprocess.Popen(args, env=env)
|
||||
|
||||
def restore_gnome():
|
||||
# Do imports lazily to save time and memory
|
||||
import gio
|
||||
import gconf
|
||||
|
||||
# We don't want to start the new gnome-panel in the current
|
||||
# directory; $HOME is better for stuff launched from it
|
||||
os.chdir(os.path.expanduser("~"))
|
||||
|
||||
def launch_component(gconf_path):
|
||||
client = gconf.client_get_default()
|
||||
component = client.get_string(gconf_path)
|
||||
|
||||
if component == None or component == "":
|
||||
return
|
||||
|
||||
# See gnome-session/gsm-util.c:gsm_util_find_desktop_file_for_app_name()
|
||||
# The one difference is that we don't search the autostart directories,
|
||||
# and just search normal application search path. (Gio doesnt' know
|
||||
# how to search the autostart dirs, so we'd have to do that ourselves.)
|
||||
appinfo = None
|
||||
try:
|
||||
appinfo = gio.unix.DesktopAppInfo(component + ".desktop")
|
||||
except:
|
||||
try:
|
||||
appinfo = gio.unix.DesktopAppInfo("gnome-" + component + ".desktop")
|
||||
except:
|
||||
pass
|
||||
|
||||
if appinfo:
|
||||
appinfo.launch()
|
||||
|
||||
launch_component("/desktop/gnome/session/required_components/windowmanager")
|
||||
launch_component("/desktop/gnome/session/required_components/panel")
|
||||
|
||||
# Main program
|
||||
|
||||
@ -207,6 +205,8 @@ 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("", "--xephyr", action="store_true",
|
||||
help="Run a debugging instance inside Xephyr")
|
||||
parser.add_option("", "--geometry", metavar="GEOMETRY",
|
||||
help="Specify Xephyr screen geometry",
|
||||
default="1024x768");
|
||||
@ -227,27 +227,6 @@ elif options.debug:
|
||||
if options.wide:
|
||||
options.geometry = "1280x800"
|
||||
|
||||
metacity_pid = pidof("metacity")
|
||||
compiz_pid = pidof("compiz.real") or pidof("compiz")
|
||||
|
||||
# In Gnome 2.26 the panel grabs a dbus name and allows replacement; use that.
|
||||
bus = dbus.Interface(dbus.SessionBus().get_object('org.freedesktop.DBus', '/org/freedesktop/DBus'),
|
||||
'org.freedesktop.DBus')
|
||||
names = bus.ListNames()
|
||||
gnome_panel_dbus = 'org.gnome.Panel' in names
|
||||
if gnome_panel_dbus:
|
||||
gnome_panel_pid = None
|
||||
else:
|
||||
gnome_panel_pid = pidof("gnome-panel")
|
||||
|
||||
# Run in Xephyr if gnome-panel is already running and the user didn't
|
||||
# specify --replace. Otherwise, run fullscreen
|
||||
if options.replace:
|
||||
run_in_xephyr = False
|
||||
else:
|
||||
run_in_xephyr = (metacity_pid != None or compiz_pid != None or
|
||||
gnome_panel_pid != None)
|
||||
|
||||
# Figure out whether or not to use GL_EXT_texture_from_pixmap. By default
|
||||
# we use it iff we aren't running Xephyr, but we allow the user to
|
||||
# explicitly disable it.
|
||||
@ -258,7 +237,7 @@ if 'GNOME_SHELL_DISABLE_TFP' in os.environ and \
|
||||
use_tfp = False
|
||||
else:
|
||||
# tfp does not work correctly in Xephyr
|
||||
use_tfp = not run_in_xephyr
|
||||
use_tfp = not options.xephyr
|
||||
|
||||
if options.verbose:
|
||||
print "Starting shell"
|
||||
@ -268,23 +247,25 @@ if options.debug:
|
||||
# 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:
|
||||
if run_in_xephyr:
|
||||
shell = start_xephyr()
|
||||
if options.xephyr:
|
||||
xephyr = start_xephyr()
|
||||
# This makes us not grab the org.gnome.Panel name
|
||||
os.environ['GNOME_SHELL_NO_REPLACE_PANEL'] = '1'
|
||||
start_shell()
|
||||
shell = start_shell()
|
||||
else:
|
||||
if gnome_panel_pid is not None:
|
||||
kill_gnome_panel(gnome_panel_pid)
|
||||
xephyr = None
|
||||
shell = start_shell()
|
||||
|
||||
# Wait for shell to exit
|
||||
if options.verbose:
|
||||
print "Waiting for shell to exit"
|
||||
shell.wait()
|
||||
if options.verbose:
|
||||
print "Shell is dead"
|
||||
|
||||
except KeyboardInterrupt, e:
|
||||
try:
|
||||
@ -292,29 +273,29 @@ except KeyboardInterrupt, e:
|
||||
except:
|
||||
pass
|
||||
shell.wait()
|
||||
if options.verbose:
|
||||
print "Shell killed"
|
||||
|
||||
finally:
|
||||
# Clean up Xephyr if it outlived the shell
|
||||
if xephyr:
|
||||
try:
|
||||
os.kill(xephyr.pid, signal.SIGKILL)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if 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 run_in_xephyr:
|
||||
# Restart gnome-panel and window manager
|
||||
|
||||
# We don't want to start the new gnome-panel in the current
|
||||
# directory; $HOME is better for stuff launched from it
|
||||
os.chdir(os.path.expanduser("~"))
|
||||
|
||||
if metacity_pid:
|
||||
if options.verbose:
|
||||
print "Restarting Metacity"
|
||||
subprocess.Popen(["/usr/bin/metacity"])
|
||||
elif compiz_pid:
|
||||
if options.verbose:
|
||||
print "Restarting Compiz"
|
||||
subprocess.Popen(["/usr/bin/compiz"])
|
||||
if gnome_panel_dbus or gnome_panel_pid:
|
||||
if options.verbose:
|
||||
print "Restarting gnome-panel"
|
||||
subprocess.Popen(["/usr/bin/gnome-panel"])
|
||||
if not options.xephyr and options.replace and not normal_exit:
|
||||
restore_gnome()
|
||||
|
@ -11,12 +11,18 @@
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#define SN_API_NOT_YET_FROZEN 1
|
||||
#include <libsn/sn.h>
|
||||
|
||||
#include "shell-texture-cache.h"
|
||||
#include "shell-app-monitor.h"
|
||||
#include "shell-app-system.h"
|
||||
#include "shell-global.h"
|
||||
#include "shell-marshal.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "window.h"
|
||||
#include "group.h"
|
||||
|
||||
/* This file includes modified code from
|
||||
* desktop-data-engine/engine-dbus/hippo-application-monitor.c
|
||||
@ -86,13 +92,13 @@ static struct
|
||||
const char *pattern;
|
||||
GRegex *regex;
|
||||
} title_patterns[] = {
|
||||
{"mozilla-firefox", ".* - Mozilla Firefox", NULL}, \
|
||||
{"openoffice.org-writer", ".* - OpenOffice.org Writer$", NULL}, \
|
||||
{"openoffice.org-calc", ".* - OpenOffice.org Calc$", NULL}, \
|
||||
{"openoffice.org-impress", ".* - OpenOffice.org Impress$", NULL}, \
|
||||
{"openoffice.org-draw", ".* - OpenOffice.org Draw$", NULL}, \
|
||||
{"openoffice.org-base", ".* - OpenOffice.org Base$", NULL}, \
|
||||
{"openoffice.org-math", ".* - OpenOffice.org Math$", NULL}, \
|
||||
{"mozilla-firefox.desktop", ".* - Mozilla Firefox", NULL}, \
|
||||
{"openoffice.org-writer.desktop", ".* - OpenOffice.org Writer$", NULL}, \
|
||||
{"openoffice.org-calc.desktop", ".* - OpenOffice.org Calc$", NULL}, \
|
||||
{"openoffice.org-impress.desktop", ".* - OpenOffice.org Impress$", NULL}, \
|
||||
{"openoffice.org-draw.desktop", ".* - OpenOffice.org Draw$", NULL}, \
|
||||
{"openoffice.org-base.desktop", ".* - OpenOffice.org Base$", NULL}, \
|
||||
{"openoffice.org-math.desktop", ".* - OpenOffice.org Math$", NULL}, \
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -135,6 +141,11 @@ G_DEFINE_TYPE (ShellAppMonitor, shell_app_monitor, G_TYPE_OBJECT);
|
||||
/* Represents an application record for a given context */
|
||||
struct AppUsage
|
||||
{
|
||||
/* Whether the application we're tracking is "transient", see
|
||||
* shell_app_info_is_transient.
|
||||
*/
|
||||
gboolean transient;
|
||||
|
||||
gdouble score; /* Based on the number of times we'e seen the app and normalized */
|
||||
long last_seen; /* Used to clear old apps we've only seen a few times */
|
||||
|
||||
@ -150,7 +161,11 @@ struct AppUsage
|
||||
};
|
||||
|
||||
enum {
|
||||
CHANGED,
|
||||
APP_ADDED,
|
||||
APP_REMOVED,
|
||||
WINDOW_ADDED,
|
||||
WINDOW_REMOVED,
|
||||
STARTUP_SEQUENCE_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -166,6 +181,9 @@ static AppUsage * get_app_usage_for_context_and_id (ShellAppMonitor *monitor,
|
||||
const char *context,
|
||||
const char *appid);
|
||||
|
||||
static void track_window (ShellAppMonitor *monitor, MetaWindow *window);
|
||||
static void disassociate_window (ShellAppMonitor *monitor, MetaWindow *window);
|
||||
|
||||
static gboolean idle_save_application_usage (gpointer data);
|
||||
|
||||
static void restore_from_file (ShellAppMonitor *monitor);
|
||||
@ -191,13 +209,49 @@ static void shell_app_monitor_class_init(ShellAppMonitorClass *klass)
|
||||
|
||||
gobject_class->finalize = shell_app_monitor_finalize;
|
||||
|
||||
signals[CHANGED] = g_signal_new ("changed",
|
||||
signals[APP_ADDED] = g_signal_new ("app-added",
|
||||
SHELL_TYPE_APP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
_shell_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
SHELL_TYPE_APP_INFO);
|
||||
signals[APP_REMOVED] = g_signal_new ("app-removed",
|
||||
SHELL_TYPE_APP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
_shell_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1,
|
||||
SHELL_TYPE_APP_INFO);
|
||||
|
||||
signals[WINDOW_ADDED] = g_signal_new ("window-added",
|
||||
SHELL_TYPE_APP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
_shell_marshal_VOID__BOXED_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
SHELL_TYPE_APP_INFO,
|
||||
META_TYPE_WINDOW);
|
||||
signals[WINDOW_REMOVED] = g_signal_new ("window-removed",
|
||||
SHELL_TYPE_APP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
_shell_marshal_VOID__BOXED_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
SHELL_TYPE_APP_INFO,
|
||||
META_TYPE_WINDOW);
|
||||
|
||||
signals[STARTUP_SEQUENCE_CHANGED] = g_signal_new ("startup-sequence-changed",
|
||||
SHELL_TYPE_APP_MONITOR,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1, SHELL_TYPE_STARTUP_SEQUENCE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -206,15 +260,20 @@ destroy_usage (AppUsage *usage)
|
||||
g_free (usage);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_wmclass_for_window (MetaWindow *window)
|
||||
/**
|
||||
* get_app_id_from_title:
|
||||
*
|
||||
* Use a window's "title" property to determine an application ID.
|
||||
* This is a temporary crutch for a few applications until we get
|
||||
* them correctly setting their WM_CLASS.
|
||||
*/
|
||||
static const char *
|
||||
get_app_id_from_title (MetaWindow *window)
|
||||
{
|
||||
static gboolean patterns_initialized = FALSE;
|
||||
const char *wm_class;
|
||||
char *title;
|
||||
int i;
|
||||
|
||||
wm_class = meta_window_get_wm_class (window);
|
||||
g_object_get (window, "title", &title, NULL);
|
||||
|
||||
if (!patterns_initialized) /* Generate match patterns once for all */
|
||||
@ -234,15 +293,15 @@ get_wmclass_for_window (MetaWindow *window)
|
||||
{
|
||||
if (g_regex_match (title_patterns[i].regex, title, 0, NULL))
|
||||
{
|
||||
g_free (title);
|
||||
/* Set a pseudo WM class, handled like true ones */
|
||||
wm_class = title_patterns[i].app_id;
|
||||
break;
|
||||
return title_patterns[i].app_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (title);
|
||||
return g_strdup (wm_class);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,44 +314,112 @@ get_wmclass_for_window (MetaWindow *window)
|
||||
static char *
|
||||
get_cleaned_wmclass_for_window (MetaWindow *window)
|
||||
{
|
||||
char *wmclass;
|
||||
const char *wmclass;
|
||||
char *cleaned_wmclass;
|
||||
|
||||
if (meta_window_get_window_type (window) != META_WINDOW_NORMAL)
|
||||
return NULL;
|
||||
|
||||
wmclass = get_wmclass_for_window (window);
|
||||
wmclass = meta_window_get_wm_class (window);
|
||||
if (!wmclass)
|
||||
return NULL;
|
||||
|
||||
cleaned_wmclass = g_utf8_strdown (wmclass, -1);
|
||||
g_free (wmclass);
|
||||
|
||||
/* This handles "Fedora Eclipse", probably others.
|
||||
* Note g_strdelimit is modify-in-place. */
|
||||
g_strdelimit (cleaned_wmclass, " ", '-');
|
||||
wmclass = g_strdup (cleaned_wmclass);
|
||||
g_free (cleaned_wmclass);
|
||||
return wmclass;
|
||||
|
||||
return cleaned_wmclass;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_app_for_window:
|
||||
* window_is_tracked:
|
||||
*
|
||||
* Returns the application associated with a window, or %NULL if
|
||||
* we're unable to determine one.
|
||||
* Returns: %TRUE iff we want to scan this window for application association
|
||||
*/
|
||||
static gboolean
|
||||
window_is_tracked (MetaWindow *window)
|
||||
{
|
||||
if (meta_window_is_override_redirect (window))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* window_is_usage_tracked:
|
||||
*
|
||||
* Determine if it makes sense to track the given window for application
|
||||
* usage. An example of a window we don't want to track is the root
|
||||
* desktop window. We skip all override-redirect types, and also
|
||||
* exclude other window types like tooltip explicitly, though generally
|
||||
* most of these should be override-redirect.
|
||||
*
|
||||
* The usage data is also currently used to return the list of user-interesting
|
||||
* windows associated with an application.
|
||||
*
|
||||
* Returns: %TRUE iff we want to record focus time spent in this window
|
||||
*/
|
||||
static gboolean
|
||||
window_is_usage_tracked (MetaWindow *window)
|
||||
{
|
||||
if (!window_is_tracked (window))
|
||||
return FALSE;
|
||||
|
||||
switch (meta_window_get_window_type (window))
|
||||
{
|
||||
/* Definitely ignore these. */
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
/* Should have already been handled by override_redirect above,
|
||||
* but explicitly list here so we get the "unhandled enum"
|
||||
* warning if in the future anything is added.*/
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
return FALSE;
|
||||
case META_WINDOW_NORMAL:
|
||||
case META_WINDOW_DIALOG:
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
case META_WINDOW_MENU:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_UTILITY:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ShellAppInfo *
|
||||
create_transient_app_for_window (MetaWindow *window)
|
||||
{
|
||||
return shell_app_system_create_from_window (shell_app_system_get_default (), window);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_app_for_window_direct:
|
||||
*
|
||||
* Looks only at the given window, and attempts to determine
|
||||
* an application based on WM_CLASS. If that fails, then
|
||||
* a "transient" application is created.
|
||||
*
|
||||
* Return value: (transfer full): A newly-referenced #ShellAppInfo
|
||||
*/
|
||||
static ShellAppInfo *
|
||||
get_app_for_window (MetaWindow *window)
|
||||
get_app_for_window_direct (MetaWindow *window)
|
||||
{
|
||||
char *wmclass;
|
||||
char *with_desktop;
|
||||
ShellAppInfo *result;
|
||||
ShellAppSystem *appsys;
|
||||
char *wmclass;
|
||||
char *with_desktop;
|
||||
|
||||
wmclass = get_cleaned_wmclass_for_window (window);
|
||||
|
||||
if (!wmclass)
|
||||
return NULL;
|
||||
return create_transient_app_for_window (window);
|
||||
|
||||
with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL);
|
||||
g_free (wmclass);
|
||||
@ -301,9 +428,70 @@ get_app_for_window (MetaWindow *window)
|
||||
result = shell_app_system_lookup_heuristic_basename (appsys, with_desktop);
|
||||
g_free (with_desktop);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
const char *id = get_app_id_from_title (window);
|
||||
|
||||
if (id != NULL)
|
||||
result = shell_app_system_load_from_desktop_file (appsys, id, NULL);
|
||||
else
|
||||
result = create_transient_app_for_window (window);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_app_for_window:
|
||||
*
|
||||
* Determines the application associated with a window, using
|
||||
* all available information such as the window's MetaGroup,
|
||||
* and what we know about other windows.
|
||||
*/
|
||||
static ShellAppInfo *
|
||||
get_app_for_window (ShellAppMonitor *monitor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
ShellAppInfo *result;
|
||||
MetaWindow *source_window;
|
||||
GSList *group_windows;
|
||||
MetaGroup *group;
|
||||
GSList *iter;
|
||||
|
||||
group = meta_window_get_group (window);
|
||||
if (group == NULL)
|
||||
group_windows = g_slist_prepend (NULL, window);
|
||||
else
|
||||
group_windows = meta_group_list_windows (group);
|
||||
|
||||
source_window = window;
|
||||
|
||||
result = NULL;
|
||||
/* Try finding a window in the group of type NORMAL; if we
|
||||
* succeed, use that as our source. */
|
||||
for (iter = group_windows; iter; iter = iter->next)
|
||||
{
|
||||
MetaWindow *group_window = iter->data;
|
||||
|
||||
if (meta_window_get_window_type (group_window) != META_WINDOW_NORMAL)
|
||||
continue;
|
||||
|
||||
source_window = group_window;
|
||||
result = g_hash_table_lookup (monitor->window_to_app, group_window);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
|
||||
g_slist_free (group_windows);
|
||||
|
||||
if (result != NULL)
|
||||
{
|
||||
shell_app_info_ref (result);
|
||||
return result;
|
||||
}
|
||||
|
||||
return get_app_for_window_direct (source_window);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_window_context (MetaWindow *window)
|
||||
{
|
||||
@ -368,9 +556,15 @@ get_active_window (ShellAppMonitor *monitor)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
screen = shell_global_get_screen (shell_global_get ());
|
||||
display = meta_screen_get_display (screen);
|
||||
return meta_display_get_focus_window (display);
|
||||
window = meta_display_get_focus_window (display);
|
||||
|
||||
if (window != NULL && window_is_usage_tracked (window))
|
||||
return window;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@ -462,13 +656,6 @@ increment_usage_for_window_at_time (ShellAppMonitor *self,
|
||||
guint usage_count;
|
||||
|
||||
usage = get_app_usage_from_window (self, window);
|
||||
if (usage == NULL)
|
||||
{
|
||||
/* This could in theory happen if we lost the app tracking, i.e.
|
||||
* the window changed WM_CLASS. In that case, time for a punt.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
usage->last_seen = time;
|
||||
|
||||
@ -491,6 +678,62 @@ increment_usage_for_window (ShellAppMonitor *self,
|
||||
increment_usage_for_window_at_time (self, window, curtime);
|
||||
}
|
||||
|
||||
/**
|
||||
* reset_usage:
|
||||
*
|
||||
* For non-transient applications, just reset the "seen sequence".
|
||||
*
|
||||
* For transient ones, we don't want to keep an AppUsage around, so
|
||||
* remove it entirely.
|
||||
*/
|
||||
static void
|
||||
reset_usage (ShellAppMonitor *self,
|
||||
const char *context,
|
||||
const char *appid,
|
||||
AppUsage *usage)
|
||||
{
|
||||
if (!usage->transient)
|
||||
{
|
||||
usage->initially_seen_sequence = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
GHashTable *usages;
|
||||
usages = g_hash_table_lookup (self->app_usages_for_context, context);
|
||||
g_hash_table_remove (usages, appid);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_transient_window_title_changed (MetaWindow *window,
|
||||
GParamSpec *spec,
|
||||
ShellAppMonitor *self)
|
||||
{
|
||||
ShellAppSystem *appsys;
|
||||
ShellAppInfo *current_app;
|
||||
ShellAppInfo *new_app;
|
||||
const char *id;
|
||||
|
||||
current_app = g_hash_table_lookup (self->window_to_app, window);
|
||||
/* Can't have lost the app */
|
||||
g_assert (current_app != NULL);
|
||||
|
||||
/* Check if we now have a mapping using the window title */
|
||||
id = get_app_id_from_title (window);
|
||||
if (id == NULL)
|
||||
return;
|
||||
|
||||
appsys = shell_app_system_get_default ();
|
||||
new_app = shell_app_system_load_from_desktop_file (appsys, id, NULL);
|
||||
if (new_app == NULL)
|
||||
return;
|
||||
shell_app_info_unref (new_app);
|
||||
|
||||
/* It's simplest to just treat this as a remove + add. */
|
||||
disassociate_window (self, window);
|
||||
track_window (self, window);
|
||||
}
|
||||
|
||||
static void
|
||||
track_window (ShellAppMonitor *self,
|
||||
MetaWindow *window)
|
||||
@ -498,23 +741,49 @@ track_window (ShellAppMonitor *self,
|
||||
ShellAppInfo *app;
|
||||
AppUsage *usage;
|
||||
|
||||
app = get_app_for_window (window);
|
||||
if (!window_is_tracked (window))
|
||||
return;
|
||||
|
||||
app = get_app_for_window (self, window);
|
||||
if (!app)
|
||||
return;
|
||||
|
||||
/* At this point we've stored the association from window -> application */
|
||||
g_hash_table_insert (self->window_to_app, window, app);
|
||||
|
||||
usage = get_app_usage_from_window (self, window);
|
||||
/* However, we don't want to record usage for all kinds of windows;
|
||||
* the desktop window is a prime example. If a window isn't usage
|
||||
* tracked it doesn't count for the purposes of an application
|
||||
* running.
|
||||
*/
|
||||
if (!window_is_usage_tracked (window))
|
||||
return;
|
||||
|
||||
/* Ephemerally keep track of the number of windows open for this app,
|
||||
* when it switches between 0 and 1 we emit a changed signal.
|
||||
usage = get_app_usage_from_window (self, window);
|
||||
usage->transient = shell_app_info_is_transient (app);
|
||||
|
||||
if (usage->transient)
|
||||
{
|
||||
/* For a transient application, it's possible one of our title regexps
|
||||
* will match at a later time, i.e. the application may not have set
|
||||
* its title fully at the time it initially maps a window. Watch
|
||||
* for title changes and recompute the app.
|
||||
*/
|
||||
g_signal_connect (window, "notify::title", G_CALLBACK (on_transient_window_title_changed), self);
|
||||
}
|
||||
|
||||
/* Keep track of the number of windows open for this app, when it
|
||||
* switches between 0 and 1 we emit an app-added signal.
|
||||
*/
|
||||
usage->window_count++;
|
||||
if (usage->initially_seen_sequence == 0)
|
||||
usage->initially_seen_sequence = ++self->initially_seen_sequence;
|
||||
usage->last_seen = get_time ();
|
||||
if (usage->window_count == 1)
|
||||
g_signal_emit (self, signals[CHANGED], 0);
|
||||
g_signal_emit (self, signals[APP_ADDED], 0, app);
|
||||
|
||||
/* Emit window-added after app-added */
|
||||
g_signal_emit (self, signals[WINDOW_ADDED], 0, app, window);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -527,33 +796,53 @@ shell_app_monitor_on_window_added (MetaWorkspace *workspace,
|
||||
track_window (self, window);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shell_app_monitor_on_window_removed (MetaWorkspace *workspace,
|
||||
MetaWindow *window,
|
||||
gpointer user_data)
|
||||
disassociate_window (ShellAppMonitor *self,
|
||||
MetaWindow *window)
|
||||
{
|
||||
ShellAppMonitor *self = SHELL_APP_MONITOR (user_data);
|
||||
ShellAppInfo *app;
|
||||
AppUsage *usage;
|
||||
|
||||
app = g_hash_table_lookup (self->window_to_app, window);
|
||||
if (!app)
|
||||
return;
|
||||
|
||||
usage = get_app_usage_from_window (self, window);
|
||||
shell_app_info_ref (app);
|
||||
|
||||
if (window == self->watched_window)
|
||||
self->watched_window = NULL;
|
||||
|
||||
usage->window_count--;
|
||||
/* Remove before emitting */
|
||||
g_hash_table_remove (self->window_to_app, window);
|
||||
|
||||
if (usage->window_count == 0)
|
||||
if (window_is_usage_tracked (window))
|
||||
{
|
||||
usage->initially_seen_sequence = 0;
|
||||
g_signal_emit (self, signals[CHANGED], 0);
|
||||
AppUsage *usage;
|
||||
const char *context;
|
||||
|
||||
context = get_window_context (window);
|
||||
usage = get_app_usage_from_window (self, window);
|
||||
usage->window_count--;
|
||||
|
||||
g_hash_table_remove (self->window_to_app, window);
|
||||
|
||||
g_signal_emit (self, signals[WINDOW_REMOVED], 0, app, window);
|
||||
|
||||
if (usage->window_count == 0)
|
||||
{
|
||||
g_signal_emit (self, signals[APP_REMOVED], 0, app);
|
||||
reset_usage (self, context, shell_app_info_get_id (app), usage);
|
||||
}
|
||||
}
|
||||
else
|
||||
g_hash_table_remove (self->window_to_app, window);
|
||||
|
||||
shell_app_info_unref (app);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_monitor_on_window_removed (MetaWorkspace *workspace,
|
||||
MetaWindow *window,
|
||||
gpointer user_data)
|
||||
{
|
||||
disassociate_window (SHELL_APP_MONITOR (user_data), window);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -621,6 +910,8 @@ on_session_status_changed (DBusGProxy *proxy,
|
||||
* @self:
|
||||
* @appid: Find windows for this id
|
||||
*
|
||||
* Returns the normal toplevel windows associated with the given application.
|
||||
*
|
||||
* Returns: (transfer container) (element-type MetaWindow): List of #MetaWindow corresponding to appid
|
||||
*/
|
||||
GSList *
|
||||
@ -639,6 +930,9 @@ shell_app_monitor_get_windows_for_app (ShellAppMonitor *self,
|
||||
ShellAppInfo *app = value;
|
||||
const char *id = shell_app_info_get_id (app);
|
||||
|
||||
if (!window_is_usage_tracked (window))
|
||||
continue;
|
||||
|
||||
if (strcmp (id, appid) != 0)
|
||||
continue;
|
||||
|
||||
@ -694,9 +988,19 @@ init_window_monitoring (ShellAppMonitor *self)
|
||||
shell_app_monitor_on_n_workspaces_changed (screen, NULL, self);
|
||||
}
|
||||
|
||||
static void
|
||||
on_startup_sequence_changed (MetaScreen *screen,
|
||||
SnStartupSequence *sequence,
|
||||
ShellAppMonitor *self)
|
||||
{
|
||||
/* Just proxy the signal */
|
||||
g_signal_emit (G_OBJECT (self), signals[STARTUP_SEQUENCE_CHANGED], 0, sequence);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_app_monitor_init (ShellAppMonitor *self)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
GdkDisplay *display;
|
||||
char *path;
|
||||
char *shell_config_dir;
|
||||
@ -704,6 +1008,7 @@ shell_app_monitor_init (ShellAppMonitor *self)
|
||||
|
||||
/* FIXME: should we create as many monitors as there are GdkScreens? */
|
||||
display = gdk_display_get_default ();
|
||||
screen = shell_global_get_screen (shell_global_get ());
|
||||
|
||||
session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
||||
self->session_proxy = dbus_g_proxy_new_for_name (session_bus, "org.gnome.SessionManager",
|
||||
@ -735,6 +1040,9 @@ shell_app_monitor_init (ShellAppMonitor *self)
|
||||
load_initial_windows (self);
|
||||
init_window_monitoring (self);
|
||||
|
||||
g_signal_connect (G_OBJECT (screen), "startup-sequence-changed",
|
||||
G_CALLBACK (on_startup_sequence_changed), self);
|
||||
|
||||
self->gconf_client = gconf_client_get_default ();
|
||||
gconf_client_add_dir (self->gconf_client, APP_MONITOR_GCONF_DIR,
|
||||
GCONF_CLIENT_PRELOAD_NONE, NULL);
|
||||
@ -793,13 +1101,20 @@ shell_app_monitor_get_most_used_apps (ShellAppMonitor *monitor,
|
||||
* @monitor: An app monitor instance
|
||||
* @metawin: A #MetaWindow
|
||||
*
|
||||
* Returns: Desktop file id associated with window
|
||||
* Returns: Application associated with window
|
||||
*/
|
||||
ShellAppInfo *
|
||||
shell_app_monitor_get_window_app (ShellAppMonitor *monitor,
|
||||
MetaWindow *metawin)
|
||||
{
|
||||
ShellAppInfo *info = g_hash_table_lookup (monitor->window_to_app, metawin);
|
||||
MetaWindow *transient_for;
|
||||
ShellAppInfo *info;
|
||||
|
||||
transient_for = meta_window_get_transient_for (metawin);
|
||||
if (transient_for != NULL)
|
||||
metawin = transient_for;
|
||||
|
||||
info = g_hash_table_lookup (monitor->window_to_app, metawin);
|
||||
if (info)
|
||||
shell_app_info_ref (info);
|
||||
return info;
|
||||
@ -816,8 +1131,10 @@ sort_apps_by_open_sequence (gconstpointer a,
|
||||
gpointer datap)
|
||||
{
|
||||
AppOpenSequenceSortData *data = datap;
|
||||
const char *id_a = a;
|
||||
const char *id_b = b;
|
||||
ShellAppInfo *app_a = (ShellAppInfo*)a;
|
||||
ShellAppInfo *app_b = (ShellAppInfo*)b;
|
||||
const char *id_a = shell_app_info_get_id (app_a);
|
||||
const char *id_b = shell_app_info_get_id (app_b);
|
||||
AppUsage *usage_a;
|
||||
AppUsage *usage_b;
|
||||
|
||||
@ -831,38 +1148,51 @@ sort_apps_by_open_sequence (gconstpointer a,
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_monitor_get_running_app_ids:
|
||||
* shell_app_monitor_get_running_apps:
|
||||
* @monitor: An app monitor instance
|
||||
* @context: Activity identifier
|
||||
*
|
||||
* Returns the set of applications which currently have at least one open
|
||||
* window in the given context.
|
||||
*
|
||||
* Returns: (element-type utf8) (transfer container): List of application desktop
|
||||
* identifiers
|
||||
* Returns: (element-type ShellAppInfo) (transfer container): Active applications
|
||||
*/
|
||||
GSList *
|
||||
shell_app_monitor_get_running_app_ids (ShellAppMonitor *monitor,
|
||||
const char *context)
|
||||
shell_app_monitor_get_running_apps (ShellAppMonitor *monitor,
|
||||
const char *context)
|
||||
{
|
||||
UsageIterator iter;
|
||||
const char *cur_context;
|
||||
const char *id;
|
||||
AppUsage *usage;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
GSList *ret;
|
||||
AppOpenSequenceSortData data;
|
||||
GHashTable *unique_apps;
|
||||
|
||||
usage_iterator_init (monitor, &iter);
|
||||
unique_apps = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_iter_init (&iter, monitor->window_to_app);
|
||||
|
||||
ret = NULL;
|
||||
while (usage_iterator_next (monitor, &iter, &cur_context, &id, &usage))
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
if (strcmp (cur_context, context) != 0)
|
||||
MetaWindow *window = key;
|
||||
ShellAppInfo *app = value;
|
||||
const char *id;
|
||||
|
||||
if (strcmp (get_window_context (window), context) != 0)
|
||||
continue;
|
||||
|
||||
if (usage->window_count > 0)
|
||||
ret = g_slist_prepend (ret, (char*)id);
|
||||
if (!window_is_usage_tracked (window))
|
||||
continue;
|
||||
|
||||
id = shell_app_info_get_id (app);
|
||||
|
||||
if (g_hash_table_lookup (unique_apps, id))
|
||||
continue;
|
||||
g_hash_table_insert (unique_apps, (gpointer)id, (gpointer)id);
|
||||
|
||||
ret = g_slist_prepend (ret, app);
|
||||
}
|
||||
g_hash_table_destroy (unique_apps);
|
||||
|
||||
data.self = monitor;
|
||||
data.context_id = context;
|
||||
@ -875,7 +1205,8 @@ idle_handle_focus_change (gpointer data)
|
||||
ShellAppMonitor *monitor = data;
|
||||
long curtime = get_time ();
|
||||
|
||||
increment_usage_for_window (monitor, monitor->watched_window);
|
||||
if (monitor->watched_window != NULL)
|
||||
increment_usage_for_window (monitor, monitor->watched_window);
|
||||
|
||||
monitor->watched_window = get_active_window (monitor);
|
||||
monitor->watch_start_time = curtime;
|
||||
@ -1038,7 +1369,6 @@ idle_save_application_usage (gpointer data)
|
||||
GDataOutputStream *data_output;
|
||||
GError *error = NULL;
|
||||
|
||||
|
||||
monitor->save_id = 0;
|
||||
|
||||
/* Parent directory is already created by shell-global */
|
||||
@ -1062,6 +1392,10 @@ idle_save_application_usage (gpointer data)
|
||||
current_context = NULL;
|
||||
while (usage_iterator_next (monitor, &iter, &context, &id, &usage))
|
||||
{
|
||||
/* Don't save the fake apps we create for windows */
|
||||
if (usage->transient)
|
||||
continue;
|
||||
|
||||
if (context != current_context)
|
||||
{
|
||||
if (current_context != NULL)
|
||||
@ -1323,7 +1657,10 @@ update_enable_monitoring (ShellAppMonitor *monitor)
|
||||
{
|
||||
monitor->watched_window = NULL;
|
||||
if (monitor->save_id)
|
||||
g_source_remove (monitor->save_id);
|
||||
{
|
||||
g_source_remove (monitor->save_id);
|
||||
monitor->save_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
monitor->enable_monitoring = enable;
|
||||
@ -1339,6 +1676,90 @@ on_enable_monitoring_key_changed (GConfClient *client,
|
||||
update_enable_monitoring ((ShellAppMonitor *) monitor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* shell_app_monitor_get_startup_sequences:
|
||||
* @self:
|
||||
*
|
||||
* Returns: (transfer none) (element-type ShellStartupSequence): Currently active startup sequences
|
||||
*/
|
||||
GSList *
|
||||
shell_app_monitor_get_startup_sequences (ShellAppMonitor *self)
|
||||
{
|
||||
ShellGlobal *global = shell_global_get ();
|
||||
MetaScreen *screen = shell_global_get_screen (global);
|
||||
return meta_screen_get_startup_sequences (screen);
|
||||
}
|
||||
|
||||
/* sn_startup_sequence_ref returns void, so make a
|
||||
* wrapper which returns self */
|
||||
static SnStartupSequence *
|
||||
sequence_ref (SnStartupSequence *sequence)
|
||||
{
|
||||
sn_startup_sequence_ref (sequence);
|
||||
return sequence;
|
||||
}
|
||||
|
||||
GType
|
||||
shell_startup_sequence_get_type (void)
|
||||
{
|
||||
static GType gtype = G_TYPE_INVALID;
|
||||
if (gtype == G_TYPE_INVALID)
|
||||
{
|
||||
gtype = g_boxed_type_register_static ("ShellStartupSequence",
|
||||
(GBoxedCopyFunc)sequence_ref,
|
||||
(GBoxedFreeFunc)sn_startup_sequence_unref);
|
||||
}
|
||||
return gtype;
|
||||
}
|
||||
|
||||
const char *
|
||||
shell_startup_sequence_get_id (ShellStartupSequence *sequence)
|
||||
{
|
||||
return sn_startup_sequence_get_id ((SnStartupSequence*)sequence);
|
||||
}
|
||||
|
||||
const char *
|
||||
shell_startup_sequence_get_name (ShellStartupSequence *sequence)
|
||||
{
|
||||
return sn_startup_sequence_get_name ((SnStartupSequence*)sequence);
|
||||
}
|
||||
|
||||
gboolean
|
||||
shell_startup_sequence_get_completed (ShellStartupSequence *sequence)
|
||||
{
|
||||
return sn_startup_sequence_get_completed ((SnStartupSequence*)sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_startup_sequence_create_icon:
|
||||
* @sequence:
|
||||
* @size: Size in pixels of icon
|
||||
*
|
||||
* Returns: (transfer none): A new #ClutterTexture containing an icon for the sequence
|
||||
*/
|
||||
ClutterActor *
|
||||
shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size)
|
||||
{
|
||||
GThemedIcon *themed;
|
||||
const char *icon_name;
|
||||
ClutterActor *texture;
|
||||
|
||||
icon_name = sn_startup_sequence_get_icon_name ((SnStartupSequence*)sequence);
|
||||
if (!icon_name)
|
||||
{
|
||||
texture = clutter_texture_new ();
|
||||
clutter_actor_set_size (texture, size, size);
|
||||
return texture;
|
||||
}
|
||||
|
||||
themed = (GThemedIcon*)g_themed_icon_new (icon_name);
|
||||
texture = shell_texture_cache_load_gicon (shell_texture_cache_get_default (),
|
||||
G_ICON (themed), size);
|
||||
g_object_unref (G_OBJECT (themed));
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_monitor_get_default:
|
||||
*
|
||||
|
@ -30,8 +30,6 @@ struct _ShellAppMonitorClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*apps_changed)(ShellAppMonitor *menuwrapper,
|
||||
gpointer data);
|
||||
};
|
||||
|
||||
GType shell_app_monitor_get_type (void) G_GNUC_CONST;
|
||||
@ -47,7 +45,19 @@ GList *shell_app_monitor_get_most_used_apps (ShellAppMonitor *monitor,
|
||||
GSList *shell_app_monitor_get_windows_for_app (ShellAppMonitor *monitor, const char *appid);
|
||||
|
||||
/* Get whatever's running right now */
|
||||
GSList *shell_app_monitor_get_running_app_ids (ShellAppMonitor *monitor, const char *context);
|
||||
GSList *shell_app_monitor_get_running_apps (ShellAppMonitor *monitor, const char *context);
|
||||
|
||||
GSList *shell_app_monitor_get_startup_sequences (ShellAppMonitor *monitor);
|
||||
|
||||
/* Hidden typedef for SnStartupSequence */
|
||||
typedef struct _ShellStartupSequence ShellStartupSequence;
|
||||
#define SHELL_TYPE_STARTUP_SEQUENCE (shell_startup_sequence_get_type ())
|
||||
GType shell_startup_sequence_get_type (void);
|
||||
|
||||
const char *shell_startup_sequence_get_id (ShellStartupSequence *sequence);
|
||||
const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
|
||||
gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
|
||||
ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gconf/gconf.h>
|
||||
#include <gconf/gconf-client.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "shell-global.h"
|
||||
#include "shell-texture-cache.h"
|
||||
@ -18,6 +19,13 @@
|
||||
|
||||
#define SHELL_APP_FAVORITES_KEY "/desktop/gnome/shell/favorite_apps"
|
||||
|
||||
/* Vendor prefixes are something that can be preprended to a .desktop
|
||||
* file name. Undo this.
|
||||
*/
|
||||
static const char*const known_vendor_prefixes[] = { "gnome",
|
||||
"fedora",
|
||||
"mozilla" };
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
@ -56,7 +64,8 @@ G_DEFINE_TYPE(ShellAppSystem, shell_app_system, G_TYPE_OBJECT);
|
||||
|
||||
typedef enum {
|
||||
SHELL_APP_INFO_TYPE_ENTRY,
|
||||
SHELL_APP_INFO_TYPE_DESKTOP_FILE
|
||||
SHELL_APP_INFO_TYPE_DESKTOP_FILE,
|
||||
SHELL_APP_INFO_TYPE_WINDOW
|
||||
} ShellAppInfoType;
|
||||
|
||||
struct _ShellAppInfo {
|
||||
@ -74,6 +83,9 @@ struct _ShellAppInfo {
|
||||
|
||||
GKeyFile *keyfile;
|
||||
char *keyfile_path;
|
||||
|
||||
MetaWindow *window;
|
||||
char *window_id;
|
||||
};
|
||||
|
||||
ShellAppInfo*
|
||||
@ -97,6 +109,10 @@ shell_app_info_unref (ShellAppInfo *info)
|
||||
g_key_file_free (info->keyfile);
|
||||
g_free (info->keyfile_path);
|
||||
break;
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
g_object_unref (info->window);
|
||||
g_free (info->window_id);
|
||||
break;
|
||||
}
|
||||
g_slice_free (ShellAppInfo, info);
|
||||
}
|
||||
@ -116,6 +132,23 @@ shell_app_info_new_from_tree_item (GMenuTreeItem *item)
|
||||
return info;
|
||||
}
|
||||
|
||||
static ShellAppInfo *
|
||||
shell_app_info_new_from_window (MetaWindow *window)
|
||||
{
|
||||
ShellAppInfo *info;
|
||||
|
||||
info = g_slice_alloc (sizeof (ShellAppInfo));
|
||||
info->type = SHELL_APP_INFO_TYPE_WINDOW;
|
||||
info->refcount = 1;
|
||||
info->window = g_object_ref (window);
|
||||
/* For windows, its id is simply its pointer address as a string.
|
||||
* There are various other alternatives, but the address is unique
|
||||
* and unchanging, which is pretty much the best we can do.
|
||||
*/
|
||||
info->window_id = g_strdup_printf ("window:%p", window);
|
||||
return info;
|
||||
}
|
||||
|
||||
static ShellAppInfo *
|
||||
shell_app_info_new_from_keyfile_take_ownership (GKeyFile *keyfile,
|
||||
const char *path)
|
||||
@ -573,8 +606,6 @@ set_gconf_value_string_list (GConfValue *val, GList *items)
|
||||
g_slist_free (tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
shell_app_system_add_favorite (ShellAppSystem *system, const char *id)
|
||||
{
|
||||
@ -669,6 +700,21 @@ shell_app_system_load_from_desktop_file (ShellAppSystem *system,
|
||||
return appinfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_create_from_window:
|
||||
*
|
||||
* In the case where we can't otherwise determine an application
|
||||
* associated with a window, this function can create a "fake"
|
||||
* application just backed by information from the window itself.
|
||||
*
|
||||
* Return value: (transfer full): A new #ShellAppInfo
|
||||
*/
|
||||
ShellAppInfo *
|
||||
shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window)
|
||||
{
|
||||
return shell_app_info_new_from_window (window);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_system_lookup_heuristic_basename:
|
||||
* @name: Probable application identifier
|
||||
@ -683,28 +729,22 @@ ShellAppInfo *
|
||||
shell_app_system_lookup_heuristic_basename (ShellAppSystem *system,
|
||||
const char *name)
|
||||
{
|
||||
char *tmpid;
|
||||
ShellAppInfo *result;
|
||||
char **vendor_prefixes;
|
||||
|
||||
result = shell_app_system_lookup_cached_app (system, name);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
/* These are common "vendor prefixes". But using
|
||||
* WM_CLASS as a source, we don't get the vendor
|
||||
* prefix. So try stripping them.
|
||||
*/
|
||||
tmpid = g_strjoin ("", "gnome-", name, NULL);
|
||||
result = shell_app_system_lookup_cached_app (system, tmpid);
|
||||
g_free (tmpid);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
tmpid = g_strjoin ("", "fedora-", name, NULL);
|
||||
result = shell_app_system_lookup_cached_app (system, tmpid);
|
||||
g_free (tmpid);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
for (vendor_prefixes = (char**)known_vendor_prefixes;
|
||||
*vendor_prefixes; vendor_prefixes++)
|
||||
{
|
||||
char *tmpid = g_strjoin (NULL, *vendor_prefixes, "-", name, NULL);
|
||||
result = shell_app_system_lookup_cached_app (system, tmpid);
|
||||
g_free (tmpid);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -718,6 +758,8 @@ shell_app_info_get_id (ShellAppInfo *info)
|
||||
return gmenu_tree_entry_get_desktop_file_id ((GMenuTreeEntry*)info->entry);
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
return info->keyfile_path;
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return info->window_id;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
@ -734,6 +776,12 @@ shell_app_info_get_name (ShellAppInfo *info)
|
||||
return g_strdup (gmenu_tree_entry_get_name ((GMenuTreeEntry*)info->entry));
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Name", NULL, NULL);
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
{
|
||||
char *title;
|
||||
g_object_get (info->window, "title", &title, NULL);
|
||||
return title;
|
||||
}
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
@ -748,6 +796,8 @@ shell_app_info_get_description (ShellAppInfo *info)
|
||||
return g_strdup (gmenu_tree_entry_get_comment ((GMenuTreeEntry*)info->entry));
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Comment", NULL, NULL);
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return NULL;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
@ -762,6 +812,8 @@ shell_app_info_get_executable (ShellAppInfo *info)
|
||||
return g_strdup (gmenu_tree_entry_get_exec ((GMenuTreeEntry*)info->entry));
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
return g_key_file_get_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Exec", NULL);
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return NULL;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
@ -775,13 +827,49 @@ shell_app_info_get_desktop_file_path (ShellAppInfo *info)
|
||||
case SHELL_APP_INFO_TYPE_ENTRY:
|
||||
return g_strdup (gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*)info->entry));
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
return g_strdup (info->keyfile_path);;
|
||||
return g_strdup (info->keyfile_path);
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return NULL;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GIcon *
|
||||
static GIcon *
|
||||
themed_icon_from_name (const char *iconname)
|
||||
{
|
||||
GIcon *icon;
|
||||
|
||||
if (!iconname)
|
||||
return NULL;
|
||||
|
||||
if (g_path_is_absolute (iconname))
|
||||
{
|
||||
GFile *file;
|
||||
file = g_file_new_for_path (iconname);
|
||||
icon = G_ICON (g_file_icon_new (file));
|
||||
g_object_unref (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp_name, *p;
|
||||
tmp_name = strdup (iconname);
|
||||
/* Work around a common mistake in desktop files */
|
||||
if ((p = strrchr (tmp_name, '.')) != NULL &&
|
||||
(strcmp (p, ".png") == 0 ||
|
||||
strcmp (p, ".xpm") == 0 ||
|
||||
strcmp (p, ".svg") == 0))
|
||||
{
|
||||
*p = 0;
|
||||
}
|
||||
icon = g_themed_icon_new (tmp_name);
|
||||
g_free (tmp_name);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
static GIcon *
|
||||
shell_app_info_get_icon (ShellAppInfo *info)
|
||||
{
|
||||
char *iconname = NULL;
|
||||
@ -796,43 +884,18 @@ shell_app_info_get_icon (ShellAppInfo *info)
|
||||
switch (info->type)
|
||||
{
|
||||
case SHELL_APP_INFO_TYPE_ENTRY:
|
||||
iconname = g_strdup (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
|
||||
break;
|
||||
return themed_icon_from_name (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL);
|
||||
icon = themed_icon_from_name (iconname);
|
||||
g_free (iconname);
|
||||
return icon;
|
||||
break;
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!iconname)
|
||||
return NULL;
|
||||
|
||||
if (g_path_is_absolute (iconname))
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path (iconname);
|
||||
icon = G_ICON (g_file_icon_new (file));
|
||||
g_object_unref (file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp_name, *p;
|
||||
tmp_name = strdup (iconname);
|
||||
/* Work around a common mistake in desktop files */
|
||||
if ((p = strrchr (tmp_name, '.')) != NULL &&
|
||||
(strcmp (p, ".png") == 0 ||
|
||||
strcmp (p, ".xpm") == 0 ||
|
||||
strcmp (p, ".svg") == 0))
|
||||
{
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
icon = g_themed_icon_new (tmp_name);
|
||||
g_free (tmp_name);
|
||||
}
|
||||
g_free (iconname);
|
||||
|
||||
return icon;
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GSList *
|
||||
@ -847,14 +910,28 @@ shell_app_info_get_is_nodisplay (ShellAppInfo *info)
|
||||
switch (info->type)
|
||||
{
|
||||
case SHELL_APP_INFO_TYPE_ENTRY:
|
||||
return gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry*)info);
|
||||
return gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry*)info->entry);
|
||||
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
|
||||
case SHELL_APP_INFO_TYPE_WINDOW:
|
||||
return FALSE;
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_info_is_transient:
|
||||
*
|
||||
* A "transient" application is one which represents
|
||||
* just an open window, i.e. we don't know how to launch it
|
||||
* again.
|
||||
*/
|
||||
gboolean
|
||||
shell_app_info_is_transient (ShellAppInfo *info)
|
||||
{
|
||||
return info->type == SHELL_APP_INFO_TYPE_WINDOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_info_create_icon_texture:
|
||||
*
|
||||
@ -869,6 +946,13 @@ shell_app_info_create_icon_texture (ShellAppInfo *info, float size)
|
||||
GIcon *icon;
|
||||
ClutterActor *ret;
|
||||
|
||||
if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
|
||||
{
|
||||
return shell_texture_cache_bind_pixbuf_property (shell_texture_cache_get_default (),
|
||||
G_OBJECT (info->window),
|
||||
"icon");
|
||||
}
|
||||
|
||||
icon = shell_app_info_get_icon (info);
|
||||
if (!icon)
|
||||
{
|
||||
@ -907,6 +991,17 @@ shell_app_info_launch_full (ShellAppInfo *info,
|
||||
if (startup_id)
|
||||
*startup_id = NULL;
|
||||
|
||||
if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
|
||||
{
|
||||
/* We can't pass URIs into a window; shouldn't hit this
|
||||
* code path. If we do, fix the caller to disallow it.
|
||||
*/
|
||||
g_return_val_if_fail (uris == NULL, TRUE);
|
||||
|
||||
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);
|
||||
@ -922,7 +1017,13 @@ shell_app_info_launch_full (ShellAppInfo *info,
|
||||
display = meta_screen_get_display (screen);
|
||||
|
||||
if (timestamp == 0)
|
||||
timestamp = meta_display_get_current_time (display);
|
||||
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);
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <gio/gio.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
#define SHELL_TYPE_APP_SYSTEM (shell_app_system_get_type ())
|
||||
#define SHELL_APP_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_APP_SYSTEM, ShellAppSystem))
|
||||
#define SHELL_APP_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_APP_SYSTEM, ShellAppSystemClass))
|
||||
@ -58,10 +60,10 @@ char *shell_app_info_get_name (ShellAppInfo *info);
|
||||
char *shell_app_info_get_description (ShellAppInfo *info);
|
||||
char *shell_app_info_get_executable (ShellAppInfo *info);
|
||||
char *shell_app_info_get_desktop_file_path (ShellAppInfo *info);
|
||||
GIcon *shell_app_info_get_icon (ShellAppInfo *info);
|
||||
ClutterActor *shell_app_info_create_icon_texture (ShellAppInfo *info, float size);
|
||||
GSList *shell_app_info_get_categories (ShellAppInfo *info);
|
||||
gboolean shell_app_info_get_is_nodisplay (ShellAppInfo *info);
|
||||
gboolean shell_app_info_is_transient (ShellAppInfo *info);
|
||||
gboolean shell_app_info_launch_full (ShellAppInfo *info,
|
||||
guint timestamp,
|
||||
GList *uris,
|
||||
@ -77,6 +79,8 @@ ShellAppInfo *shell_app_system_lookup_cached_app (ShellAppSystem *system, const
|
||||
|
||||
ShellAppInfo *shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, const char *id);
|
||||
|
||||
ShellAppInfo *shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window);
|
||||
|
||||
GSList *shell_app_system_get_menus (ShellAppSystem *system);
|
||||
|
||||
GSList *shell_app_system_get_all_settings (ShellAppSystem *system);
|
||||
|
248
src/shell-button-box.c
Normal file
248
src/shell-button-box.c
Normal file
@ -0,0 +1,248 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/**
|
||||
* SECTION:shell-button-box
|
||||
* @short_description: A box with properties useful for implementing buttons
|
||||
*
|
||||
* A #BigBox subclass which translates lower-level Clutter button events
|
||||
* into higher level properties which are useful for implementing "button-like"
|
||||
* actors.
|
||||
*/
|
||||
|
||||
#include "shell-button-box.h"
|
||||
|
||||
G_DEFINE_TYPE(ShellButtonBox, shell_button_box, BIG_TYPE_BOX);
|
||||
|
||||
struct _ShellButtonBoxPrivate {
|
||||
gboolean held;
|
||||
gboolean hover;
|
||||
gboolean pressed;
|
||||
};
|
||||
|
||||
/* Signals */
|
||||
enum
|
||||
{
|
||||
ACTIVATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_HOVER,
|
||||
PROP_PRESSED,
|
||||
};
|
||||
|
||||
static guint shell_button_box_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
set_hover (ShellButtonBox *box,
|
||||
gboolean hover)
|
||||
{
|
||||
if (box->priv->hover == hover)
|
||||
return;
|
||||
box->priv->hover = hover;
|
||||
g_object_notify (G_OBJECT (box), "hover");
|
||||
}
|
||||
|
||||
static void
|
||||
set_pressed (ShellButtonBox *box,
|
||||
gboolean pressed)
|
||||
{
|
||||
if (box->priv->pressed == pressed)
|
||||
return;
|
||||
box->priv->pressed = pressed;
|
||||
g_object_notify (G_OBJECT (box), "pressed");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_button_box_contains (ShellButtonBox *box,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
while (actor != NULL && actor != (ClutterActor*)box)
|
||||
{
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
return actor != NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_button_box_on_enter (ShellButtonBox *box,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (shell_button_box_contains (box, event->crossing.related))
|
||||
return TRUE;
|
||||
if (!shell_button_box_contains (box, clutter_event_get_source (event)))
|
||||
return TRUE;
|
||||
|
||||
set_hover (box, TRUE);
|
||||
if (box->priv->held)
|
||||
set_pressed (box, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_button_box_on_leave (ShellButtonBox *box,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (shell_button_box_contains (box, event->crossing.related))
|
||||
return TRUE;
|
||||
|
||||
set_hover (box, FALSE);
|
||||
set_pressed (box, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_button_box_on_press (ShellButtonBox *box,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterActor *source;
|
||||
|
||||
if (box->priv->held)
|
||||
return TRUE;
|
||||
|
||||
source = clutter_event_get_source (event);
|
||||
if (!shell_button_box_contains (box, source))
|
||||
return FALSE;
|
||||
|
||||
box->priv->held = TRUE;
|
||||
clutter_grab_pointer (CLUTTER_ACTOR (box));
|
||||
|
||||
set_pressed (box, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
shell_button_box_on_release (ShellButtonBox *box,
|
||||
ClutterEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterActor *source;
|
||||
|
||||
if (!box->priv->held)
|
||||
return TRUE;
|
||||
|
||||
source = clutter_event_get_source (event);
|
||||
|
||||
box->priv->held = FALSE;
|
||||
clutter_ungrab_pointer ();
|
||||
|
||||
if (!shell_button_box_contains (box, source))
|
||||
return FALSE;
|
||||
|
||||
set_pressed (box, FALSE);
|
||||
|
||||
g_signal_emit (G_OBJECT (box), shell_button_box_signals[ACTIVATE], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_button_box_set_property(GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_button_box_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ShellButtonBox *box = SHELL_BUTTON_BOX (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PRESSED:
|
||||
g_value_set_boolean (value, box->priv->pressed);
|
||||
break;
|
||||
case PROP_HOVER:
|
||||
g_value_set_boolean (value, box->priv->hover);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
shell_button_box_class_init (ShellButtonBoxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = shell_button_box_get_property;
|
||||
gobject_class->set_property = shell_button_box_set_property;
|
||||
|
||||
/**
|
||||
* ShellButtonBox::activate
|
||||
* @box: The #ShellButtonBox
|
||||
*
|
||||
* This signal is emitted when the button should take the action
|
||||
* associated with button click+release.
|
||||
*/
|
||||
shell_button_box_signals[ACTIVATE] =
|
||||
g_signal_new ("activate",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* ShellButtonBox:hover
|
||||
*
|
||||
* This property tracks whether the mouse is over the button; note this
|
||||
* state is independent of whether the button is pressed.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_HOVER,
|
||||
g_param_spec_boolean ("hover",
|
||||
"Hovering state",
|
||||
"Whether the mouse is over the button",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
/**
|
||||
* ShellButtonBox:pressed
|
||||
*
|
||||
* This property tracks whether the button should have a "pressed in"
|
||||
* effect.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PRESSED,
|
||||
g_param_spec_boolean ("pressed",
|
||||
"Pressed state",
|
||||
"Whether the button is currently pressed",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (ShellButtonBoxPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
shell_button_box_init (ShellButtonBox *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SHELL_TYPE_BUTTON_BOX,
|
||||
ShellButtonBoxPrivate);
|
||||
|
||||
g_signal_connect (G_OBJECT (self), "enter-event", G_CALLBACK(shell_button_box_on_enter), NULL);
|
||||
g_signal_connect (G_OBJECT (self), "leave-event", G_CALLBACK(shell_button_box_on_leave), NULL);
|
||||
g_signal_connect (G_OBJECT (self), "button-press-event", G_CALLBACK(shell_button_box_on_press), NULL);
|
||||
g_signal_connect (G_OBJECT (self), "button-release-event", G_CALLBACK(shell_button_box_on_release), NULL);
|
||||
}
|
33
src/shell-button-box.h
Normal file
33
src/shell-button-box.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __SHELL_BUTTON_BOX_H__
|
||||
#define __SHELL_BUTTON_BOX_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include "big/box.h"
|
||||
|
||||
#define SHELL_TYPE_BUTTON_BOX (shell_button_box_get_type ())
|
||||
#define SHELL_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_BUTTON_BOX, ShellButtonBox))
|
||||
#define SHELL_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_BUTTON_BOX, ShellButtonBoxClass))
|
||||
#define SHELL_IS_BUTTON_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SHELL_TYPE_BUTTON_BOX))
|
||||
#define SHELL_IS_BUTTON_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_BUTTON_BOX))
|
||||
#define SHELL_BUTTON_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_BUTTON_BOX, ShellButtonBoxClass))
|
||||
|
||||
typedef struct _ShellButtonBox ShellButtonBox;
|
||||
typedef struct _ShellButtonBoxClass ShellButtonBoxClass;
|
||||
|
||||
typedef struct _ShellButtonBoxPrivate ShellButtonBoxPrivate;
|
||||
|
||||
struct _ShellButtonBox
|
||||
{
|
||||
BigBox parent;
|
||||
|
||||
ShellButtonBoxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _ShellButtonBoxClass
|
||||
{
|
||||
BigBoxClass parent_class;
|
||||
};
|
||||
|
||||
GType shell_button_box_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* __SHELL_BUTTON_BOX_H__ */
|
@ -40,8 +40,18 @@ shell_drawing_area_allocate (ClutterActor *self,
|
||||
ShellDrawingArea *area = SHELL_DRAWING_AREA (self);
|
||||
int width = box->x2 - box->x1;
|
||||
int height = box->y2 - box->y1;
|
||||
ClutterActorBox child_box;
|
||||
|
||||
clutter_actor_allocate (CLUTTER_ACTOR (area->priv->texture), box, flags);
|
||||
/* Chain up directly to ClutterActor to set actor->allocation. We explicitly skip our parent class
|
||||
* ClutterGroup here because we want to override the allocate function. */
|
||||
(CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->allocate (self, box, flags);
|
||||
|
||||
child_box.x1 = 0;
|
||||
child_box.x2 = width;
|
||||
child_box.y1 = 0;
|
||||
child_box.y2 = height;
|
||||
|
||||
clutter_actor_allocate (CLUTTER_ACTOR (area->priv->texture), &child_box, flags);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
clutter_cairo_texture_set_surface_size (area->priv->texture,
|
||||
|
@ -146,25 +146,12 @@ shell_draw_clock (ClutterCairoTexture *texture,
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
void
|
||||
shell_draw_glow (ClutterCairoTexture *texture,
|
||||
double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha)
|
||||
static void
|
||||
draw_glow (cairo_t *cr, double red, double green, double blue, double alpha)
|
||||
{
|
||||
cairo_t *cr;
|
||||
guint width, height;
|
||||
cairo_pattern_t *gradient;
|
||||
|
||||
clutter_cairo_texture_get_surface_size (texture, &width, &height);
|
||||
|
||||
clutter_cairo_texture_clear (texture);
|
||||
cr = clutter_cairo_texture_create (texture);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||
cairo_scale (cr, width / 2.0, height / 2.0);
|
||||
|
||||
gradient = cairo_pattern_create_radial (0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
|
||||
cairo_pattern_add_color_stop_rgba (gradient, 0.0, red, green, blue, alpha);
|
||||
@ -174,8 +161,64 @@ shell_draw_glow (ClutterCairoTexture *texture,
|
||||
|
||||
cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 2.0 * M_PI);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
cairo_pattern_destroy (gradient);
|
||||
}
|
||||
|
||||
void
|
||||
shell_draw_app_highlight (ClutterCairoTexture *texture,
|
||||
int num_windows,
|
||||
double red,
|
||||
double green,
|
||||
double blue,
|
||||
double alpha)
|
||||
{
|
||||
cairo_t *cr;
|
||||
guint width, height;
|
||||
|
||||
g_return_if_fail (num_windows > 0);
|
||||
|
||||
clutter_cairo_texture_get_surface_size (texture, &width, &height);
|
||||
|
||||
clutter_cairo_texture_clear (texture);
|
||||
cr = clutter_cairo_texture_create (texture);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||
|
||||
if (num_windows == 1)
|
||||
{
|
||||
cairo_scale (cr, width / 2.0, height / 2.0);
|
||||
draw_glow (cr, red, green, blue, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
int num_circles, i;
|
||||
double scale, highlight_width;
|
||||
|
||||
num_circles = num_windows == 2 ? 2 : 3;
|
||||
|
||||
/* The circles will have radius 1.0 (diameter 2.0) and overlap
|
||||
* by 0.2, so the total width of the highlight is:
|
||||
*/
|
||||
highlight_width = 2.0 * num_circles - 0.2 * (num_circles - 1);
|
||||
|
||||
scale = MIN (height / 2.0, width / highlight_width);
|
||||
cairo_scale (cr, scale, scale);
|
||||
|
||||
/* The leftmost circle's left side is at -highlight_width/2, so
|
||||
* its center is that plus 1.
|
||||
*/
|
||||
cairo_translate (cr, -highlight_width / 2.0 + 1.0, 0.0);
|
||||
for (i = 0; i < num_circles; i++)
|
||||
{
|
||||
draw_glow (cr, red, green, blue, alpha);
|
||||
cairo_translate (cr, 1.8, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,12 @@ void shell_draw_clock (ClutterCairoTexture *texture,
|
||||
int hour,
|
||||
int minute);
|
||||
|
||||
void shell_draw_glow (ClutterCairoTexture *texture,
|
||||
double red,
|
||||
double blue,
|
||||
double green,
|
||||
double alpha);
|
||||
void shell_draw_app_highlight (ClutterCairoTexture *texture,
|
||||
int num_windows,
|
||||
double red,
|
||||
double blue,
|
||||
double green,
|
||||
double alpha);
|
||||
|
||||
guint shell_add_hook_paint_red_border (ClutterActor *actor);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <unistd.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <math.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
@ -40,7 +40,6 @@ struct _ShellGlobal {
|
||||
|
||||
MutterPlugin *plugin;
|
||||
ShellWM *wm;
|
||||
gboolean keyboard_grabbed;
|
||||
const char *imagedir;
|
||||
const char *configdir;
|
||||
|
||||
@ -475,66 +474,66 @@ _shell_global_set_plugin (ShellGlobal *global,
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_grab_keyboard:
|
||||
* shell_global_begin_modal:
|
||||
* @global: a #ShellGlobal
|
||||
*
|
||||
* Grab the keyboard to the stage window. The stage will receive
|
||||
* all keyboard events until shell_global_ungrab_keyboard() is called.
|
||||
* This is appropriate to do when the desktop goes into a special
|
||||
* mode where no normal global key shortcuts or application keyboard
|
||||
* processing should happen.
|
||||
* Grabs the keyboard and mouse to the stage window. The stage will
|
||||
* receive all keyboard and mouse events until shell_global_end_modal()
|
||||
* is called. This is used to implement "modes" for the shell, such as the
|
||||
* overview mode or the "looking glass" debug overlay, that block
|
||||
* application and normal key shortcuts.
|
||||
*
|
||||
* Returns value: %TRUE if we succesfully entered the mode. %FALSE if we couldn't
|
||||
* enter the mode. Failure may occur because an application has the pointer
|
||||
* or keyboard grabbed, because Mutter is in a mode itself like moving a
|
||||
* window or alt-Tab window selection, or because shell_global_begin_modal()
|
||||
* was previouly called.
|
||||
*/
|
||||
gboolean
|
||||
shell_global_grab_keyboard (ShellGlobal *global)
|
||||
shell_global_begin_modal (ShellGlobal *global,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaScreen *screen = mutter_plugin_get_screen (global->plugin);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
ClutterStage *stage = CLUTTER_STAGE (mutter_plugin_get_stage (global->plugin));
|
||||
Window stagewin = clutter_x11_get_stage_window (stage);
|
||||
|
||||
/* FIXME: we need to coordinate with the rest of Metacity or we
|
||||
* may grab the keyboard away from other portions of Metacity
|
||||
* and leave Metacity in a confused state. An X client is allowed
|
||||
* to overgrab itself, though not allowed to grab they keyboard
|
||||
* away from another applications.
|
||||
*/
|
||||
if (global->keyboard_grabbed)
|
||||
return FALSE;
|
||||
|
||||
if (XGrabKeyboard (xdisplay, stagewin,
|
||||
False, /* owner_events - steal events from the rest of metacity */
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime) != Success)
|
||||
return FALSE; /* probably AlreadyGrabbed, some other app has a keyboard grab */
|
||||
|
||||
global->keyboard_grabbed = TRUE;
|
||||
|
||||
return TRUE;
|
||||
return mutter_plugin_begin_modal (global->plugin, stagewin, None, 0, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_global_ungrab_keyboard:
|
||||
* shell_global_end_modal:
|
||||
* @global: a #ShellGlobal
|
||||
*
|
||||
* Undoes the effect of shell_global_grab_keyboard
|
||||
* Undoes the effect of shell_global_begin_modal().
|
||||
*/
|
||||
void
|
||||
shell_global_ungrab_keyboard (ShellGlobal *global)
|
||||
shell_global_end_modal (ShellGlobal *global,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaScreen *screen;
|
||||
MetaDisplay *display;
|
||||
Display *xdisplay;
|
||||
mutter_plugin_end_modal (global->plugin, timestamp);
|
||||
}
|
||||
|
||||
g_return_if_fail (global->keyboard_grabbed);
|
||||
/**
|
||||
* shell_global_display_is_grabbed
|
||||
* @global: a #ShellGlobal
|
||||
*
|
||||
* Determines whether Mutter currently has a grab (keyboard or mouse or
|
||||
* both) on the display. This could be the result of a current window
|
||||
* management operation like a window move, or could be from
|
||||
* shell_global_begin_modal().
|
||||
*
|
||||
* This function is useful to for ad-hoc checks to avoid over-grabbing
|
||||
* the Mutter grab a grab from GTK+. Longer-term we might instead want a
|
||||
* mechanism to make Mutter use GDK grabs instead of raw XGrabPointer().
|
||||
*
|
||||
* Return value: %TRUE if Mutter has a grab on the display
|
||||
*/
|
||||
gboolean
|
||||
shell_global_display_is_grabbed (ShellGlobal *global)
|
||||
{
|
||||
MetaScreen *screen = mutter_plugin_get_screen (global->plugin);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
|
||||
screen = mutter_plugin_get_screen (global->plugin);
|
||||
display = meta_screen_get_display (screen);
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
XUngrabKeyboard (xdisplay, CurrentTime);
|
||||
|
||||
global->keyboard_grabbed = FALSE;
|
||||
return meta_display_get_grab_op (display) != META_GRAB_OP_NONE;
|
||||
}
|
||||
|
||||
/* Code to close all file descriptors before we exec; copied from gspawn.c in GLib.
|
||||
|
@ -64,8 +64,12 @@ GList *shell_global_get_windows (ShellGlobal *global);
|
||||
void _shell_global_set_plugin (ShellGlobal *global,
|
||||
MutterPlugin *plugin);
|
||||
|
||||
gboolean shell_global_grab_keyboard (ShellGlobal *global);
|
||||
void shell_global_ungrab_keyboard (ShellGlobal *global);
|
||||
gboolean shell_global_begin_modal (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
void shell_global_end_modal (ShellGlobal *global,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean shell_global_display_is_grabbed (ShellGlobal *global);
|
||||
|
||||
void shell_global_reexec_self (ShellGlobal *global);
|
||||
|
||||
|
@ -1,2 +1,4 @@
|
||||
VOID:INT,INT,INT
|
||||
VOID:OBJECT,INT,INT,INT,INT
|
||||
VOID:BOXED
|
||||
VOID:BOXED,OBJECT
|
||||
|
@ -24,15 +24,25 @@ shell_stack_allocate (ClutterActor *self,
|
||||
ClutterAllocationFlags flags)
|
||||
{
|
||||
GList *children, *iter;
|
||||
float width, height;
|
||||
|
||||
/* chain up to set actor->allocation */
|
||||
width = box->x2 - box->x1;
|
||||
height = box->y2 - box->y1;
|
||||
|
||||
/* Chain up directly to ClutterActor to set actor->allocation. We explicitly skip our parent class
|
||||
* ClutterGroup here because we want to override the allocate function. */
|
||||
(CLUTTER_ACTOR_CLASS (g_type_class_peek (clutter_actor_get_type ())))->allocate (self, box, flags);
|
||||
|
||||
children = clutter_container_get_children (CLUTTER_CONTAINER (self));
|
||||
for (iter = children; iter; iter = iter->next)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (iter->data);
|
||||
clutter_actor_allocate (actor, box, flags);
|
||||
ClutterActorBox child_box;
|
||||
child_box.x1 = 0;
|
||||
child_box.x2 = width;
|
||||
child_box.y1 = 0;
|
||||
child_box.y2 = height;
|
||||
clutter_actor_allocate (actor, &child_box, flags);
|
||||
}
|
||||
g_list_free (children);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@ -660,23 +660,53 @@ position_menu (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user
|
||||
*y = (gint)(0.5 + src_y + height);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_status_menu_toggle:
|
||||
* @menu: a #ShellStatusMenu
|
||||
*
|
||||
* 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
|
||||
* shell_status_menu_is_active().
|
||||
*/
|
||||
void
|
||||
shell_status_menu_toggle (ShellStatusMenu *status, ClutterEvent *event)
|
||||
{
|
||||
ShellStatusMenuPrivate *priv = status->priv;
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu)))
|
||||
if (GTK_WIDGET_VISIBLE (priv->menu))
|
||||
{
|
||||
gtk_widget_hide (GTK_WIDGET (priv->menu));
|
||||
gtk_menu_popdown (GTK_MENU (priv->menu));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_show (GTK_WIDGET (priv->menu));
|
||||
/* We don't want to overgrab a Mutter grab with the grab that GTK+
|
||||
* uses on menus.
|
||||
*/
|
||||
ShellGlobal *global = shell_global_get ();
|
||||
if (shell_global_display_is_grabbed (global))
|
||||
return;
|
||||
|
||||
gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, position_menu,
|
||||
status, 1, event->button.time);
|
||||
status, 1, event->button.time);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_status_menu_is_active:
|
||||
* @menu: a #ShellStatusMenu
|
||||
*
|
||||
* Gets whether the menu is currently popped up
|
||||
*
|
||||
* Return value: %TRUE if the menu is currently popped up
|
||||
*/
|
||||
gboolean
|
||||
shell_status_menu_is_active (ShellStatusMenu *status)
|
||||
{
|
||||
ShellStatusMenuPrivate *priv = status->priv;
|
||||
|
||||
return GTK_WIDGET_VISIBLE (priv->menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_status_menu_get_name:
|
||||
* @menu: a #ShellStatusMenu
|
||||
|
@ -36,7 +36,7 @@ struct _ShellStatusMenuClass
|
||||
GType shell_status_menu_get_type (void);
|
||||
|
||||
void shell_status_menu_toggle (ShellStatusMenu *menu, ClutterEvent *event);
|
||||
|
||||
gboolean shell_status_menu_is_active (ShellStatusMenu *menu);
|
||||
ClutterText *shell_status_menu_get_name (ShellStatusMenu *menu);
|
||||
ClutterTexture *shell_status_menu_get_icon (ShellStatusMenu *menu);
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
#include "shell-texture-cache.h"
|
||||
#include "shell-global.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgnomeui/gnome-thumbnail.h>
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnomeui/gnome-desktop-thumbnail.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct
|
||||
@ -20,7 +21,7 @@ typedef struct
|
||||
struct _ShellTextureCachePrivate
|
||||
{
|
||||
GHashTable *keyed_cache; /* CacheKey -> CoglTexture* */
|
||||
GnomeThumbnailFactory *thumbnails;
|
||||
GnomeDesktopThumbnailFactory *thumbnails;
|
||||
};
|
||||
|
||||
static void shell_texture_cache_dispose (GObject *object);
|
||||
@ -129,7 +130,7 @@ shell_texture_cache_init (ShellTextureCache *self)
|
||||
self->priv = g_new0 (ShellTextureCachePrivate, 1);
|
||||
self->priv->keyed_cache = g_hash_table_new_full (cache_key_hash, cache_key_equal,
|
||||
cache_key_destroy, cogl_handle_unref);
|
||||
self->priv->thumbnails = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL);
|
||||
self->priv->thumbnails = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -209,7 +210,7 @@ compute_pixbuf_scale (gint width,
|
||||
}
|
||||
|
||||
// Scale the image only if that will not increase its original dimensions.
|
||||
if (scaled_width >= 0 && scaled_height >= 0 && scaled_width < width && scaled_height < height)
|
||||
if (scaled_width > 0 && scaled_height > 0 && scaled_width < width && scaled_height < height)
|
||||
{
|
||||
*new_width = scaled_width;
|
||||
*new_height = scaled_height;
|
||||
@ -403,7 +404,7 @@ impl_load_thumbnail (ShellTextureCache *cache,
|
||||
guint size,
|
||||
GError **error)
|
||||
{
|
||||
GnomeThumbnailFactory *thumbnail_factory;
|
||||
GnomeDesktopThumbnailFactory *thumbnail_factory;
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
GFile *file;
|
||||
GFileInfo *file_info;
|
||||
@ -423,24 +424,24 @@ impl_load_thumbnail (ShellTextureCache *cache,
|
||||
|
||||
thumbnail_factory = cache->priv->thumbnails;
|
||||
|
||||
existing_thumbnail = gnome_thumbnail_factory_lookup (thumbnail_factory, uri, mtime);
|
||||
existing_thumbnail = gnome_desktop_thumbnail_factory_lookup (thumbnail_factory, uri, mtime);
|
||||
|
||||
if (existing_thumbnail != NULL)
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_size (existing_thumbnail, size, size, error);
|
||||
else if (gnome_thumbnail_factory_has_valid_failed_thumbnail (thumbnail_factory, uri, mtime))
|
||||
else if (gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (thumbnail_factory, uri, mtime))
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Has failed thumbnail");
|
||||
else if (gnome_thumbnail_factory_can_thumbnail (thumbnail_factory, uri, mime_type, mtime))
|
||||
else if (gnome_desktop_thumbnail_factory_can_thumbnail (thumbnail_factory, uri, mime_type, mtime))
|
||||
{
|
||||
pixbuf = gnome_thumbnail_factory_generate_thumbnail (thumbnail_factory, uri, mime_type);
|
||||
pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumbnail_factory, uri, mime_type);
|
||||
if (pixbuf)
|
||||
{
|
||||
// we need to save the thumbnail so that we don't need to generate it again in the future
|
||||
gnome_thumbnail_factory_save_thumbnail (thumbnail_factory, pixbuf, uri, mtime);
|
||||
gnome_desktop_thumbnail_factory_save_thumbnail (thumbnail_factory, pixbuf, uri, mtime);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to generate thumbnail");
|
||||
gnome_thumbnail_factory_create_failed_thumbnail (thumbnail_factory, uri, mtime);
|
||||
gnome_desktop_thumbnail_factory_create_failed_thumbnail (thumbnail_factory, uri, mtime);
|
||||
}
|
||||
}
|
||||
return pixbuf;
|
||||
@ -769,6 +770,108 @@ out:
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
ShellTextureCache *cache;
|
||||
ClutterTexture *texture;
|
||||
GObject *source;
|
||||
guint notify_signal_id;
|
||||
gboolean weakref_active;
|
||||
} ShellTextureCachePropertyBind;
|
||||
|
||||
static void
|
||||
shell_texture_cache_reset_texture (ShellTextureCachePropertyBind *bind, const char *propname)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
CoglHandle texdata;
|
||||
|
||||
g_object_get (bind->source, propname, &pixbuf, NULL);
|
||||
|
||||
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
if (pixbuf != NULL)
|
||||
{
|
||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
clutter_texture_set_cogl_texture (bind->texture, texdata);
|
||||
cogl_handle_unref (texdata);
|
||||
|
||||
clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 255);
|
||||
}
|
||||
else
|
||||
clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_texture_cache_on_pixbuf_notify (GObject *object,
|
||||
GParamSpec *paramspec,
|
||||
gpointer data)
|
||||
{
|
||||
ShellTextureCachePropertyBind *bind = data;
|
||||
shell_texture_cache_reset_texture (bind, paramspec->name);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_texture_cache_bind_weak_notify (gpointer data,
|
||||
GObject *source_location)
|
||||
{
|
||||
ShellTextureCachePropertyBind *bind = data;
|
||||
bind->weakref_active = FALSE;
|
||||
g_signal_handler_disconnect (bind->source, bind->notify_signal_id);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_texture_cache_free_bind (gpointer data)
|
||||
{
|
||||
ShellTextureCachePropertyBind *bind = data;
|
||||
if (bind->weakref_active)
|
||||
g_object_weak_unref (G_OBJECT(bind->texture), shell_texture_cache_bind_weak_notify, bind);
|
||||
g_free (bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_texture_cache_bind_pixbuf_property:
|
||||
* @cache:
|
||||
* @object: A #GObject with a property @property_name of type #GdkPixbuf
|
||||
* @property_name: Name of a property
|
||||
*
|
||||
* Create a #ClutterTexture which tracks the #GdkPixbuf value of a GObject property
|
||||
* named by @property_name. Unlike other methods in ShellTextureCache, the underlying
|
||||
* CoglHandle is not shared by default with other invocations to this method.
|
||||
*
|
||||
* If the source object is destroyed, the texture will continue to show the last
|
||||
* value of the property.
|
||||
*
|
||||
* Return value: (transfer none): A new #ClutterActor
|
||||
*/
|
||||
ClutterActor *
|
||||
shell_texture_cache_bind_pixbuf_property (ShellTextureCache *cache,
|
||||
GObject *object,
|
||||
const char *property_name)
|
||||
{
|
||||
ClutterTexture *texture;
|
||||
gchar *notify_key;
|
||||
ShellTextureCachePropertyBind *bind;
|
||||
|
||||
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
||||
|
||||
bind = g_new0 (ShellTextureCachePropertyBind, 1);
|
||||
bind->cache = cache;
|
||||
bind->texture = texture;
|
||||
bind->source = object;
|
||||
g_object_weak_ref (G_OBJECT (texture), shell_texture_cache_bind_weak_notify, bind);
|
||||
bind->weakref_active = TRUE;
|
||||
|
||||
shell_texture_cache_reset_texture (bind, property_name);
|
||||
|
||||
notify_key = g_strdup_printf ("notify::%s", property_name);
|
||||
bind->notify_signal_id = g_signal_connect_data (object, notify_key, G_CALLBACK(shell_texture_cache_on_pixbuf_notify),
|
||||
bind, (GClosureNotify)shell_texture_cache_free_bind, 0);
|
||||
g_free (notify_key);
|
||||
|
||||
return CLUTTER_ACTOR(texture);
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_texture_cache_load_gicon:
|
||||
*
|
||||
@ -1093,47 +1196,44 @@ shell_texture_cache_load_recent_thumbnail (ShellTextureCache *cache,
|
||||
/**
|
||||
* shell_texture_cache_evict_thumbnail:
|
||||
* @cache:
|
||||
* @size: Size in pixels
|
||||
* @uri: Source URI
|
||||
*
|
||||
* Removes the reference the shell_texture_cache_load_thumbnail() function
|
||||
* created for a thumbnail.
|
||||
* Removes all references added by shell_texture_cache_load_thumbnail() function
|
||||
* created for the given URI.
|
||||
*/
|
||||
void
|
||||
shell_texture_cache_evict_thumbnail (ShellTextureCache *cache,
|
||||
int size,
|
||||
const char *uri)
|
||||
{
|
||||
CacheKey key;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
memset (&key, 0, sizeof(key));
|
||||
key.size = size;
|
||||
key.thumbnail_uri = (char*)uri;
|
||||
g_hash_table_iter_init (&iter, cache->priv->keyed_cache);
|
||||
|
||||
g_hash_table_remove (cache->priv->keyed_cache, &key);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
CacheKey *cachekey = key;
|
||||
|
||||
if (cachekey->thumbnail_uri == NULL || strcmp (cachekey->thumbnail_uri, uri) != 0)
|
||||
continue;
|
||||
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_texture_cache_evict_recent_thumbnail:
|
||||
* @cache:
|
||||
* @size: Size in pixels
|
||||
* @info: A recent info
|
||||
*
|
||||
* Removes the reference the shell_texture_cache_load_recent_thumbnail() function
|
||||
* created for a thumbnail.
|
||||
* Removes all references added by shell_texture_cache_load_recent_thumbnail() function
|
||||
* for the URI associated with the given @info.
|
||||
*/
|
||||
void
|
||||
shell_texture_cache_evict_recent_thumbnail (ShellTextureCache *cache,
|
||||
int size,
|
||||
GtkRecentInfo *info)
|
||||
{
|
||||
CacheKey key;
|
||||
|
||||
memset (&key, 0, sizeof(key));
|
||||
key.size = size;
|
||||
key.thumbnail_uri = (char*)gtk_recent_info_get_uri (info);
|
||||
|
||||
g_hash_table_remove (cache->priv->keyed_cache, &key);
|
||||
shell_texture_cache_evict_thumbnail (cache, gtk_recent_info_get_uri (info));
|
||||
}
|
||||
|
||||
static ShellTextureCache *instance = NULL;
|
||||
|
@ -40,6 +40,10 @@ GType shell_texture_cache_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ShellTextureCache* shell_texture_cache_get_default (void);
|
||||
|
||||
ClutterActor *shell_texture_cache_bind_pixbuf_property (ShellTextureCache *cache,
|
||||
GObject *object,
|
||||
const char *property_name);
|
||||
|
||||
ClutterActor *shell_texture_cache_load_icon_name (ShellTextureCache *cache,
|
||||
const char *name,
|
||||
gint size);
|
||||
@ -58,11 +62,9 @@ ClutterActor *shell_texture_cache_load_recent_thumbnail (ShellTextureCache *cach
|
||||
GtkRecentInfo *info);
|
||||
|
||||
void shell_texture_cache_evict_thumbnail (ShellTextureCache *cache,
|
||||
int size,
|
||||
const char *uri);
|
||||
|
||||
void shell_texture_cache_evict_recent_thumbnail (ShellTextureCache *cache,
|
||||
int size,
|
||||
GtkRecentInfo *info);
|
||||
|
||||
ClutterActor *shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#include "tidy-enum-types.h"
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@filename@" */
|
||||
#include "@filename@"
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType
|
||||
@enum_name@_get_type(void) {
|
||||
static GType enum_type_id = 0;
|
||||
if (G_UNLIKELY (!enum_type_id))
|
||||
{
|
||||
static const G@Type@Value values[] = {
|
||||
/*** END value-header ***/
|
||||
|
||||
/*** BEGIN value-production ***/
|
||||
{ @VALUENAME@, "@VALUENAME@", "@valuenick@" },
|
||||
/*** END value-production ***/
|
||||
|
||||
/*** BEGIN value-tail ***/
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
enum_type_id = g_@type@_register_static("@EnumName@", values);
|
||||
}
|
||||
return enum_type_id;
|
||||
}
|
||||
/*** END value-tail ***/
|
@ -1,25 +0,0 @@
|
||||
/*** BEGIN file-header ***/
|
||||
#ifndef __TIDY_ENUM_TYPES_H__
|
||||
#define __TIDY_ENUM_TYPES_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*** END file-header ***/
|
||||
|
||||
/*** BEGIN file-production ***/
|
||||
/* enumerations from "@filename@" */
|
||||
/*** END file-production ***/
|
||||
|
||||
/*** BEGIN file-tail ***/
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* !__TIDY_ENUM_TYPES_H__ */
|
||||
/*** END file-tail ***/
|
||||
|
||||
/*** BEGIN value-header ***/
|
||||
GType @enum_name@_get_type (void) G_GNUC_CONST;
|
||||
#define TIDY_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
|
||||
|
||||
/*** END value-header ***/
|
1044
src/tidy/tidy-grid.c
1044
src/tidy/tidy-grid.c
File diff suppressed because it is too large
Load Diff
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Authored By Matthew Allum <mallum@openedhand.com>
|
||||
*
|
||||
* Copyright (C) 2008 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TIDY_GRID_H__
|
||||
#define __TIDY_GRID_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TIDY_TYPE_GRID (tidy_grid_get_type())
|
||||
#define TIDY_GRID(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGrid))
|
||||
#define TIDY_GRID_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGridClass))
|
||||
#define TIDY_IS_GRID(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TIDY_TYPE_GRID))
|
||||
#define TIDY_IS_GRID_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TIDY_TYPE_GRID))
|
||||
#define TIDY_GRID_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TIDY_TYPE_GRID, \
|
||||
TidyGridClass))
|
||||
|
||||
typedef struct _TidyGrid TidyGrid;
|
||||
typedef struct _TidyGridClass TidyGridClass;
|
||||
typedef struct _TidyGridPrivate TidyGridPrivate;
|
||||
|
||||
struct _TidyGridClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
struct _TidyGrid
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
TidyGridPrivate *priv;
|
||||
};
|
||||
|
||||
GType tidy_grid_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *tidy_grid_new (void);
|
||||
void tidy_grid_set_end_align (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_end_align (TidyGrid *self);
|
||||
void tidy_grid_set_homogenous_rows (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_homogenous_rows (TidyGrid *self);
|
||||
void tidy_grid_set_homogenous_columns (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_homogenous_columns (TidyGrid *self);
|
||||
void tidy_grid_set_column_major (TidyGrid *self,
|
||||
gboolean value);
|
||||
gboolean tidy_grid_get_column_major (TidyGrid *self);
|
||||
void tidy_grid_set_row_gap (TidyGrid *self,
|
||||
gfloat value);
|
||||
gfloat tidy_grid_get_row_gap (TidyGrid *self);
|
||||
void tidy_grid_set_column_gap (TidyGrid *self,
|
||||
gfloat value);
|
||||
gfloat tidy_grid_get_column_gap (TidyGrid *self);
|
||||
void tidy_grid_set_valign (TidyGrid *self,
|
||||
gdouble value);
|
||||
gdouble tidy_grid_get_valign (TidyGrid *self);
|
||||
void tidy_grid_set_halign (TidyGrid *self,
|
||||
gdouble value);
|
||||
gdouble tidy_grid_get_halign (TidyGrid *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __TIDY_GRID_H__ */
|
@ -1,8 +0,0 @@
|
||||
VOID:OBJECT
|
||||
VOID:VOID
|
||||
VOID:PARAM
|
||||
VOID:POINTER
|
||||
VOID:UINT
|
||||
VOID:UINT,UINT
|
||||
VOID:OBJECT,OBJECT
|
||||
VOID:STRING,OBJECT
|
@ -10,6 +10,23 @@
|
||||
# Copyright (C) 2006, 2007, 2008 Imendio AB
|
||||
#
|
||||
|
||||
# Pre-check on GNOME version
|
||||
|
||||
gnome_version=`gnome-session --version 2>/dev/null | (read name version && echo $version)`
|
||||
have_gnome_26=false
|
||||
case $gnome_version in
|
||||
2.2[6789]*|2.[3456789]*|3.*)
|
||||
have_gnome_26=true
|
||||
;;
|
||||
esac
|
||||
|
||||
if $have_gnome_26 ; then : ; else
|
||||
echo "GNOME 2.26 or newer is required to build GNOME Shell" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
############################################################
|
||||
|
||||
if which lsb_release > /dev/null 2>&1; then
|
||||
system=`lsb_release -is`
|
||||
elif [ -f /etc/fedora-release ] ; then
|
||||
@ -35,7 +52,7 @@ fi
|
||||
# ({mozilla,firefox,xulrunner}-js), xdamage
|
||||
#
|
||||
# Non-devel packages needed by gnome-shell and its deps:
|
||||
# gdb, glxinfo, gstreamer-plugins-base, gstreamer-plugins-good,
|
||||
# glxinfo, gstreamer-plugins-base, gstreamer-plugins-good,
|
||||
# python, Xephyr, xeyes*, xlogo*, xterm*, zenity
|
||||
#
|
||||
# (*)ed packages are only needed because gnome-shell launches them
|
||||
@ -62,7 +79,7 @@ if test x$system = xUbuntu -o x$system = xDebian ; then
|
||||
build-essential curl \
|
||||
automake bison flex git-core gnome-common gtk-doc-tools \
|
||||
libdbus-glib-1-dev libgconf2-dev libgtk2.0-dev libffi-dev \
|
||||
libgnome-menu-dev libgnomeui-dev librsvg2-dev libwnck-dev libgl1-mesa-dev \
|
||||
libgnome-menu-dev libgnome-desktop-dev librsvg2-dev libwnck-dev libgl1-mesa-dev \
|
||||
mesa-common-dev mesa-utils python-dev libreadline5-dev xulrunner-dev \
|
||||
xserver-xephyr \
|
||||
libgstreamer0.10-dev gstreamer0.10-plugins-base gstreamer0.10-plugins-good \
|
||||
@ -84,11 +101,11 @@ if test x$system = xFedora ; then
|
||||
binutils curl gcc make \
|
||||
automake bison flex git gnome-common gnome-doc-utils intltool \
|
||||
libtool pkgconfig \
|
||||
dbus-glib-devel GConf2-devel gnome-menus-devel gtk2-devel libffi-devel libgnomeui-devel \
|
||||
dbus-glib-devel GConf2-devel gnome-menus-devel gtk2-devel libffi-devel gnome-desktop-devel \
|
||||
librsvg2-devel libwnck-devel mesa-libGL-devel python-devel readline-devel \
|
||||
xulrunner-devel libXdamage-devel \
|
||||
gstreamer-devel gstreamer-plugins-base gstreamer-plugins-good \
|
||||
gdb glx-utils xorg-x11-apps xorg-x11-server-Xephyr xterm zenity \
|
||||
glx-utils xorg-x11-apps xorg-x11-server-Xephyr xterm zenity \
|
||||
; do
|
||||
if ! rpm -q $pkg > /dev/null 2>&1; then
|
||||
reqd="$pkg $reqd"
|
||||
@ -104,7 +121,7 @@ if test x$system = xSUSE ; then
|
||||
for pkg in \
|
||||
curl \
|
||||
bison flex gnome-doc-utils-devel \
|
||||
gconf2-devel libffi-devel libgnomeui-devel librsvg-devel libwnck-devel \
|
||||
gconf2-devel libffi-devel gnome-desktop-devel librsvg-devel libwnck-devel \
|
||||
xorg-x11-proto-devel readline-devel mozilla-xulrunner190-devel \
|
||||
xorg-x11-devel xterm xorg-x11 xorg-x11-server-extra \
|
||||
; do
|
||||
|
Reference in New Issue
Block a user