Fix merge conflicts

This commit is contained in:
David Zeuthen 2010-12-20 11:55:36 -05:00
commit 137ea12109
30 changed files with 1710 additions and 661 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ data/org.gnome.shell.gschema.xml
data/org.gnome.shell.gschema.valid
data/org.gnome.accessibility.magnifier.gschema.xml
data/org.gnome.accessibility.magnifier.gschema.valid
js/misc/config.js
intltool-extract.in
intltool-merge.in
intltool-update.in

View File

@ -94,9 +94,21 @@ PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 gnome-desktop-3.0 >= 2.9
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(JS_TEST, clutter-x11-1.0 gjs-1.0 gobject-introspection-1.0 gtk+-3.0)
AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 2.90.0],
[BLUETOOTH_DIR=`$PKG_CONFIG --variable=libdir gnome-bluetooth-1.0`/gnome-bluetooth
BLUETOOTH_LIBS="-L'$BLUETOOTH_DIR' -lgnome-bluetooth-applet"
AC_SUBST([BLUETOOTH_LIBS],["$BLUETOOTH_LIBS"])
AC_DEFINE_UNQUOTED([BLUETOOTH_DIR],["$BLUETOOTH_DIR"],[Path to installed GnomeBluetooth typelib and library])
AC_DEFINE([HAVE_BLUETOOTH],[1],[Define if you have libgnome-bluetooth-applet])
AC_SUBST([HAVE_BLUETOOTH],[1])
AC_MSG_RESULT([yes])],
[AC_DEFINE([HAVE_BLUETOOTH],[0])
AC_SUBST([HAVE_BLUETOOTH],[0])
AC_MSG_RESULT([no])])
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
# FIXME: metacity-plugins.pc should point directly to its .gir file
MUTTER_LIB_DIR=`$PKG_CONFIG --variable=libdir mutter-plugins`
@ -167,6 +179,7 @@ AC_CONFIG_FILES([
Makefile
data/Makefile
js/Makefile
js/misc/config.js
src/Makefile
tests/Makefile
po/Makefile.in

View File

@ -27,6 +27,7 @@ dist_theme_DATA = \
theme/corner-ripple.png \
theme/dash-placeholder.svg \
theme/dialog-error.svg \
theme/filter-selected.svg \
theme/gnome-shell.css \
theme/mosaic-view-active.svg \
theme/mosaic-view.svg \

View File

@ -1,12 +1,30 @@
<Menu>
<DefaultLayout>
<Menuname>Apps</Menuname>
<Menuname>Accessories</Menuname>
<Menuname>Games</Menuname>
<Menuname>Tools</Menuname>
<Menuname>Graphics</Menuname>
<Menuname>Internet</Menuname>
<Menuname>Multimedia</Menuname>
<Menuname>Office</Menuname>
<Menuname>Other</Menuname>
</DefaultLayout>
<Name>Applications</Name>
<AppDir>/usr/local/share/applications</AppDir>
<DefaultAppDirs/>
<Menu>
<Name>Accessories</Name>
<Include>
<And>
<Category>Utility</Category>
<Not>
<Category>System</Category>
</Not>
</And>
</Include>
</Menu>
<Menu>
<Name>Games</Name>
<Include>
@ -15,21 +33,47 @@
</And>
</Include>
</Menu>
<Menu>
<Name>Tools</Name>
<Name>Graphics</Name>
<Include>
<Category>Development</Category>
<And>
<Category>System</Category>
<Not>
<Category>Settings</Category>
</Not>
<Category>Graphics</Category>
</And>
<Category>Utility</Category>
</Include>
</Menu>
<Menu>
<Name>Apps</Name>
<Name>Internet</Name>
<Include>
<And>
<Category>Network</Category>
<Not><Category>Settings</Category></Not>
</And>
</Include>
</Menu>
<Menu>
<Name>Multimedia</Name>
<Include>
<And>
<Category>AudioVideo</Category>
<Not><Category>Settings</Category></Not>
</And>
</Include>
</Menu>
<Menu>
<Name>Office</Name>
<Include>
<And>
<Category>Office</Category>
</And>
</Include>
</Menu>
<Menu>
<Name>Other</Name>
<OnlyUnallocated/>
<Include>
<And>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
width="10"
height="20"
id="svg10003"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="filter-selected.svg">
<defs
id="defs10005">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective10011" />
<inkscape:perspective
id="perspective9998"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="32"
inkscape:cy="10.181818"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1680"
inkscape:window-height="994"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
<metadata
id="metadata10008">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(0,-44)">
<path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/app-picker.png"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="rect34320"
d="m -0.18726572,54.181804 10.55634072,10.55636 10e-6,-21.11269 z"
style="opacity:0.21000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -105,6 +105,10 @@ StTooltip StLabel {
min-width: 200px;
}
.popup-sub-menu {
background-color: #606060;
}
/* The remaining popup-menu sizing is all done in ems, so that if you
* override .popup-menu.font-size, everything else will scale with it.
*/
@ -470,26 +474,28 @@ StTooltip StLabel {
/* Apps */
.overview-pane {
width: 440px;
}
.icon-grid {
spacing: 36px;
-shell-grid-item-size: 70px;
}
.all-app {
padding: 16px 250px 10px 16px;
padding: 16px 25px 16px 16px;
spacing: 20px;
}
.app-section-divider-container {
padding-top: 36px;
padding-bottom: 36px;
.app-filter {
font-size: 14px;
font-weight: bold;
height: 40px;
color: #aaa;
width: 200px;
}
.app-section-divider {
height: 2px;
.app-filter:selected {
color: #ffffff;
background-image: url("filter-selected.svg");
background-position: 190px 10px;
}
#dash > .app-well-app {
@ -1032,7 +1038,7 @@ StTooltip StLabel {
color: #bbbbbb;
}
.chat-response {
#notification StEntry {
padding: 4px;
border-radius: 4px;
border: 1px solid #565656;
@ -1042,7 +1048,7 @@ StTooltip StLabel {
caret-size: 1px;
}
.chat-response:focus {
#notification StEntry:focus {
border: 1px solid #3a3a3a;
color: #545454;
background-color: #e8e8e8;

View File

@ -2,6 +2,7 @@
jsdir = $(pkgdatadir)/js
nobase_dist_js_DATA = \
misc/config.js \
misc/docInfo.js \
misc/fileUtils.js \
misc/format.js \
@ -48,6 +49,7 @@ nobase_dist_js_DATA = \
ui/status/accessibility.js \
ui/status/power.js \
ui/status/volume.js \
ui/status/bluetooth.js \
ui/telepathyClient.js \
ui/tweener.js \
ui/viewSelector.js \

3
js/misc/config.js.in Normal file
View File

@ -0,0 +1,3 @@
/* mode: js2; indent-tabs-mode: nil; tab-size: 4 */
const HAVE_BLUETOOTH = @HAVE_BLUETOOTH@;

View File

@ -29,10 +29,20 @@ function AlphabeticalView() {
AlphabeticalView.prototype = {
_init: function() {
this.actor = new St.BoxLayout({ vertical: true });
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.START });
this._appSystem = Shell.AppSystem.get_default();
this.actor.add(this._grid.actor, { y_align: St.Align.START, expand: true });
this._filterApp = null;
let box = new St.BoxLayout({ vertical: true });
box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
this.actor = new St.ScrollView({ x_fill: true,
y_fill: false,
y_align: St.Align.START,
vshadows: true });
this.actor.add_actor(box);
this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
},
_removeAll: function() {
@ -40,20 +50,24 @@ AlphabeticalView.prototype = {
this._apps = [];
},
_addApp: function(app) {
let appIcon = new AppWellIcon(this._appSystem.get_app(app.get_id()));
appIcon.connect('launching', Lang.bind(this, function() {
this.emit('launching');
}));
appIcon._draggable.connect('drag-begin', Lang.bind(this, function() {
this.emit('drag-begin');
}));
_addApp: function(appInfo) {
let appIcon = new AppWellIcon(this._appSystem.get_app(appInfo.get_id()));
this._grid.addItem(appIcon.actor);
appIcon._appInfo = appInfo;
if (this._filterApp && !this._filterApp(appInfo))
appIcon.actor.hide();
this._apps.push(appIcon);
},
setFilter: function(filter) {
this._filterApp = filter;
for (let i = 0; i < this._apps.length; i++)
this._apps[i].actor.visible = filter(this._apps[i]._appInfo);
},
refresh: function(apps) {
let ids = [];
for (let i in apps)
@ -70,8 +84,6 @@ AlphabeticalView.prototype = {
}
};
Signals.addSignalMethods(AlphabeticalView.prototype);
function ViewByCategories() {
this._init();
}
@ -79,59 +91,78 @@ function ViewByCategories() {
ViewByCategories.prototype = {
_init: function() {
this._appSystem = Shell.AppSystem.get_default();
this.actor = new St.BoxLayout({ vertical: true });
this.actor = new St.BoxLayout({ style_class: 'all-app' });
this.actor._delegate = this;
this._view = new AlphabeticalView();
this._filters = new St.BoxLayout({ vertical: true });
this.actor.add(this._view.actor, { expand: true, x_fill: true, y_fill: true });
this.actor.add(this._filters, { expand: false, y_fill: false, y_align: St.Align.START });
this._sections = [];
},
_updateSections: function(apps) {
this._removeAll();
_selectCategory: function(num) {
if (num != -1)
this._allFilter.remove_style_pseudo_class('selected');
else
this._allFilter.add_style_pseudo_class('selected');
let sections = this._appSystem.get_sections();
if (!sections)
return;
for (let i = 0; i < sections.length; i++) {
if (i) {
let actor = new St.Bin({ style_class: 'app-section-divider' });
let divider = new St.Bin({ style_class: 'app-section-divider-container',
child: actor,
x_fill: true });
this._view.setFilter(Lang.bind(this, function(app) {
if (num == -1)
return true;
return this._sections[num].name == app.get_section();
}));
this.actor.add(divider, { y_fill: false, expand: true });
for (let i = 0; i < this._sections.length; i++) {
if (i == num)
this._sections[i].filterActor.add_style_pseudo_class('selected');
else
this._sections[i].filterActor.remove_style_pseudo_class('selected');
}
let _apps = apps.filter(function(app) {
return app.get_section() == sections[i];
});
this._sections[i] = { view: new AlphabeticalView(),
apps: _apps,
name: sections[i] };
this._sections[i].view.connect('launching', Lang.bind(this, function() {
this.emit('launching');
},
_addFilter: function(name, num) {
let button = new St.Button({ label: name,
style_class: 'app-filter',
x_align: St.Align.START });
this._filters.add(button, { expand: true, x_fill: true, y_fill: false });
button.connect('clicked', Lang.bind(this, function() {
this._selectCategory(num);
}));
this._sections[i].view.connect('drag-begin', Lang.bind(this, function() {
this.emit('drag-begin');
}));
this.actor.add(this._sections[i].view.actor, { y_align: St.Align.START, expand: true });
}
if (num != -1)
this._sections[num] = { filterActor: button,
name: name };
else
this._allFilter = button;
},
_removeAll: function() {
this.actor.destroy_children();
this._sections.forEach(function (section) { section.view.disconnectAll(); });
this._sections = [];
this._filters.destroy_children();
},
refresh: function(apps) {
this._updateSections(apps);
for (let i = 0; i < this._sections.length; i++) {
this._sections[i].view.refresh(this._sections[i].apps);
}
this._removeAll();
let sections = this._appSystem.get_sections();
this._apps = apps;
this._view.refresh(apps);
this._addFilter(_("All"), -1);
if (!sections)
return;
for (let i = 0; i < sections.length; i++)
this._addFilter(sections[i], i);
this._selectCategory(-1);
}
};
Signals.addSignalMethods(ViewByCategories.prototype);
/* This class represents a display containing a collection of application items.
* The applications are sorted based on their name.
*/
@ -146,17 +177,8 @@ AllAppDisplay.prototype = {
Main.queueDeferredWork(this._workId);
}));
this._scrollView = new St.ScrollView({ x_fill: true,
y_fill: false,
vshadows: true });
this.actor = new St.Bin({ style_class: 'all-app',
y_align: St.Align.START,
child: this._scrollView });
this._appView = new ViewByCategories();
this._scrollView.add_actor(this._appView.actor);
this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
this.actor = new St.Bin({ child: this._appView.actor, x_fill: true, y_fill: true });
this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
},
@ -169,8 +191,6 @@ AllAppDisplay.prototype = {
this._appView.refresh(apps);
}
};
Signals.addSignalMethods(AllAppDisplay.prototype);
function BaseAppSearchProvider() {
this._init();

View File

@ -165,8 +165,16 @@ IconGrid.prototype = {
alloc.natural_size = nColumns * this._item_size + totalSpacing;
},
_getPreferredHeight: function (grid, forWidth, alloc) {
_getVisibleChildren: function() {
let children = this._grid.get_children();
children = children.filter(function(actor) {
return actor.visible;
});
return children;
},
_getPreferredHeight: function (grid, forWidth, alloc) {
let children = this._getVisibleChildren();
let [nColumns, usedWidth] = this._computeLayout(forWidth);
let nRows;
if (nColumns > 0)
@ -182,7 +190,7 @@ IconGrid.prototype = {
},
_allocate: function (grid, box, flags) {
let children = this._grid.get_children();
let children = this._getVisibleChildren();
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;

View File

@ -135,6 +135,7 @@ function start() {
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
telepathyClient = new TelepathyClient.Client();
panel.startStatusArea();
_startDate = new Date();

View File

@ -226,6 +226,9 @@ Notification.prototype = {
_init: function(source, title, banner, params) {
this.source = source;
this.urgent = false;
this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false;
this.expanded = false;
this._useActionIcons = false;
this._customContent = false;
@ -257,7 +260,7 @@ Notification.prototype = {
function (actor, event) {
if (!this._actionArea ||
!this._actionArea.contains(event.get_source()))
this.emit('clicked');
this._onClicked();
}));
// The first line should have the title, followed by the
@ -484,7 +487,7 @@ Notification.prototype = {
}
this._buttonBox.add(button);
button.connect('clicked', Lang.bind(this, function() { this.emit('action-invoked', id); }));
button.connect('clicked', Lang.bind(this, this._onActionInvoked, id));
this._updated();
},
@ -492,6 +495,14 @@ Notification.prototype = {
this.urgent = urgent;
},
setResident: function(resident) {
this.resident = resident;
},
setTransient: function(isTransient) {
this.isTransient = isTransient;
},
setUseActionIcons: function(useIcons) {
this._useActionIcons = useIcons;
},
@ -696,6 +707,28 @@ Notification.prototype = {
return false;
},
_onActionInvoked: function(actor, id) {
this.emit('action-invoked', id);
if (!this.resident) {
// We don't hide a resident notification when the user invokes one of its actions,
// because it is common for such notifications to update themselves with new
// information based on the action. We'd like to display the updated information
// in place, rather than pop-up a new notification.
this.emit('done-displaying');
this.destroy();
}
},
_onClicked: function() {
this.emit('clicked');
// We hide all types of notifications once the user clicks on them because the common
// outcome of clicking should be the relevant window being brought forward and the user's
// attention switching to the window.
this.emit('done-displaying');
if (!this.resident)
this.destroy();
},
_onKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.Escape) {
@ -781,6 +814,11 @@ Source.prototype = {
this.title = title;
this._iconBin = new St.Bin({ width: this.ICON_SIZE,
height: this.ICON_SIZE });
this.isTransient = false;
},
setTransient: function(isTransient) {
this.isTransient = isTransient;
},
// Called to create a new icon actor (of size this.ICON_SIZE).
@ -811,6 +849,7 @@ Source.prototype = {
this.notification = null;
this._notificationDestroyedId = 0;
this._notificationClickedId = 0;
this._notificationRemoved();
}
}));
@ -830,8 +869,13 @@ Source.prototype = {
this._iconBin.child = icon;
},
// Default implementation is to do nothing, but subclass can override
// Default implementation is to do nothing, but subclasses can override
_notificationClicked: function(notification) {
},
// Default implementation is to destroy this source, but subclasses can override
_notificationRemoved: function() {
this.destroy();
}
};
Signals.addSignalMethods(Source.prototype);
@ -905,6 +949,7 @@ MessageTray.prototype = {
this._notificationBin.hide();
this._notificationQueue = [];
this._notification = null;
this._notificationClickedId = 0;
this._summaryBin = new St.Bin({ anchor_gravity: Clutter.Gravity.NORTH_EAST });
this.actor.add_actor(this._summaryBin);
@ -926,6 +971,7 @@ MessageTray.prototype = {
this._summaryNotificationBoxPointer.actor.hide();
this._summaryNotification = null;
this._summaryNotificationClickedId = 0;
this._clickedSummaryItem = null;
this._clickedSummaryItemAllocationChangedId = 0;
this._expandedSummaryItem = null;
@ -1033,6 +1079,14 @@ MessageTray.prototype = {
}
this._summaryItems.push(summaryItem);
// We keep this._newSummaryItems to track any new sources that were added to the
// summary and show the summary with them to the user for a short period of time
// after notifications are done showing. However, we don't want that to happen for
// transient sources, which are removed after the notification is shown, but are
// not removed fast enough because of the callbacks to avoid the summary popping up.
// So we just don't add transient sources to this._newSummaryItems .
if (!source.isTransient)
this._newSummaryItems.push(summaryItem);
source.connect('notify', Lang.bind(this, this._onNotify));
@ -1465,6 +1519,8 @@ MessageTray.prototype = {
_showNotification: function() {
this._notification = this._notificationQueue.shift();
this._notificationClickedId = this._notification.connect('done-displaying',
Lang.bind(this, this.escapeTray));
this._notificationBin.child = this._notification.actor;
this._notificationBin.opacity = 0;
@ -1562,7 +1618,12 @@ MessageTray.prototype = {
this._notificationBin.hide();
this._notificationBin.child = null;
this._notification.collapseCompleted();
this._notification.disconnect(this._notificationClickedId);
this._notificationClickedId = 0;
let notification = this._notification;
this._notification = null;
if (notification.isTransient)
notification.destroy();
},
_expandNotification: function(autoExpanding) {
@ -1636,7 +1697,8 @@ MessageTray.prototype = {
_showSummaryNotification: function() {
this._summaryNotification = this._clickedSummaryItem.source.notification;
this._summaryNotificationClickedId = this._summaryNotification.connect('done-displaying',
Lang.bind(this, this.escapeTray));
let index = this._notificationQueue.indexOf(this._summaryNotification);
if (index != -1)
this._notificationQueue.splice(index, 1);
@ -1706,8 +1768,12 @@ MessageTray.prototype = {
this._summaryNotificationState = State.HIDDEN;
this._summaryNotificationBoxPointer.bin.child = null;
this._summaryNotification.collapseCompleted();
this._summaryNotification.disconnect(this._summaryNotificationClickedId);
this._summaryNotificationClickedId = 0;
let summaryNotification = this._summaryNotification;
this._summaryNotification = null;
if (summaryNotification.isTransient && !this._reNotifyWithSummaryNotificationAfterHide)
summaryNotification.destroy();
if (this._reNotifyWithSummaryNotificationAfterHide) {
this._onNotify(summaryNotification.source, summaryNotification);
this._reNotifyWithSummaryNotificationAfterHide = false;

View File

@ -175,14 +175,43 @@ NotificationDaemon.prototype = {
}
},
_newSource: function(title, pid) {
let source = new Source(title, pid);
this._sources[pid] = source;
// Returns the source associated with ndata.notification if it is set.
// Otherwise, returns the source associated with the pid if one is
// stored in this._sources and the notification is not transient.
// Otherwise, creates a new source as long as pid is provided.
//
// Either a pid or ndata.notification is needed to retrieve or
// create a source.
_getSource: function(title, pid, ndata) {
if (!pid && !(ndata && ndata.notification))
return null;
// We use notification's source for the notifications we still have
// around that are getting replaced because we don't keep sources
// for transient notifications in this._sources, but we still want
// the notification associated with them to get replaced correctly.
if (ndata && ndata.notification)
return ndata.notification.source;
let isForTransientNotification = (ndata && ndata.hints['transient'] == true);
// We don't want to override a persistent notification
// with a transient one from the same sender, so we
// always create a new source object for new transient notifications
// and never add it to this._sources .
if (!isForTransientNotification && this._sources[pid])
return this._sources[pid];
let source = new Source(title, pid);
source.setTransient(isForTransientNotification);
if (!isForTransientNotification) {
this._sources[pid] = source;
source.connect('destroy', Lang.bind(this,
function() {
delete this._sources[pid];
}));
}
Main.messageTray.add(source);
return source;
@ -234,7 +263,8 @@ NotificationDaemon.prototype = {
let sender = DBus.getCurrentMessageContext().sender;
let pid = this._senderToPid[sender];
let source = pid ? this._sources[pid] : null;
let source = this._getSource(appName, pid, ndata);
if (source) {
this._notifyForSource(source, ndata);
@ -255,16 +285,23 @@ NotificationDaemon.prototype = {
if (!ndata)
return;
this._senderToPid[sender] = pid;
source = this._sources[pid];
source = this._getSource(appName, pid, ndata);
if (!source)
source = this._newSource(appName, pid);
// We only store sender-pid entries for persistent sources.
// Removing the entries once the source is destroyed
// would result in the entries associated with transient
// sources removed once the notification is shown anyway.
// However, keeping these pairs would mean that we would
// possibly remove an entry associated with a persistent
// source when a transient source for the same sender is
// distroyed.
if (!source.isTransient) {
this._senderToPid[sender] = pid;
source.connect('destroy', Lang.bind(this,
function() {
delete this._senderToPid[sender];
}));
}
this._notifyForSource(source, ndata);
}));
@ -291,7 +328,10 @@ NotificationDaemon.prototype = {
function(n) {
delete this._notifications[id];
}));
notification.connect('action-invoked', Lang.bind(this, this._actionInvoked, source, id));
notification.connect('action-invoked', Lang.bind(this,
function(n, actionId) {
this._emitActionInvoked(id, actionId);
}));
} else {
notification.update(summary, body, { icon: iconActor,
bannerMarkup: true,
@ -305,6 +345,10 @@ NotificationDaemon.prototype = {
}
notification.setUrgent(hints.urgency == Urgency.CRITICAL);
notification.setResident(hints.resident == true);
// 'transient' is a reserved keyword in JS, so we have to retrieve the value
// of the 'transient' hint with hints['transient'] rather than hints.transient
notification.setTransient(hints['transient'] == true);
let sourceIconActor = source.useNotificationIcon ? this._iconForNotificationData(icon, hints, source.ICON_SIZE) : null;
source.notify(notification, sourceIconActor);
@ -352,17 +396,13 @@ NotificationDaemon.prototype = {
for (let id in this._sources) {
let source = this._sources[id];
if (source.app == tracker.focus_app) {
source.activated();
if (source.notification && !source.notification.resident)
source.notification.destroy();
return;
}
}
},
_actionInvoked: function(notification, action, source, id) {
source.activated();
this._emitActionInvoked(id, action);
},
_emitNotificationClosed: function(id, reason) {
DBus.session.emit_signal('/org/freedesktop/Notifications',
'org.freedesktop.Notifications',
@ -378,9 +418,7 @@ NotificationDaemon.prototype = {
},
_onTrayIconAdded: function(o, icon) {
let source = this._sources[icon.pid];
if (!source)
source = this._newSource(icon.title || icon.wm_class || _("Unknown"), icon.pid);
let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null);
source.setTrayIcon(icon);
},
@ -421,6 +459,9 @@ Source.prototype = {
},
_setApp: function() {
if (this.app)
return;
this.app = Shell.WindowTracker.get_default().get_app_from_pid(this._pid);
if (!this.app)
return;
@ -440,12 +481,10 @@ Source.prototype = {
},
_notificationClicked: function(notification) {
notification.destroy();
this.openApp();
this.activated();
},
activated: function() {
_notificationRemoved: function() {
if (!this._isTrayIcon)
this.destroy();
},

View File

@ -28,7 +28,6 @@ const ANIMATION_TIME = 0.25;
// We split the screen vertically between the dash and the view selector.
const DASH_SPLIT_FRACTION = 0.1;
const SHELL_INFO_HIDE_TIMEOUT = 10;
function Source() {
this._init();
@ -61,14 +60,10 @@ function ShellInfo() {
ShellInfo.prototype = {
_init: function() {
this._source = null;
this._timeoutId = 0;
this._undoCallback = null;
},
_onUndoClicked: function() {
Mainloop.source_remove(this._timeoutId);
this._timeoutId = 0;
if (this._undoCallback)
this._undoCallback();
this._undoCallback = null;
@ -77,20 +72,7 @@ ShellInfo.prototype = {
this._source.destroy();
},
_onTimeout: function() {
this._timeoutId = 0;
if (this._source)
this._source.destroy();
return false;
},
setMessage: function(text, undoCallback, undoLabel) {
if (this._timeoutId)
Mainloop.source_remove(this._timeoutId);
this._timeoutId = Mainloop.timeout_add_seconds(SHELL_INFO_HIDE_TIMEOUT,
Lang.bind(this, this._onTimeout));
if (this._source == null) {
this._source = new Source();
this._source.connect('destroy', Lang.bind(this,
@ -106,6 +88,8 @@ ShellInfo.prototype = {
else
notification.update(text, null, { clear: true });
notification.setTransient(true);
this._undoCallback = undoCallback;
if (undoCallback) {
notification.addButton('system-undo',
@ -171,10 +155,10 @@ Overview.prototype = {
this._group.add_actor(this.viewSelector.actor);
this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
this.viewSelector.addViewTab("Windows", this._workspacesDisplay.actor);
this.viewSelector.addViewTab(_("Windows"), this._workspacesDisplay.actor);
let appView = new AppDisplay.AllAppDisplay();
this.viewSelector.addViewTab("Applications", appView.actor);
this.viewSelector.addViewTab(_("Applications"), appView.actor);
// Default search providers
this.viewSelector.addSearchProvider(new AppDisplay.AppSearchProvider());

View File

@ -12,6 +12,7 @@ const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const Calendar = imports.ui.calendar;
const Config = imports.misc.config;
const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const PanelMenu = imports.ui.panelMenu;
@ -37,6 +38,14 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
'battery': imports.ui.status.power.Indicator
};
if (Config.HAVE_BLUETOOTH)
STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION['bluetooth'] = imports.ui.status.bluetooth.Indicator;
const CLOCK_FORMAT_KEY = 'format';
const CLOCK_CUSTOM_FORMAT_KEY = 'custom-format';
const CLOCK_SHOW_DATE_KEY = 'show-date';
const CLOCK_SHOW_SECONDS_KEY = 'show-seconds';
function AnimatedIcon(name, size) {
this._init(name, size);
}
@ -809,25 +818,9 @@ Panel.prototype = {
this._rightBox.add(trayBox);
this._rightBox.add(statusBox);
for (let i = 0; i < STANDARD_TRAY_ICON_ORDER.length; i++) {
let role = STANDARD_TRAY_ICON_ORDER[i];
let constructor = STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION[role];
if (!constructor) {
// This icon is not implemented (this is a bug)
continue;
}
let indicator = new constructor();
statusBox.add(indicator.actor);
this._menus.addMenu(indicator.menu);
}
Main.statusIconDispatcher.connect('status-icon-added', Lang.bind(this, this._onTrayIconAdded));
Main.statusIconDispatcher.connect('status-icon-removed', Lang.bind(this, this._onTrayIconRemoved));
this._statusmenu = new StatusMenu.StatusMenuButton();
this._menus.addMenu(this._statusmenu.menu);
this._rightBox.add(this._statusmenu.actor);
// 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
@ -853,6 +846,28 @@ Panel.prototype = {
Main.chrome.addActor(this.actor, { visibleInOverview: true });
},
startStatusArea: function() {
for (let i = 0; i < STANDARD_TRAY_ICON_ORDER.length; i++) {
let role = STANDARD_TRAY_ICON_ORDER[i];
let constructor = STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION[role];
if (!constructor) {
// This icon is not implemented (this is a bug)
continue;
}
let indicator = new constructor();
this._statusBox.add(indicator.actor);
this._menus.addMenu(indicator.menu);
}
this._statusmenu = new StatusMenu.StatusMenuButton();
this._menus.addMenu(this._statusmenu.menu);
this._rightBox.add(this._statusmenu.actor);
},
hideCalendar: function() {
this._clockButton.closeCalendar();
},
startupAnimation: function() {
this.actor.y = -this.actor.height;
Tweener.addTween(this.actor,

View File

@ -50,7 +50,7 @@ Button.prototype = {
if (open) {
this.actor.add_style_pseudo_class('pressed');
let focus = global.stage.get_key_focus();
if (!focus || (focus != this.actor && !menu.contains(focus)))
if (!focus || (focus != this.actor && !menu.actor.contains(focus)))
this.actor.grab_key_focus();
} else
this.actor.remove_style_pseudo_class('pressed');

View File

@ -87,7 +87,7 @@ PopupBaseMenuItem.prototype = {
},
_onButtonReleaseEvent: function (actor, event) {
this.emit('activate', event);
this.activate(event);
return true;
},
@ -95,7 +95,7 @@ PopupBaseMenuItem.prototype = {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.emit('activate', event);
this.activate(event);
return true;
}
return false;
@ -132,29 +132,16 @@ PopupBaseMenuItem.prototype = {
this.emit('destroy');
},
// true if non descendant content includes @actor
contains: function(actor) {
return false;
},
// adds an actor to the menu item; @column defaults to the next
// open column, @span defaults to 1. If @span is -1, the actor
// will span the width of the menu item. Children are not
// allowed to overlap each other.
addActor: function(child, column, span) {
if (column == null) {
if (this._children.length) {
let lastChild = this._children[this._children.length - 1];
column = lastChild.column + lastChild.span;
} else
column = 0;
span = 1;
} else if (span == null)
span = 1;
this._children.push({ actor: child,
column: column,
span: span });
// adds an actor to the menu item; @params can contain %span
// (column span; defaults to 1, -1 means "all the remaining width"),
// %expand (defaults to #false), and %align (defaults to
// #St.Align.START)
addActor: function(child, params) {
params = Params.parse(params, { span: 1,
expand: false,
align: St.Align.START });
params.actor = child;
this._children.push(params);
this.actor.connect('destroy', Lang.bind(this, function () { this._removeChild(child); }));
this.actor.add_actor(child);
},
@ -272,25 +259,44 @@ PopupBaseMenuItem.prototype = {
for (let i = 0, col = 0; i < this._children.length; i++) {
let child = this._children[i];
let childBox = new Clutter.ActorBox();
childBox.x1 = x;
let [minWidth, naturalWidth] = child.actor.get_preferred_width(-1);
let availWidth, extraWidth;
if (this._columnWidths) {
if (child.span == -1)
childBox.x2 = box.x2;
availWidth = box.x2 - x;
else {
childBox.x2 = x;
availWidth = 0;
for (let j = 0; j < child.span; j++)
childBox.x2 += this._columnWidths[col++];
availWidth += this._columnWidths[col++];
}
extraWidth = availWidth - naturalWidth;
} else {
let [min, natural] = child.actor.get_preferred_width(-1);
childBox.x2 = x + natural;
availWidth = naturalWidth;
extraWidth = 0;
}
let [min, natural] = child.actor.get_preferred_height(-1);
childBox.y1 = Math.round(box.y1 + (height - natural) / 2);
childBox.y2 = childBox.y1 + natural;
if (child.expand) {
childBox.x1 = x;
childBox.x2 = x + availWidth;
} else if (child.align === St.Align.CENTER) {
childBox.x1 = x + Math.round(extraWidth / 2);
childBox.x2 = childBox.x1 + naturalWidth;
} else if (child.align === St.Align.END) {
childBox.x2 = x + availWidth;
childBox.x1 = childBox.x2 - naturalWidth;
} else {
childBox.x1 = x;
childBox.x2 = x + naturalWidth;
}
let [minHeight, naturalHeight] = child.actor.get_preferred_height(-1);
childBox.y1 = Math.round(box.y1 + (height - naturalHeight) / 2);
childBox.y2 = childBox.y1 + naturalHeight;
child.actor.allocate(childBox, flags);
x = childBox.x2 + this._spacing;
x += availWidth + this._spacing;
}
}
};
@ -322,7 +328,7 @@ PopupSeparatorMenuItem.prototype = {
PopupBaseMenuItem.prototype._init.call(this, { reactive: false });
this._drawingArea = new St.DrawingArea({ style_class: 'popup-separator-menu-item' });
this.addActor(this._drawingArea, 0, -1);
this.addActor(this._drawingArea, { span: -1, expand: true });
this._drawingArea.connect('repaint', Lang.bind(this, this._onRepaint));
},
@ -367,7 +373,7 @@ PopupSliderMenuItem.prototype = {
this._value = Math.max(Math.min(value, 1), 0);
this._slider = new St.DrawingArea({ style_class: 'popup-slider-menu-item', reactive: true });
this.addActor(this._slider, 0, -1);
this.addActor(this._slider, { span: -1, expand: true });
this._slider.connect('repaint', Lang.bind(this, this._sliderRepaint));
this._slider.connect('button-press-event', Lang.bind(this, this._startDragging));
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
@ -534,7 +540,7 @@ PopupSwitchMenuItem.prototype = {
this._switch = new Switch(active);
this.addActor(this.label);
this.addActor(this._switch.actor);
this.addActor(this._switch.actor, { align: St.Align.END });
this.connect('activate', Lang.bind(this,function(from) {
this.toggle();
@ -569,7 +575,7 @@ PopupImageMenuItem.prototype = {
this.label = new St.Label({ text: text });
this.addActor(this.label);
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.addActor(this._icon);
this.addActor(this._icon, { align: St.Align.END });
this.setIcon(iconName);
},
@ -601,76 +607,21 @@ function findNextInCycle(items, current, direction) {
return items[mod(cur + direction, items.length)];
}
function PopupMenu() {
this._init.apply(this, arguments);
function PopupMenuBase() {
throw new TypeError('Trying to instantiate abstract class PopupMenuBase');
}
PopupMenu.prototype = {
_init: function(sourceActor, alignment, arrowSide, gap) {
PopupMenuBase.prototype = {
_init: function(sourceActor, styleClass) {
this.sourceActor = sourceActor;
this._alignment = alignment;
this._arrowSide = arrowSide;
this._gap = gap;
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START });
this.actor = this._boxPointer.actor;
this.actor.style_class = 'popup-menu-boxpointer';
this._boxWrapper = new Shell.GenericContainer();
this._boxWrapper.connect('get-preferred-width', Lang.bind(this, this._boxGetPreferredWidth));
this._boxWrapper.connect('get-preferred-height', Lang.bind(this, this._boxGetPreferredHeight));
this._boxWrapper.connect('allocate', Lang.bind(this, this._boxAllocate));
this._boxPointer.bin.set_child(this._boxWrapper);
this._box = new St.BoxLayout({ style_class: 'popup-menu-content',
this.box = new St.BoxLayout({ style_class: styleClass,
vertical: true });
this._boxWrapper.add_actor(this._box);
this.actor.add_style_class_name('popup-menu');
global.focus_manager.add_group(this.actor);
if (sourceActor._delegate instanceof PopupSubMenuMenuItem) {
this._isSubMenu = true;
this.actor.reactive = true;
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
}
this.isOpen = false;
this._activeMenuItem = null;
},
_boxGetPreferredWidth: function (actor, forHeight, alloc) {
// Update the menuitem column widths
let columnWidths = [];
let items = this._box.get_children();
for (let i = 0; i < items.length; i++) {
if (items[i]._delegate instanceof PopupBaseMenuItem) {
let itemColumnWidths = items[i]._delegate.getColumnWidths();
for (let j = 0; j < itemColumnWidths.length; j++) {
if (j >= columnWidths.length || itemColumnWidths[j] > columnWidths[j])
columnWidths[j] = itemColumnWidths[j];
}
}
}
for (let i = 0; i < items.length; i++) {
if (items[i]._delegate instanceof PopupBaseMenuItem)
items[i]._delegate.setColumnWidths(columnWidths);
}
// Now they will request the right sizes
[alloc.min_size, alloc.natural_size] = this._box.get_preferred_width(forHeight);
},
_boxGetPreferredHeight: function (actor, forWidth, alloc) {
[alloc.min_size, alloc.natural_size] = this._box.get_preferred_height(forWidth);
},
_boxAllocate: function (actor, box, flags) {
this._box.allocate(box, flags);
},
addAction: function(title, callback) {
var menuItem = new PopupMenuItem(title);
this.addMenuItem(menuItem);
@ -681,9 +632,29 @@ PopupMenu.prototype = {
addMenuItem: function(menuItem, position) {
if (position == undefined)
this._box.add(menuItem.actor);
this.box.add(menuItem.actor);
else
this._box.insert_actor(menuItem.actor, position);
this.box.insert_actor(menuItem.actor, position);
if (menuItem instanceof PopupSubMenuMenuItem) {
if (position == undefined)
this.box.add(menuItem.menu.actor);
else
this.box.insert_actor(menuItem.menu.actor, position + 1);
menuItem._subMenuActivateId = menuItem.menu.connect('activate', Lang.bind(this, function() {
this.emit('activate');
this.close();
}));
menuItem._subMenuActiveChangeId = menuItem.menu.connect('active-changed', Lang.bind(this, function(submenu, submenuItem) {
if (this._activeMenuItem && this._activeMenuItem != submenuItem)
this._activeMenuItem.setActive(false);
this._activeMenuItem = submenuItem;
this.emit('active-changed', submenuItem);
}));
menuItem._closingId = this.connect('open-state-changed', function(self, open) {
if (!open)
menuItem.menu.immediateClose();
});
}
menuItem._activeChangeId = menuItem.connect('active-changed', Lang.bind(this, function (menuItem, active) {
if (active && this._activeMenuItem != menuItem) {
if (this._activeMenuItem)
@ -702,17 +673,45 @@ PopupMenu.prototype = {
menuItem.connect('destroy', Lang.bind(this, function(emitter) {
menuItem.disconnect(menuItem._activateId);
menuItem.disconnect(menuItem._activeChangeId);
if (menuItem.menu) {
menuItem.menu.disconnect(menuItem._subMenuActivateId);
menuItem.menu.disconnect(menuItem._subMenuActiveChangeId);
this.disconnect(menuItem._closingId);
}
if (menuItem == this._activeMenuItem)
this._activeMenuItem = null;
}));
},
getColumnWidths: function() {
let columnWidths = [];
let items = this.box.get_children();
for (let i = 0; i < items.length; i++) {
if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase) {
let itemColumnWidths = items[i]._delegate.getColumnWidths();
for (let j = 0; j < itemColumnWidths.length; j++) {
if (j >= columnWidths.length || itemColumnWidths[j] > columnWidths[j])
columnWidths[j] = itemColumnWidths[j];
}
}
}
return columnWidths;
},
setColumnWidths: function(widths) {
let items = this.box.get_children();
for (let i = 0; i < items.length; i++) {
if (items[i]._delegate instanceof PopupBaseMenuItem || items[i]._delegate instanceof PopupMenuBase)
items[i]._delegate.setColumnWidths(widths);
}
},
addActor: function(actor) {
this._box.add(actor);
this.box.add(actor);
},
getMenuItems: function() {
return this._box.get_children().map(function (actor) { return actor._delegate; });
return this.box.get_children().map(function (actor) { return actor._delegate; }).filter(function(item) { return item instanceof PopupBaseMenuItem; });
},
removeAll: function() {
@ -723,81 +722,17 @@ PopupMenu.prototype = {
}
},
setArrowOrigin: function(origin) {
this._boxPointer.setArrowOrigin(origin);
},
activateFirst: function() {
let children = this._box.get_children();
let children = this.box.get_children();
for (let i = 0; i < children.length; i++) {
let actor = children[i];
if (actor._delegate && actor.visible && actor.reactive) {
if (actor._delegate && actor._delegate instanceof PopupBaseMenuItem && actor.visible && actor.reactive) {
actor._delegate.setActive(true);
break;
}
}
},
open: function() {
if (this.isOpen)
return;
let primary = global.get_primary_monitor();
// We need to show it now to force an allocation,
// so that we can query the correct size.
this.actor.show();
// Position correctly relative to the sourceActor
let [sourceX, sourceY] = this.sourceActor.get_transformed_position();
let [sourceWidth, sourceHeight] = this.sourceActor.get_transformed_size();
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
let menuWidth = natWidth, menuHeight = natHeight;
// Position the non-pointing axis
if (this._isSubmenu) {
if (this._arrowSide == St.Side.TOP || this._arrowSide == St.Side.BOTTOM) {
// vertical submenu
if (sourceY + sourceHeigth + menuHeight + this._gap < primary.y + primary.height)
this._boxPointer._arrowSide = this._arrowSide = St.Side.TOP;
else if (primary.y + menuHeight + this._gap < sourceY)
this._boxPointer._arrowSide = this._arrowSide = St.Side.BOTTOM;
else
this._boxPointer._arrowSide = this._arrowSide = St.Side.TOP;
} else {
// horizontal submenu
if (sourceX + sourceWidth + menuWidth + this._gap < primary.x + primary.width)
this._boxPointer._arrowSide = this._arrowSide = St.Side.LEFT;
else if (primary.x + menuWidth + this._gap < sourceX)
this._boxPointer._arrowSide = this._arrowSide = St.Side.RIGHT;
else
this._boxPointer._arrowSide = this._arrowSide = St.Side.LEFT;
}
}
this._boxPointer.setPosition(this.sourceActor, this._gap, this._alignment);
// Now show it
this.actor.reactive = true;
this._boxPointer.animateAppear();
this.isOpen = true;
this.emit('open-state-changed', true);
},
close: function() {
if (!this.isOpen)
return;
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this.actor.reactive = false;
this._boxPointer.animateDisappear();
this.isOpen = false;
this.emit('open-state-changed', false);
},
toggle: function() {
if (this.isOpen)
this.close();
@ -805,30 +740,6 @@ PopupMenu.prototype = {
this.open();
},
_onKeyPressEvent: function(actor, event) {
// Move focus back to parent menu if the user types Left.
// (This handler is only connected if the PopupMenu is a
// submenu.)
if (this.isOpen &&
this._activeMenuItem &&
event.get_key_symbol() == Clutter.KEY_Left) {
this._activeMenuItem.setActive(false);
return true;
}
return false;
},
// return true if the actor is inside the menu or
// any actor related to the active submenu
contains: function(actor) {
if (this.actor.contains(actor))
return true;
if (this._activeMenuItem)
return this._activeMenuItem.contains(actor);
return false;
},
destroy: function() {
this.removeAll();
this.actor.destroy();
@ -836,7 +747,186 @@ PopupMenu.prototype = {
this.emit('destroy');
}
};
Signals.addSignalMethods(PopupMenu.prototype);
Signals.addSignalMethods(PopupMenuBase.prototype);
function PopupMenu() {
this._init.apply(this, arguments);
}
PopupMenu.prototype = {
__proto__: PopupMenuBase.prototype,
_init: function(sourceActor, alignment, arrowSide, gap) {
PopupMenuBase.prototype._init.call (this, sourceActor, 'popup-menu-content');
this._alignment = alignment;
this._arrowSide = arrowSide;
this._gap = gap;
this._boxPointer = new BoxPointer.BoxPointer(arrowSide,
{ x_fill: true,
y_fill: true,
x_align: St.Align.START });
this.actor = this._boxPointer.actor;
this.actor._delegate = this;
this.actor.style_class = 'popup-menu-boxpointer';
this._boxWrapper = new Shell.GenericContainer();
this._boxWrapper.connect('get-preferred-width', Lang.bind(this, this._boxGetPreferredWidth));
this._boxWrapper.connect('get-preferred-height', Lang.bind(this, this._boxGetPreferredHeight));
this._boxWrapper.connect('allocate', Lang.bind(this, this._boxAllocate));
this._boxPointer.bin.set_child(this._boxWrapper);
this._boxWrapper.add_actor(this.box);
this.actor.add_style_class_name('popup-menu');
global.focus_manager.add_group(this.actor);
this.actor.reactive = true;
},
_boxGetPreferredWidth: function (actor, forHeight, alloc) {
let columnWidths = this.getColumnWidths();
this.setColumnWidths(columnWidths);
// Now they will request the right sizes
[alloc.min_size, alloc.natural_size] = this.box.get_preferred_width(forHeight);
},
_boxGetPreferredHeight: function (actor, forWidth, alloc) {
[alloc.min_size, alloc.natural_size] = this.box.get_preferred_height(forWidth);
},
_boxAllocate: function (actor, box, flags) {
this.box.allocate(box, flags);
},
setArrowOrigin: function(origin) {
this._boxPointer.setArrowOrigin(origin);
},
open: function() {
if (this.isOpen)
return;
this.isOpen = true;
this._boxPointer.setPosition(this.sourceActor, this._gap, this._alignment);
this._boxPointer.animateAppear();
this.emit('open-state-changed', true);
},
close: function() {
if (!this.isOpen)
return;
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this._boxPointer.animateDisappear();
this.isOpen = false;
this.emit('open-state-changed', false);
}
};
function PopupSubMenu() {
this._init.apply(this, arguments);
}
PopupSubMenu.prototype = {
__proto__: PopupMenuBase.prototype,
_init: function(sourceActor, sourceArrow) {
PopupMenuBase.prototype._init.call(this, sourceActor, 'popup-sub-menu');
this._arrow = sourceArrow;
this._arrow.rotation_center_z_gravity = Clutter.Gravity.CENTER;
this.actor = this.box;
this.actor._delegate = this;
this.actor.clip_to_allocation = true;
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this.actor.hide();
},
open: function() {
if (this.isOpen)
return;
this.isOpen = true;
let [naturalHeight, minHeight] = this.actor.get_preferred_height(-1);
this.actor.height = 0;
this.actor.show();
this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor,
{ _arrow_rotation: 90,
height: naturalHeight,
time: 0.25,
onUpdateScope: this,
onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrow_rotation;
},
onCompleteScope: this,
onComplete: function() {
this.actor.set_height(-1);
this.emit('open-state-changed', true);
}
});
},
close: function() {
if (!this.isOpen)
return;
this.isOpen = false;
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this.actor._arrow_rotation = this._arrow.rotation_angle_z;
Tweener.addTween(this.actor,
{ _arrow_rotation: 0,
height: 0,
time: 0.25,
onCompleteScope: this,
onComplete: function() {
this.actor.hide();
this.actor.set_height(-1);
this.emit('open-state-changed', false);
},
onUpdateScope: this,
onUpdate: function() {
this._arrow.rotation_angle_z = this.actor._arrow_rotation;
}
});
},
immediateClose: function() {
if (!this.isOpen)
return;
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this.actor.hide();
this.isOpen = false;
this.emit('open-state-changed', false);
},
_onKeyPressEvent: function(actor, event) {
// Move focus back to parent menu if the user types Left.
if (this.isOpen && event.get_key_symbol() == Clutter.KEY_Left) {
this.close();
this.sourceActor._delegate.setActive(true);
return true;
}
return false;
}
};
function PopupSubMenuMenuItem() {
this._init.apply(this, arguments);
@ -846,77 +936,46 @@ PopupSubMenuMenuItem.prototype = {
__proto__: PopupBaseMenuItem.prototype,
_init: function(text) {
PopupBaseMenuItem.prototype._init.call(this, { activate: false, hover: false });
this.actor.connect('enter-event', Lang.bind(this, this._mouseEnter));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
PopupBaseMenuItem.prototype._init.call(this);
this.actor.add_style_class_name('popup-submenu-menu-item');
this.label = new St.Label({ text: text });
this.addActor(this.label);
this.addActor(new St.Label({ text: '>' }));
this._triangle = new St.Label({ text: '\u25B8' });
this.addActor(this._triangle, { align: St.Align.END });
this.menu = new PopupMenu(this.actor, St.Align.MIDDLE, St.Side.LEFT, 0, true);
Main.chrome.addActor(this.menu.actor, { visibleInOverview: true,
affectsStruts: false });
this.menu.actor.hide();
this._openStateChangedId = this.menu.connect('open-state-changed', Lang.bind(this, this._subMenuOpenStateChanged));
this._activateId = this.menu.connect('activate', Lang.bind(this, this._subMenuActivate));
this.menu = new PopupSubMenu(this.actor, this._triangle);
this.menu.connect('open-state-changed', Lang.bind(this, this._subMenuOpenStateChanged));
},
_subMenuOpenStateChanged: function(menu, open) {
PopupBaseMenuItem.prototype.setActive.call(this, open);
},
_subMenuActivate: function(menu, menuItem) {
this.emit('activate', null);
},
setMenu: function(newmenu) {
if (this.menu) {
this.menu.close();
this.menu.disconnect(this._openStateChangedId);
this.menu.disconnect(this._activateId);
}
if (newmenu) {
this._openStateChangedId = newmenu.connect('open-state-changed', Lang.bind(this, this._subMenuOpenStateChanged));
this._activateId = newmenu.connect('activate', Lang.bind(this, this._subMenuActivate));
}
this.menu = newmenu;
if (open)
this.actor.add_style_pseudo_class('open');
else
this.actor.remove_style_pseudo_class('open');
},
destroy: function() {
if (this.menu)
this.menu.destroy();
PopupBaseMenuItem.prototype.destroy.call(this);
},
setActive: function(active) {
if (this.menu) {
if (active)
this.menu.open();
else
this.menu.close();
}
PopupBaseMenuItem.prototype.setActive.call(this, active);
},
_onKeyPressEvent: function(actor, event) {
if (!this.menu)
return false;
if (event.get_key_symbol() == Clutter.KEY_Right) {
this.menu.open();
this.menu.activateFirst();
return true;
}
return false;
return PopupBaseMenuItem.prototype._onKeyPressEvent.call(this, actor, event);
},
contains: function(actor) {
return this.menu && this.menu.contains(actor);
activate: function(event) {
this.menu.open();
},
_mouseEnter: function(event) {
this.setActive(true);
_onButtonReleaseEvent: function(actor) {
this.menu.toggle();
}
};
@ -1045,7 +1104,7 @@ PopupMenuManager.prototype = {
_eventIsOnActiveMenu: function(event) {
let src = event.get_source();
return this._activeMenu != null
&& (this._activeMenu.contains(src) ||
&& (this._activeMenu.actor.contains(src) ||
(this._activeMenu.sourceActor && this._activeMenu.sourceActor.contains(src)));
},

446
js/ui/status/bluetooth.js Normal file
View File

@ -0,0 +1,446 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Clutter = imports.gi.Clutter;
const Gdk = imports.gi.Gdk;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const GnomeBluetoothApplet = imports.gi.GnomeBluetoothApplet;
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const ConnectionState = {
DISCONNECTED: 0,
CONNECTED: 1,
DISCONNECTING: 2,
CONNECTING: 3
}
function Indicator() {
this._init.apply(this, arguments);
}
Indicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'bluetooth-disabled', null);
GLib.spawn_command_line_sync ('pkill -f "^bluetooth-applet$"');
this._applet = new GnomeBluetoothApplet.Applet();
this._killswitch = new PopupMenu.PopupSwitchMenuItem(_("Bluetooth"), false);
this._applet.connect('notify::killswitch-state', Lang.bind(this, this._updateKillswitch));
this._killswitch.connect('toggled', Lang.bind(this, function() {
let current_state = this._applet.killswitch_state;
if (current_state != GnomeBluetoothApplet.KillswitchState.HARD_BLOCKED &&
current_state != GnomeBluetoothApplet.KillswitchState.NO_ADAPTER) {
this._applet.killswitch_state = this._killswitch.state ?
GnomeBluetoothApplet.KillswitchState.UNBLOCKED:
GnomeBluetoothApplet.KillswitchState.SOFT_BLOCKED;
} else
this._killswitch.setToggleState(false);
}));
this._discoverable = new PopupMenu.PopupSwitchMenuItem(_("Visibility"), this._applet.discoverable);
this._applet.connect('notify::discoverable', Lang.bind(this, function() {
this._discoverable.setToggleState(this._applet.discoverable);
}));
this._discoverable.connect('toggled', Lang.bind(this, function() {
this._applet.discoverable = this._discoverable.state;
}));
this._updateKillswitch();
this.menu.addMenuItem(this._killswitch);
this.menu.addMenuItem(this._discoverable);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._fullMenuItems = [new PopupMenu.PopupMenuItem(_("Send Files to Device...")),
new PopupMenu.PopupSeparatorMenuItem(),
new PopupMenu.PopupSeparatorMenuItem(),
new PopupMenu.PopupMenuItem(_("Setup a New Device..."))];
this._deviceSep = this._fullMenuItems[1]; // hidden if no device exists
this._fullMenuItems[0].connect('activate', function() {
GLib.spawn_command_line_async('bluetooth-sendto');
});
this._fullMenuItems[3].connect('activate', function() {
GLib.spawn_command_line_async('bluetooth-wizard');
});
for (let i = 0; i < this._fullMenuItems.length; i++) {
let item = this._fullMenuItems[i];
this.menu.addMenuItem(item);
}
this._deviceItemPosition = 5;
this._deviceItems = [];
this._applet.connect('devices-changed', Lang.bind(this, this._updateDevices));
this._updateDevices();
this._applet.connect('notify::show-full-menu', Lang.bind(this, this._updateFullMenu));
this._updateFullMenu();
this.menu.addAction(_("Bluetooth Settings"), function() {
GLib.spawn_command_line_async('gnome-control-center bluetooth');
});
this._applet.connect('pincode-request', Lang.bind(this, this._pinRequest));
this._applet.connect('confirm-request', Lang.bind(this, this._confirmRequest));
this._applet.connect('auth-request', Lang.bind(this, this._authRequest));
this._applet.connect('cancel-request', Lang.bind(this, this._cancelRequest));
},
_updateKillswitch: function() {
let current_state = this._applet.killswitch_state;
let on = current_state == GnomeBluetoothApplet.KillswitchState.UNBLOCKED;
let can_toggle = current_state != GnomeBluetoothApplet.KillswitchState.NO_ADAPTER &&
current_state != GnomeBluetoothApplet.KillswitchState.HARD_BLOCKED;
this._killswitch.setToggleState(on);
this._killswitch.actor.reactive = can_toggle;
if (on) {
this._discoverable.actor.show();
this.setIcon('bluetooth-active');
} else {
this._discoverable.actor.hide();
this.setIcon('bluetooth-disabled');
}
},
_updateDevices: function() {
this._destroyAll(this._deviceItems);
this._deviceItems = [];
let devices = this._applet.get_devices();
if (devices.length == 0)
this._deviceSep.actor.hide();
else
this._deviceSep.actor.show();
for (let i = 0; i < devices.length; i++) {
let d = devices[i];
let item = this._createDeviceItem(d);
if (item) {
this.menu.addMenuItem(item, this._deviceItemPosition + this._deviceItems.length);
this._deviceItems.push(item);
}
}
},
_createDeviceItem: function(device) {
if (!device.can_connect && device.capabilities == GnomeBluetoothApplet.Capabilities.NONE)
return null;
let item = new PopupMenu.PopupSubMenuMenuItem(device.alias);
item._device = device;
if (device.can_connect) {
item._connected = device.connected;
let menuitem = new PopupMenu.PopupSwitchMenuItem(_("Connection"), device.connected);
menuitem.connect('toggled', Lang.bind(this, function() {
if (item._connected > ConnectionState.CONNECTED) {
// operation already in progress, revert
menuitem.setToggleState(menuitem.state);
}
if (item._connected) {
item._connected = ConnectionState.DISCONNECTING;
this._applet.disconnect_device(item._device.device_path, function(applet, success) {
if (success) { // apply
item._connected = ConnectionState.DISCONNECTED;
menuitem.setToggleState(false);
} else { // revert
item._connected = ConnectionState.CONNECTED;
menuitem.setToggleState(true);
}
});
} else {
item._connected = ConnectionState.CONNECTING;
this._applet.connect_device(item._device.device_path, function(applet, success) {
if (success) { // apply
item._connected = ConnectionState.CONNECTED;
menuitem.setToggleState(true);
} else { // revert
item._connected = ConnectionState.DISCONNECTED;
menuitem.setToggleState(false);
}
});
}
}));
item.menu.addMenuItem(menuitem);
}
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_PUSH) {
item.menu.addAction(_("Send Files..."), Lang.bind(this, function() {
this._applet.send_to_address(device.bdaddr, device.alias);
}));
}
if (device.capabilities & GnomeBluetoothApplet.Capabilities.OBEX_FILE_TRANSFER) {
item.menu.addAction(_("Browse Files..."), Lang.bind(this, function(event) {
this._applet.browse_address(device.bdaddr, event.get_time(),
Lang.bind(this, function(applet, result) {
try {
applet.browse_address_finish(result);
} catch (e) {
this._ensureSource();
this._source.notify(new MessageTray.Notification(this._source,
_("Bluetooth"),
_("Error browsing device"),
{ body: _("The requested device cannot be browsed, error is '%s'").format(e) }));
}
}));
}));
}
switch (device.type) {
case GnomeBluetoothApplet.Type.KEYBOARD:
item.menu.addAction(_("Keyboard Settings"), function() {
GLib.spawn_command_line_async('gnome-control-center keyboard');
});
break;
case GnomeBluetoothApplet.Type.MOUSE:
item.menu.addAction(_("Mouse Settings"), function() {
GLib.spawn_command_line_async('gnome-control-center mouse');
});
break;
case GnomeBluetoothApplet.Type.HEADSET:
case GnomeBluetoothApplet.Type.HEADPHONES:
case GnomeBluetoothApplet.Type.OTHER_AUDIO:
item.menu.addAction(_("Sound Settings"), function() {
GLib.spawn_command_line_async('gnome-control-center sound');
});
break;
default:
break;
}
return item;
},
_updateFullMenu: function() {
if (this._applet.show_full_menu) {
this._showAll(this._fullMenuItems);
this._showAll(this._deviceItems);
} else {
this._hideAll(this._fullMenuItems);
this._hideAll(this._deviceItems);
}
},
_showAll: function(items) {
for (let i = 0; i < items.length; i++)
items[i].actor.show();
},
_hideAll: function(items) {
for (let i = 0; i < items.length; i++)
items[i].actor.hide();
},
_destroyAll: function(items) {
for (let i = 0; i < items.length; i++)
items[i].destroy();
},
_ensureSource: function() {
if (!this._source) {
this._source = new Source();
Main.messageTray.add(this._source);
}
},
_authRequest: function(applet, device_path, name, long_name, uuid) {
this._ensureSource();
this._source.notify(new AuthNotification(this._source, this._applet, device_path, name, long_name, uuid));
},
_confirmRequest: function(applet, device_path, name, long_name, pin) {
this._ensureSource();
this._source.notify(new ConfirmNotification(this._source, this._applet, device_path, name, long_name, pin));
},
_pinRequest: function(applet, device_path, name, long_name, numeric) {
this._ensureSource();
this._source.notify(new PinNotification(this._source, this._applet, device_path, name, long_name, numeric));
},
_cancelRequest: function() {
this._source.destroy();
}
}
function Source() {
this._init.apply(this, arguments);
}
Source.prototype = {
__proto__: MessageTray.Source.prototype,
_init: function() {
MessageTray.Source.prototype._init.call(this, _("Bluetooth Agent"));
this._setSummaryIcon(this.createNotificationIcon());
},
notify: function(notification) {
this._private_destroyId = notification.connect('destroy', Lang.bind(this, function(notification) {
if (this.notification == notification) {
// the destroyed notification is the last for this source
this.notification.disconnect(this._private_destroyId);
this.destroy();
}
}));
MessageTray.Source.prototype.notify.call(this, notification);
},
createNotificationIcon: function() {
return new St.Icon({ icon_name: 'bluetooth-active',
icon_type: St.IconType.SYMBOLIC,
icon_size: this.ICON_SIZE });
}
}
function AuthNotification() {
this._init.apply(this, arguments);
}
AuthNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
_init: function(source, applet, device_path, name, long_name, uuid) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth Agent"),
_("Authorization request from %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants access to the service '%s'").format(long_name, uuid));
this.addButton('always-grant', _("Always grant access"));
this.addButton('grant', _("Grant this time only"));
this.addButton('reject', _("Reject"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
switch (action) {
case 'always-grant':
this._applet.agent_reply_auth(this._devicePath, true, true);
break;
case 'grant':
this._applet.agent_reply_auth(this._devicePath, true, false);
break;
case 'reject':
default:
this._applet.agent_reply_auth(this._devicePath, false, false);
}
this.destroy();
}));
}
}
function ConfirmNotification() {
this._init.apply(this, arguments);
}
ConfirmNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
_init: function(source, applet, device_path, name, long_name, pin) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth Agent"),
_("Pairing confirmation for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please confirm whether the PIN '%s' matches the one on the device.").format(pin));
this.addButton('matches', _("Matches"));
this.addButton('does-not-match', _("Does not match"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'matches')
this._applet.agent_reply_confirm(this._devicePath, true);
else
this._applet.agent_reply_confirm(this._devicePath, false);
this.destroy();
}));
}
}
function PinNotification() {
this._init.apply(this, arguments);
}
PinNotification.prototype = {
__proto__: MessageTray.Notification.prototype,
_init: function(source, applet, device_path, name, long_name, numeric) {
MessageTray.Notification.prototype._init.call(this,
source,
_("Bluetooth Agent"),
_("Pairing request for %s").format(name),
{ customContent: true });
this.setResident(true);
this._applet = applet;
this._devicePath = device_path;
this._numeric = numeric;
this.addBody(_("Device %s wants to pair with this computer").format(long_name));
this.addBody(_("Please enter the PIN mentioned on the device."));
this._entry = new St.Entry();
this._entry.connect('key-release-event', Lang.bind(this, function(entry, event) {
let key = event.get_key_symbol();
if (key == Clutter.KEY_Return) {
this.emit('action-invoked', 'ok');
return true;
} else if (key == Clutter.KEY_Escape) {
this.emit('action-invoked', 'cancel');
return true;
}
return false;
}));
this.addActor(this._entry);
this.addButton('ok', _("Ok"));
this.addButton('cancel', _("Cancel"));
this.connect('action-invoked', Lang.bind(this, function(self, action) {
if (action == 'ok') {
if (this._numeric)
this._applet.agent_reply_passkey(this._devicePath, parseInt(this._entry.text));
else
this._applet.agent_reply_pincode(this._devicePath, this._entry.text);
} else {
if (this._numeric)
this._applet.agent_reply_passkey(this._devicePath, -1);
else
this._applet.agent_reply_pincode(this._devicePath, null);
}
this.destroy();
}));
},
grabFocus: function(lockTray) {
MessageTray.Notification.prototype.grabFocus.call(this, lockTray);
global.stage.set_key_focus(this._entry);
}
}

View File

@ -74,9 +74,7 @@ Indicator.prototype = {
this._batteryItem = new PopupMenu.PopupMenuItem('');
this._primaryPercentage = new St.Label();
let percentBin = new St.Bin();
percentBin.set_child(this._primaryPercentage, { x_align: St.Align.END });
this._batteryItem.addActor(percentBin);
this._batteryItem.addActor(this._primaryPercentage, { align: St.Align.END });
this.menu.addMenuItem(this._batteryItem);
this._deviceSep = new PopupMenu.PopupSeparatorMenuItem();
@ -84,9 +82,6 @@ Indicator.prototype = {
this._otherDevicePosition = 2;
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("What's using power..."),function() {
GLib.spawn_command_line_async('gnome-power-statistics --device wakeups');
});
this.menu.addAction(_("Power Settings"),function() {
GLib.spawn_command_line_async('gnome-control-center power');
});
@ -232,10 +227,8 @@ DeviceItem.prototype = {
this._box.add_actor(this._label);
this.addActor(this._box);
let percentBin = new St.Bin({ x_align: St.Align.END });
let percentLabel = new St.Label({ text: '%d%%'.format(Math.round(percentage)) });
percentBin.child = percentLabel;
this.addActor(percentBin);
this.addActor(percentLabel, { align: St.Align.END });
},
_deviceTypeToString: function(type) {

View File

@ -396,7 +396,7 @@ WindowOverlay.prototype = {
// These parameters are not the values retrieved with
// get_transformed_position() and get_transformed_size(),
// as windowClone might be moving.
// See Workspace._fadeInWindowOverlay
// See Workspace._showWindowOverlay
updatePositions: function(cloneX, cloneY, cloneWidth, cloneHeight) {
let button = this.closeButton;
let title = this.title;
@ -566,8 +566,6 @@ Workspace.prototype = {
Lang.bind(this, this._windowRemoved));
this._repositionWindowsId = 0;
this._visible = false;
this.leavingOverview = false;
},
@ -948,6 +946,9 @@ Workspace.prototype = {
let slots = this._computeAllWindowSlots(visibleClones.length);
visibleClones = this._orderWindowsByMotionAndStartup(visibleClones, slots);
let currentWorkspace = global.screen.get_active_workspace();
let isOnCurrentWorkspace = this.metaWorkspace == currentWorkspace;
for (let i = 0; i < visibleClones.length; i++) {
let slot = slots[i];
let clone = visibleClones[i];
@ -964,7 +965,7 @@ Workspace.prototype = {
if (overlay)
overlay.hide();
if (animate) {
if (animate && isOnCurrentWorkspace) {
if (!metaWindow.showing_on_its_workspace()) {
/* Hidden windows should fade in and grow
* therefore we need to resize them now so they
@ -994,13 +995,13 @@ Workspace.prototype = {
time: Overview.ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this._fadeInWindowOverlay(clone, overlay);
this._showWindowOverlay(clone, overlay, true);
})
});
} else {
clone.actor.set_position(x, y);
clone.actor.set_scale(scale, scale);
this._fadeInWindowOverlay(clone, overlay);
this._showWindowOverlay(clone, overlay, isOnCurrentWorkspace);
}
}
},
@ -1021,7 +1022,7 @@ Workspace.prototype = {
}
},
_fadeInWindowOverlay: function(clone, overlay) {
_showWindowOverlay: function(clone, overlay, fade) {
if (clone.inDrag)
return;
@ -1043,17 +1044,21 @@ Workspace.prototype = {
if (overlay) {
overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
if (fade)
overlay.fadeIn();
else
overlay.show();
}
},
_fadeInAllOverlays: function() {
_showAllOverlays: function() {
let currentWorkspace = global.screen.get_active_workspace();
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
let overlay = this._windowOverlays[i];
if (this._showOnlyWindows != null && !(clone.metaWindow in this._showOnlyWindows))
continue;
this._fadeInWindowOverlay(clone, overlay);
this._showWindowOverlay(clone, overlay, this.metaWorkspace == currentWorkspace);
}
},
@ -1089,7 +1094,7 @@ Workspace.prototype = {
showWindowsOverlays: function() {
this._windowOverlaysGroup.show();
this._fadeInAllOverlays();
this._showAllOverlays();
},
hideWindowsOverlays: function() {
@ -1206,12 +1211,12 @@ Workspace.prototype = {
this.positionWindows(WindowPositionFlags.ANIMATE | WindowPositionFlags.ZOOM);
else
this.positionWindows(WindowPositionFlags.ZOOM);
this._visible = true;
},
// Animates the return from Overview mode
zoomFromOverview : function() {
let currentWorkspace = global.screen.get_active_workspace();
this.leavingOverview = true;
this._hideAllOverlays();
@ -1223,6 +1228,9 @@ Workspace.prototype = {
this._overviewHiddenId = Main.overview.connect('hidden', Lang.bind(this,
this._doneLeavingOverview));
if (this._metaWorkspace == currentWorkspace)
return;
// Position and scale the windows.
for (let i = 0; i < this._windows.length; i++) {
let clone = this._windows[i];
@ -1253,7 +1261,6 @@ Workspace.prototype = {
}
}
this._visible = false;
},
destroy : function() {

145
po/es.po
View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&component=general\n"
"POT-Creation-Date: 2010-12-02 18:10+0000\n"
"PO-Revision-Date: 2010-12-11 16:42+0100\n"
"POT-Creation-Date: 2010-12-18 19:25+0000\n"
"PO-Revision-Date: 2010-12-19 13:12+0100\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"
@ -399,23 +399,27 @@ msgstr "Formato _12 horas"
msgid "_24 hour format"
msgstr "Formato _24 horas"
#: ../js/ui/appDisplay.js:215
#: ../js/ui/appDisplay.js:154
msgid "All"
msgstr "Todas"
#: ../js/ui/appDisplay.js:235
msgid "APPLICATIONS"
msgstr "APLICACIONES"
#: ../js/ui/appDisplay.js:245
#: ../js/ui/appDisplay.js:265
msgid "PREFERENCES"
msgstr "PREFERENCIAS"
#: ../js/ui/appDisplay.js:542
#: ../js/ui/appDisplay.js:562
msgid "New Window"
msgstr "Ventana nueva"
#: ../js/ui/appDisplay.js:546
#: ../js/ui/appDisplay.js:566
msgid "Remove from Favorites"
msgstr "Quitar de los favoritos"
#: ../js/ui/appDisplay.js:547
#: ../js/ui/appDisplay.js:567
msgid "Add to Favorites"
msgstr "Añadir a los favoritos"
@ -467,63 +471,71 @@ msgstr "Ver fuente"
msgid "Web Page"
msgstr "Página web"
#: ../js/ui/overview.js:112
#: ../js/ui/overview.js:96
msgid "Undo"
msgstr "Deshacer"
#: ../js/ui/overview.js:158
msgid "Windows"
msgstr "Ventanas"
#: ../js/ui/overview.js:161
msgid "Applications"
msgstr "Aplicaciones"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:470
#: ../js/ui/panel.js:474
#, c-format
msgid "Quit %s"
msgstr "Salir de %s"
#: ../js/ui/panel.js:495
#: ../js/ui/panel.js:499
msgid "Preferences"
msgstr "Preferencias"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:581
#: ../js/ui/panel.js:585
msgid "%a %b %e, %R:%S"
msgstr "%a %e de %b, %R:%S"
#: ../js/ui/panel.js:582
#: ../js/ui/panel.js:586
msgid "%a %b %e, %R"
msgstr "%a %e de %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:586
#: ../js/ui/panel.js:590
msgid "%a %R:%S"
msgstr "%a %R:%S"
#: ../js/ui/panel.js:587
#: ../js/ui/panel.js:591
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:594
#: ../js/ui/panel.js:598
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e de %b, %H:%M:%S"
#: ../js/ui/panel.js:595
#: ../js/ui/panel.js:599
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e de %b, %H:%M"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:599
#: ../js/ui/panel.js:603
msgid "%a %l:%M:%S %p"
msgstr "%a %H:%M:%S"
#: ../js/ui/panel.js:600
#: ../js/ui/panel.js:604
msgid "%a %l:%M %p"
msgstr "%a %H:%M"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:745
#: ../js/ui/panel.js:749
msgid "Activities"
msgstr "Actividades"
@ -642,101 +654,87 @@ msgstr "Contraste alto"
msgid "Large Text"
msgstr "<b>Texto:</b>"
#: ../js/ui/status/power.js:87
msgid "What's using power..."
msgstr "Lo que está usando energía…"
#: ../js/ui/status/power.js:90
#| msgid "System Settings"
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "Configuración de energía"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:112
#, c-format
#| msgid "%d hour ago"
#| msgid_plural "%d hours ago"
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
msgstr[0] "Queda %d hora"
msgstr[1] "Queda %d horas"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:115
#, c-format
msgid "%d %s %d %s remaining"
msgstr "Quedan %d %s %d %s"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:117
msgid "hour"
msgid_plural "hours"
msgstr[0] "hora"
msgstr[1] "horas"
#: ../js/ui/status/power.js:122
#| msgid "%d minute ago"
#| msgid_plural "%d minutes ago"
#: ../js/ui/status/power.js:117
msgid "minute"
msgid_plural "minutes"
msgstr[0] "miuto"
msgstr[1] "minutos"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:120
#, c-format
#| msgid "%d minute ago"
#| msgid_plural "%d minutes ago"
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "Queda %d minuto"
msgstr[1] "Queda %d minutos"
#: ../js/ui/status/power.js:244
#: ../js/ui/status/power.js:237
msgid "AC adapter"
msgstr "Adaptador de corriente"
#: ../js/ui/status/power.js:246
#: ../js/ui/status/power.js:239
msgid "Laptop battery"
msgstr "Batería del portátil"
#: ../js/ui/status/power.js:248
#: ../js/ui/status/power.js:241
msgid "UPS"
msgstr "SAI"
#: ../js/ui/status/power.js:250
#: ../js/ui/status/power.js:243
msgid "Monitor"
msgstr "Monitor"
#: ../js/ui/status/power.js:252
#| msgid "Mouse Keys"
#: ../js/ui/status/power.js:245
msgid "Mouse"
msgstr "Ratón"
#: ../js/ui/status/power.js:254
#| msgid "Screen Keyboard"
#: ../js/ui/status/power.js:247
msgid "Keyboard"
msgstr "Teclado"
#: ../js/ui/status/power.js:256
#: ../js/ui/status/power.js:249
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:258
#: ../js/ui/status/power.js:251
msgid "Cell phone"
msgstr "Teléfono móvil"
#: ../js/ui/status/power.js:260
#: ../js/ui/status/power.js:253
msgid "Media player"
msgstr "Reproductor multimedia"
#: ../js/ui/status/power.js:262
#| msgid "Enabled"
#: ../js/ui/status/power.js:255
msgid "Tablet"
msgstr "Tableta"
#: ../js/ui/status/power.js:264
#: ../js/ui/status/power.js:257
msgid "Computer"
msgstr "Equipo"
#: ../js/ui/status/power.js:266 ../src/shell-app-system.c:1012
#: ../js/ui/status/power.js:259 ../src/shell-app-system.c:1012
msgid "Unknown"
msgstr "Desconocido"
@ -749,10 +747,37 @@ msgid "Microphone"
msgstr "Micrófono"
#: ../js/ui/status/volume.js:62
#| msgid "System Settings"
msgid "Sound Settings"
msgstr "Configuración del sonido"
#: ../js/ui/telepathyClient.js:560
#, c-format
msgid "%s is online."
msgstr "%s está conectado/a."
#: ../js/ui/telepathyClient.js:565
#, c-format
msgid "%s is offline."
msgstr "%s está desconectado/a."
#: ../js/ui/telepathyClient.js:568
#, c-format
msgid "%s is away."
msgstr "%s está ausente."
#: ../js/ui/telepathyClient.js:571
#, c-format
msgid "%s is busy."
msgstr "%s está ocupado/a."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:664
#, no-c-format
msgid "Sent at %X on %A"
msgstr "Enviado a las %X el %A"
#: ../js/ui/viewSelector.js:26
msgid "Search your computer"
msgstr "Buscar en su equipo"
@ -800,32 +825,32 @@ msgstr[1] "%u entradas"
msgid "System Sounds"
msgstr "Sonidos del sistema"
#: ../src/shell-global.c:1163
#: ../src/shell-global.c:1155
msgid "Less than a minute ago"
msgstr "Hace menos de un minuto"
#: ../src/shell-global.c:1167
#: ../src/shell-global.c:1159
#, 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:1172
#: ../src/shell-global.c:1164
#, 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:1177
#: ../src/shell-global.c:1169
#, 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:1182
#: ../src/shell-global.c:1174
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
@ -856,6 +881,9 @@ msgstr "Buscar"
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "What's using power..."
#~ msgstr "Lo que está usando energía…"
#~ msgid "Overview workspace view mode"
#~ msgstr "Modo de visualización de la vista previa del área de trabajo"
@ -899,9 +927,6 @@ msgstr "%1$s: %2$s"
#~ msgid "%H:%M"
#~ msgstr "%H:%M"
#~ msgid "Applications"
#~ msgstr "Aplicaciones"
#~ msgid "Recent Documents"
#~ msgstr "Documentos recientes"

236
po/et.po
View File

@ -8,9 +8,9 @@ msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&component=general\n"
"POT-Creation-Date: 2010-10-16 19:24+0000\n"
"PO-Revision-Date: 2010-10-17 17:16+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz gmail com>\n"
"POT-Creation-Date: 2010-12-18 23:05+0000\n"
"PO-Revision-Date: 2010-12-18 11:47+0200\n"
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
"Language-Team: Estonian <gnome-et@linux.ee>\n"
"Language: et\n"
"MIME-Version: 1.0\n"
@ -83,9 +83,6 @@ msgstr "Kui tõene, kuvatakse kalendris kuupäeva ISO nädalate järgi."
msgid "List of desktop file IDs for favorite applications"
msgstr "Lemmikrakenduste töölauafailide ID-de loend"
msgid "Overview workspace view mode"
msgstr ""
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
"used for gst-launch. The pipeline should have an unconnected sink pad where "
@ -125,11 +122,6 @@ msgstr ""
msgid "The gstreamer pipeline used to encode the screencast"
msgstr ""
msgid ""
"The selected workspace view mode in the overview. Supported values are "
"\"single\" and \"grid\"."
msgstr ""
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
@ -270,7 +262,7 @@ msgid "Width of the vertical and horizontal lines that make up the crosshairs."
msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
msgid "Clock Format"
msgstr "Kella formaat"
msgstr "Kellaaja vorming"
msgid "Clock Preferences"
msgstr "Kella eelistused"
@ -290,7 +282,9 @@ msgstr "_12 tunni vorming"
msgid "_24 hour format"
msgstr "_24 tunni vorming"
#. **** Applications ****
msgid "All"
msgstr ""
msgid "APPLICATIONS"
msgstr "Rakendused"
@ -306,9 +300,6 @@ msgstr "Eemalda lemmikutest"
msgid "Add to Favorites"
msgstr "Lisa lemmikutesse"
msgid "Drag here to add favorites"
msgstr "Lemmikute lisamiseks lohista need siia"
#, c-format
msgid "%s has been added to your favorites."
msgstr "%s lisati lemmikutesse."
@ -317,22 +308,9 @@ msgstr "%s lisati lemmikutesse."
msgid "%s has been removed from your favorites."
msgstr "%s eemaldati lemmikutest."
msgid "Find"
msgstr "Otsi"
msgid "Remove"
msgstr ""
msgid "Searching..."
msgstr "Otsimine..."
msgid "No matching results."
msgstr "Tulemused puuduvad."
#. **** Places ****
#. Translators: This is in the sense of locations for documents,
#. network locations, etc.
msgid "PLACES & DEVICES"
msgstr "Asukohad ja seadmed"
#. **** Documents ****
msgid "RECENT ITEMS"
msgstr "Hiljutised dokumendid"
@ -342,6 +320,8 @@ msgstr "Ühtegi laiendust pole paigaldatud"
msgid "Enabled"
msgstr "Lubatud"
#. translators:
#. * The device has been disabled
msgid "Disabled"
msgstr "Keelatud"
@ -360,6 +340,12 @@ msgstr "Veebileht"
msgid "Undo"
msgstr "Võta tagasi"
msgid "Windows"
msgstr "Aknad"
msgid "Applications"
msgstr "Rakendused"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#, c-format
msgid "Quit %s"
@ -415,6 +401,9 @@ msgstr "Proovi uuesti"
msgid "Connect to..."
msgstr "Ühendumine..."
msgid "PLACES & DEVICES"
msgstr "Asukohad ja seadmed"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
@ -436,14 +425,11 @@ msgstr "Saadaval"
msgid "Busy"
msgstr "Hõivatud"
msgid "Invisible"
msgstr "Nähtamatu"
msgid "My Account"
msgstr "Minu konto"
msgid "Account Information..."
msgstr "Konto andmed..."
msgid "System Settings..."
msgstr "Süsteemi sätted..."
msgid "System Settings"
msgstr "Süsteemi sätted"
msgid "Lock Screen"
msgstr "Lukusta ekraan"
@ -454,9 +440,146 @@ msgstr "Vaheta kasutajat"
msgid "Log Out..."
msgstr "Logi välja..."
msgid "Suspend..."
msgstr ""
msgid "Shut Down..."
msgstr "Lülita välja..."
msgid "Zoom"
msgstr ""
msgid "Screen Reader"
msgstr "Ekraanilugeja"
msgid "Screen Keyboard"
msgstr "Ekraaniklaviatuur"
msgid "Visual Alerts"
msgstr "Visuaalsed märguanded"
msgid "Sticky Keys"
msgstr "Kleepuvad klahvid"
msgid "Slow Keys"
msgstr "Aeglased klahvid"
msgid "Bounce Keys"
msgstr ""
msgid "Mouse Keys"
msgstr "Hiireklahvid"
msgid "Universal Access Settings"
msgstr "Universaalse ligipääsu sätted"
msgid "High Contrast"
msgstr ""
msgid "Large Text"
msgstr ""
msgid "Power Settings"
msgstr "Toitesätted..."
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
msgstr[0] ""
msgstr[1] ""
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#, c-format
msgid "%d %s %d %s remaining"
msgstr ""
msgid "hour"
msgid_plural "hours"
msgstr[0] "tund"
msgstr[1] "tundi"
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minut"
msgstr[1] "minutit"
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] ""
msgstr[1] ""
msgid "AC adapter"
msgstr "Võrgutoite adapter"
msgid "Laptop battery"
msgstr "Sülearvuti aku"
msgid "UPS"
msgstr "UPS"
msgid "Monitor"
msgstr "Monitor"
msgid "Mouse"
msgstr "Hiir"
msgid "Keyboard"
msgstr "Klaviatuur"
msgid "PDA"
msgstr ""
msgid "Cell phone"
msgstr "Mobiiltelefon"
msgid "Media player"
msgstr "Meediaesitaja"
msgid "Tablet"
msgstr ""
msgid "Computer"
msgstr "Arvuti"
msgid "Unknown"
msgstr "Tundmatu"
msgid "Volume"
msgstr "Helivaljus"
msgid "Microphone"
msgstr "Mikrofon"
msgid "Sound Settings"
msgstr "Helisätted"
#, c-format
msgid "%s is online."
msgstr "%s on ühendatud."
#, c-format
msgid "%s is offline."
msgstr "%s on ühendamata."
#, c-format
msgid "%s is away."
msgstr "%s on eemal."
#, c-format
msgid "%s is busy."
msgstr "%s on hõivatud."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#, no-c-format
msgid "Sent at %X on %A"
msgstr ""
msgid "Search your computer"
msgstr ""
#, c-format
msgid "%s has finished starting"
msgstr "%s läks käima"
@ -472,6 +595,25 @@ msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
msgid "Can't remove the first workspace."
msgstr "Esimest tööala pole võimalik eemaldada."
#. translators:
#. * The number of sound outputs on a particular device
#, c-format
msgid "%u Output"
msgid_plural "%u Outputs"
msgstr[0] ""
msgstr[1] ""
#. translators:
#. * The number of sound inputs on a particular device
#, c-format
msgid "%u Input"
msgid_plural "%u Inputs"
msgstr[0] ""
msgstr[1] ""
msgid "System Sounds"
msgstr "Süsteemi helid"
msgid "Less than a minute ago"
msgstr "Vähem kui minuti eest"
@ -518,3 +660,21 @@ msgstr "Otsing"
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "Drag here to add favorites"
#~ msgstr "Lemmikute lisamiseks lohista need siia"
#~ msgid "Find"
#~ msgstr "Otsi"
#~ msgid "Searching..."
#~ msgstr "Otsimine..."
#~ msgid "No matching results."
#~ msgstr "Tulemused puuduvad."
#~ msgid "Invisible"
#~ msgstr "Nähtamatu"
#~ msgid "Account Information..."
#~ msgstr "Konto andmed..."

100
po/he.po
View File

@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-13 23:50+0200\n"
"PO-Revision-Date: 2010-12-13 23:52+0200\n"
"POT-Creation-Date: 2010-12-19 01:04+0200\n"
"PO-Revision-Date: 2010-12-19 01:04+0200\n"
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <he@li.org>\n"
"MIME-Version: 1.0\n"
@ -390,23 +390,27 @@ msgstr "מבנה _12 שעות"
msgid "_24 hour format"
msgstr "מבנה _24 שעות"
#: ../js/ui/appDisplay.js:215
#: ../js/ui/appDisplay.js:154
msgid "All"
msgstr "הכול"
#: ../js/ui/appDisplay.js:235
msgid "APPLICATIONS"
msgstr "יישומים"
#: ../js/ui/appDisplay.js:245
#: ../js/ui/appDisplay.js:265
msgid "PREFERENCES"
msgstr "העדפות"
#: ../js/ui/appDisplay.js:542
#: ../js/ui/appDisplay.js:562
msgid "New Window"
msgstr "חלון חדש"
#: ../js/ui/appDisplay.js:546
#: ../js/ui/appDisplay.js:566
msgid "Remove from Favorites"
msgstr "הסרה מהמועדפים"
#: ../js/ui/appDisplay.js:547
#: ../js/ui/appDisplay.js:567
msgid "Add to Favorites"
msgstr "הוספה למועדפים"
@ -458,63 +462,71 @@ msgstr "צפייה במקור"
msgid "Web Page"
msgstr "דף אינטרנט"
#: ../js/ui/overview.js:112
#: ../js/ui/overview.js:96
msgid "Undo"
msgstr "ביטול"
#: ../js/ui/overview.js:158
msgid "Windows"
msgstr "חלונות"
#: ../js/ui/overview.js:161
msgid "Applications"
msgstr "יישומים"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:470
#: ../js/ui/panel.js:474
#, c-format
msgid "Quit %s"
msgstr "יציאה מ־%s"
#: ../js/ui/panel.js:495
#: ../js/ui/panel.js:499
msgid "Preferences"
msgstr "העדפות"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:581
#: ../js/ui/panel.js:585
msgid "%a %b %e, %R:%S"
msgstr "%a %b %e, %R:%S"
#: ../js/ui/panel.js:582
#: ../js/ui/panel.js:586
msgid "%a %b %e, %R"
msgstr "%a %b %e, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:586
#: ../js/ui/panel.js:590
msgid "%a %R:%S"
msgstr "%a %R:%S"
#: ../js/ui/panel.js:587
#: ../js/ui/panel.js:591
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:594
#: ../js/ui/panel.js:598
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %b %e, %l:%M:%S %p"
#: ../js/ui/panel.js:595
#: ../js/ui/panel.js:599
msgid "%a %b %e, %l:%M %p"
msgstr "%a %b %e, %l:%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:599
#: ../js/ui/panel.js:603
msgid "%a %l:%M:%S %p"
msgstr "%a %l:%M:%S %p"
#: ../js/ui/panel.js:600
#: ../js/ui/panel.js:604
msgid "%a %l:%M %p"
msgstr "%a %l:%M %p"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:745
#: ../js/ui/panel.js:749
msgid "Activities"
msgstr "פעילויות"
@ -633,15 +645,11 @@ msgstr "ניגודיות גבוהה"
msgid "Large Text"
msgstr "טקסט גדול"
#: ../js/ui/status/power.js:87
msgid "What's using power..."
msgstr "מה צורך חשמל..."
#: ../js/ui/status/power.js:90
#: ../js/ui/status/power.js:85
msgid "Power Settings"
msgstr "הגדרות צריכת החשמל"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:112
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -650,26 +658,26 @@ msgstr[1] "נותרו %d שעות"
msgstr[2] "נותרו שעתיים"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:115
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s נותרו"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:117
msgid "hour"
msgid_plural "hours"
msgstr[0] "שעה"
msgstr[1] "שעות"
msgstr[2] "שעתיים"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:117
msgid "minute"
msgid_plural "minutes"
msgstr[0] "דקה"
msgstr[1] "דקות"
msgstr[2] "דקות"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:120
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
@ -677,51 +685,51 @@ msgstr[0] "דקה אחת נותרה"
msgstr[1] "%d דקות נותרו"
msgstr[2] "שתי דקות נותרו"
#: ../js/ui/status/power.js:244
#: ../js/ui/status/power.js:237
msgid "AC adapter"
msgstr "מתאם חשמל"
#: ../js/ui/status/power.js:246
#: ../js/ui/status/power.js:239
msgid "Laptop battery"
msgstr "סוללת נייד"
#: ../js/ui/status/power.js:248
#: ../js/ui/status/power.js:241
msgid "UPS"
msgstr "אל־פסק"
#: ../js/ui/status/power.js:250
#: ../js/ui/status/power.js:243
msgid "Monitor"
msgstr "צג"
#: ../js/ui/status/power.js:252
#: ../js/ui/status/power.js:245
msgid "Mouse"
msgstr "עכבר"
#: ../js/ui/status/power.js:254
#: ../js/ui/status/power.js:247
msgid "Keyboard"
msgstr "מקלדת"
#: ../js/ui/status/power.js:256
#: ../js/ui/status/power.js:249
msgid "PDA"
msgstr "מחשב כף יד"
#: ../js/ui/status/power.js:258
#: ../js/ui/status/power.js:251
msgid "Cell phone"
msgstr "טלפון סלולרי"
#: ../js/ui/status/power.js:260
#: ../js/ui/status/power.js:253
msgid "Media player"
msgstr "נגן מדיה"
#: ../js/ui/status/power.js:262
#: ../js/ui/status/power.js:255
msgid "Tablet"
msgstr "טבלת שליטה"
#: ../js/ui/status/power.js:264
#: ../js/ui/status/power.js:257
msgid "Computer"
msgstr "מחשב"
#: ../js/ui/status/power.js:266 ../src/shell-app-system.c:1012
#: ../js/ui/status/power.js:259 ../src/shell-app-system.c:1012
msgid "Unknown"
msgstr "לא ידוע"
@ -760,8 +768,8 @@ msgstr "%s עסוק/ה."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:663
#, c-format
#: ../js/ui/telepathyClient.js:664
#, no-c-format
msgid "Sent at %X on %A"
msgstr "נשלח ב־%X בשעה %A"
@ -872,6 +880,9 @@ msgstr "חיפוש"
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "What's using power..."
#~ msgstr "מה צורך חשמל..."
#~ msgid "Overview workspace view mode"
#~ msgstr "Overview workspace view mode"
@ -918,9 +929,6 @@ msgstr "%1$s: %2$s"
#~ msgid "%H:%M"
#~ msgstr "%H:%M"
#~ msgid "Applications"
#~ msgstr "יישומים"
#~ msgid "Recent Documents"
#~ msgstr "מסמכים אחרונים"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 2.91.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-12-06 19:04+0100\n"
"PO-Revision-Date: 2010-12-06 19:06+0100\n"
"POT-Creation-Date: 2010-12-17 14:18+0100\n"
"PO-Revision-Date: 2010-12-17 14:19+0100\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
@ -393,10 +393,18 @@ msgstr "Vis kildekode"
msgid "Web Page"
msgstr "Nettside"
#: ../js/ui/overview.js:112
#: ../js/ui/overview.js:96
msgid "Undo"
msgstr "Angre"
#: ../js/ui/overview.js:158
msgid "Windows"
msgstr "Vinduer"
#: ../js/ui/overview.js:161
msgid "Applications"
msgstr "Programmer"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:470
#, c-format
@ -568,15 +576,15 @@ msgstr "Høy kontrast"
msgid "Large Text"
msgstr "Stor tekst"
#: ../js/ui/status/power.js:87
#: ../js/ui/status/power.js:85
msgid "What's using power..."
msgstr "Hva bruker strøm..."
#: ../js/ui/status/power.js:90
#: ../js/ui/status/power.js:88
msgid "Power Settings"
msgstr "Innstillinger for strøm"
#: ../js/ui/status/power.js:117
#: ../js/ui/status/power.js:115
#, c-format
msgid "%d hour remaining"
msgid_plural "%d hours remaining"
@ -584,75 +592,75 @@ msgstr[0] "%d time gjenstår"
msgstr[1] "%d timer gjenstår"
#. TRANSLATORS: this is a time string, as in "%d hours %d minutes remaining"
#: ../js/ui/status/power.js:120
#: ../js/ui/status/power.js:118
#, c-format
msgid "%d %s %d %s remaining"
msgstr "%d %s %d %s gjenstår"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:120
msgid "hour"
msgid_plural "hours"
msgstr[0] "time"
msgstr[1] "timer"
#: ../js/ui/status/power.js:122
#: ../js/ui/status/power.js:120
msgid "minute"
msgid_plural "minutes"
msgstr[0] "minutt"
msgstr[1] "minutter"
#: ../js/ui/status/power.js:125
#: ../js/ui/status/power.js:123
#, c-format
msgid "%d minute remaining"
msgid_plural "%d minutes remaining"
msgstr[0] "%d minutt gjenstår"
msgstr[1] "%d minutter gjenstår"
#: ../js/ui/status/power.js:244
#: ../js/ui/status/power.js:240
msgid "AC adapter"
msgstr "Strømadapter"
#: ../js/ui/status/power.js:246
#: ../js/ui/status/power.js:242
msgid "Laptop battery"
msgstr "Batteri på bærbar"
#: ../js/ui/status/power.js:248
#: ../js/ui/status/power.js:244
msgid "UPS"
msgstr "UPS"
#: ../js/ui/status/power.js:250
#: ../js/ui/status/power.js:246
msgid "Monitor"
msgstr "Skjerm"
#: ../js/ui/status/power.js:252
#: ../js/ui/status/power.js:248
msgid "Mouse"
msgstr "Mus"
#: ../js/ui/status/power.js:254
#: ../js/ui/status/power.js:250
msgid "Keyboard"
msgstr "Tastatur"
#: ../js/ui/status/power.js:256
#: ../js/ui/status/power.js:252
msgid "PDA"
msgstr "PDA"
#: ../js/ui/status/power.js:258
#: ../js/ui/status/power.js:254
msgid "Cell phone"
msgstr "Mobiltelefon"
#: ../js/ui/status/power.js:260
#: ../js/ui/status/power.js:256
msgid "Media player"
msgstr "Medieavspiller"
#: ../js/ui/status/power.js:262
#: ../js/ui/status/power.js:258
msgid "Tablet"
msgstr "Nettbrett"
#: ../js/ui/status/power.js:264
#: ../js/ui/status/power.js:260
msgid "Computer"
msgstr "Datamaskin"
#: ../js/ui/status/power.js:266 ../src/shell-app-system.c:1012
#: ../js/ui/status/power.js:262 ../src/shell-app-system.c:1012
msgid "Unknown"
msgstr "Ukjent"
@ -668,6 +676,34 @@ msgstr "Mikrofon"
msgid "Sound Settings"
msgstr "Innstillinger for lyd"
#: ../js/ui/telepathyClient.js:560
#, c-format
msgid "%s is online."
msgstr "%s er tilkoblet."
#: ../js/ui/telepathyClient.js:565
#, c-format
msgid "%s is offline."
msgstr "%s er frakoblet."
#: ../js/ui/telepathyClient.js:568
#, c-format
msgid "%s is away."
msgstr "«%s» er borte."
#: ../js/ui/telepathyClient.js:571
#, c-format
msgid "%s is busy."
msgstr "%s er opptatt."
#. Translators: this is a time format string followed by a date.
#. If applicable, replace %X with a strftime format valid for your
#. locale, without seconds.
#: ../js/ui/telepathyClient.js:664
#, no-c-format
msgid "Sent at %X on %A"
msgstr "Sendt %X på %A"
#: ../js/ui/viewSelector.js:26
msgid "Search your computer"
msgstr "Søk på din datamaskin"
@ -715,32 +751,32 @@ msgstr[1] "%u innganger"
msgid "System Sounds"
msgstr "Systemlyder"
#: ../src/shell-global.c:1163
#: ../src/shell-global.c:1155
msgid "Less than a minute ago"
msgstr "Mindre enn ett minutt siden"
#: ../src/shell-global.c:1167
#: ../src/shell-global.c:1159
#, 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:1172
#: ../src/shell-global.c:1164
#, 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:1177
#: ../src/shell-global.c:1169
#, 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:1182
#: ../src/shell-global.c:1174
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"

View File

@ -218,10 +218,12 @@ libgnome_shell_la_LIBADD = \
-lm \
$(MUTTER_PLUGIN_LIBS) \
$(LIBGNOMEUI_LIBS) \
$(BLUETOOTH_LIBS) \
libst-1.0.la \
libgdmuser-1.0.la \
libtray.la \
libgvc.la
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
typelibdir = $(pkglibdir)

View File

@ -357,6 +357,10 @@ gnome_shell_plugin_start (MetaPlugin *plugin)
"GL buffer swap complete event received (with timestamp of completion)",
"x");
#if HAVE_BLUETOOTH
g_irepository_prepend_search_path (BLUETOOTH_DIR);
#endif
g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
shell_js = g_getenv("GNOME_SHELL_JS");
@ -364,7 +368,10 @@ gnome_shell_plugin_start (MetaPlugin *plugin)
shell_js = JSDIR;
search_path = g_strsplit(shell_js, ":", -1);
shell_plugin->gjs_context = gjs_context_new_with_search_path(search_path);
shell_plugin->gjs_context = g_object_new (GJS_TYPE_CONTEXT,
"search-path", search_path,
"js-version", "1.8",
NULL);
g_strfreev(search_path);
/* Disable the gnome-volume-control debug */

View File

@ -1183,9 +1183,7 @@ on_sliced_image_loaded (GObject *source_object,
{
ClutterActor *actor = load_from_pixbuf (GDK_PIXBUF (list->data));
clutter_actor_hide (actor);
clutter_container_add_actor (CLUTTER_CONTAINER (data->group), actor);
g_object_unref (list->data);
}
}
@ -1198,6 +1196,17 @@ on_data_destroy (gpointer data)
g_free (d);
}
static void
free_glist_unref_gobjects (gpointer p)
{
GList *list = p;
GList *iter;
for (iter = list; iter; iter = iter->next)
g_object_unref (iter->data);
g_list_free (list);
}
static void
load_sliced_image (GSimpleAsyncResult *result,
GObject *object,
@ -1223,17 +1232,14 @@ load_sliced_image (GSimpleAsyncResult *result,
for (x = 0; x < width; x += data->grid_height)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y, data->grid_width, data->grid_height);
if (!pixbuf)
{
g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
"Has failed thumbnail");
break;
}
g_assert (pixbuf != NULL);
res = g_list_append (res, pixbuf);
}
}
if (res)
g_simple_async_result_set_op_res_gpointer (result, res, (GDestroyNotify)g_list_free);
/* We don't need the original pixbuf anymore, though the subpixbufs
will hold a reference. */
g_object_unref (pix);
g_simple_async_result_set_op_res_gpointer (result, res, free_glist_unref_gobjects);
}
/**

View File

@ -10,15 +10,18 @@ let stage = Clutter.Stage.get_default();
stage.width = 640;
stage.height = 480;
let vbox = new St.BoxLayout({ vertical: true,
width: stage.width,
let vbox = new St.BoxLayout({ width: stage.width,
height: stage.height,
style: 'padding: 10px;'
+ 'spacing: 20px;'
+ 'background: #ffee88;' });
style: 'background: #ffee88;' });
stage.add_actor(vbox);
let scroll = new St.ScrollView();
scroll.add_actor(vbox);
stage.add_actor(scroll);
vbox.add(scroll, { expand: true });
let box = new St.BoxLayout({ vertical: true,
style: 'padding: 10px;'
+ 'spacing: 20px;' });
scroll.add_actor(box);
function addTestCase(radii, useGradient) {
let background;
@ -29,7 +32,7 @@ function addTestCase(radii, useGradient) {
else
background = 'background: white;';
vbox.add(new St.Label({ text: "border-radius: " + radii + ";",
box.add(new St.Label({ text: "border-radius: " + radii + ";",
style: 'border: 1px solid black; '
+ 'border-radius: ' + radii + ';'
+ 'padding: 5px;' + background }),

View File

@ -10,61 +10,64 @@ let stage = Clutter.Stage.get_default();
stage.width = 640;
stage.height = 480;
let vbox = new St.BoxLayout({ vertical: true,
width: stage.width,
let vbox = new St.BoxLayout({ width: stage.width,
height: stage.height,
style: 'padding: 10px;'
+ 'spacing: 20px;'
+ 'background: #ffee88;' });
let scroll = new St.ScrollView();
scroll.add_actor(vbox);
stage.add_actor(scroll);
style: 'background: #ffee88;' });
stage.add_actor(vbox);
vbox.add(new St.Label({ text: "Hello World",
let scroll = new St.ScrollView();
vbox.add(scroll, { expand: true });
let box = new St.BoxLayout({ vertical: true,
style: 'padding: 10px;'
+ 'spacing: 20px;' });
scroll.add_actor(box);
box.add(new St.Label({ text: "Hello World",
style: 'border: 1px solid black; '
+ 'padding: 5px;' }));
vbox.add(new St.Label({ text: "Hello Round World",
box.add(new St.Label({ text: "Hello Round World",
style: 'border: 3px solid green; '
+ 'border-radius: 8px; '
+ 'padding: 5px;' }));
vbox.add(new St.Label({ text: "Hello Background",
box.add(new St.Label({ text: "Hello Background",
style: 'border: 3px solid green; '
+ 'border-radius: 8px; '
+ 'background: white; '
+ 'padding: 5px;' }));
vbox.add(new St.Label({ text: "Hello Translucent Black Border",
box.add(new St.Label({ text: "Hello Translucent Black Border",
style: 'border: 3px solid rgba(0, 0, 0, 0.4); '
+ 'background: white; ' }));
vbox.add(new St.Label({ text: "Hello Translucent Background",
box.add(new St.Label({ text: "Hello Translucent Background",
style: 'background: rgba(255, 255, 255, 0.3);' }));
vbox.add(new St.Label({ text: "Border, Padding, Content: 20px" }));
box.add(new St.Label({ text: "Border, Padding, Content: 20px" }));
let b1 = new St.BoxLayout({ vertical: true,
style: 'border: 20px solid black; '
+ 'background: white; '
+ 'padding: 20px;' });
vbox.add(b1);
box.add(b1);
b1.add(new St.BoxLayout({ width: 20, height: 20,
style: 'background: black' }));
vbox.add(new St.Label({ text: "Translucent big blue border, with rounding",
box.add(new St.Label({ text: "Translucent big blue border, with rounding",
style: 'border: 20px solid rgba(0, 0, 255, 0.2); '
+ 'border-radius: 10px; '
+ 'background: white; '
+ 'padding: 10px;' }));
vbox.add(new St.Label({ text: "Transparent border",
box.add(new St.Label({ text: "Transparent border",
style: 'border: 20px solid transparent; '
+ 'background: white; '
+ 'padding: 10px;' }));
vbox.add(new St.Label({ text: "Border Image",
box.add(new St.Label({ text: "Border Image",
style_class: "border-image",
style: "padding: 10px;" }));

View File

@ -230,6 +230,7 @@
<dep package="gnome-icon-theme-symbolic"/>
<dep package="libcanberra"/>
<dep package="gnome-settings-daemon"/>
<dep package="gnome-bluetooth"/>
</dependencies>
</autotools>
@ -251,6 +252,15 @@
</dependencies>
</metamodule>
<autotools id="gnome-bluetooth" autogenargs="--disable-nautilus-sendto">
<branch repo="git.gnome.org" module="gnome-bluetooth" />
<dependencies>
<dep package="gobject-introspection"/>
<dep package="gnome-control-center"/>
<dep package="libnotify"/>
</dependencies>
</autotools>
<tarball id="polkit" version="0.99">
<source href="http://hal.freedesktop.org/releases/polkit-0.99.tar.gz"
hash="sha256:f612c7c26ec822f67751420057a4ae113fc50ab51070758faacf2ad30bb3583f"