Merge branch 'master' into datetime

This commit is contained in:
David Zeuthen
2010-11-16 09:16:38 -05:00
120 changed files with 6811 additions and 2026 deletions

View File

@ -2,20 +2,7 @@
const DBus = imports.dbus;
// D-Bus utils; should eventually move to gjs.
// https://bugzilla.gnome.org/show_bug.cgi?id=610859
function makeProxyClass(iface) {
let constructor = function() { this._init.apply(this, arguments); };
constructor.prototype._init = function(bus, name, path) {
bus.proxifyObject(this, name, path);
};
DBus.proxifyPrototype(constructor.prototype, iface);
return constructor;
}
// D-Bus utils
function nameToPath(name) {
return '/' + name.replace(/\./g, '/');
};
@ -118,7 +105,7 @@ const ChannelDispatchOperationIface = {
outSignature: '' }
]
};
let ChannelDispatchOperation = makeProxyClass(ChannelDispatchOperationIface);
let ChannelDispatchOperation = DBus.makeProxyClass(ChannelDispatchOperationIface);
const CONNECTION_NAME = TELEPATHY + '.Connection';
const ConnectionIface = {
@ -128,7 +115,7 @@ const ConnectionIface = {
inSignature: 'uu' }
]
};
let Connection = makeProxyClass(ConnectionIface);
let Connection = DBus.makeProxyClass(ConnectionIface);
const ConnectionStatus = {
CONNECTED: 0,
@ -150,7 +137,7 @@ const ConnectionAliasingIface = {
inSignature: 'a(us)' }
]
};
let ConnectionAliasing = makeProxyClass(ConnectionAliasingIface);
let ConnectionAliasing = DBus.makeProxyClass(ConnectionAliasingIface);
const CONNECTION_AVATARS_NAME = CONNECTION_NAME + '.Interface.Avatars';
const ConnectionAvatarsIface = {
@ -174,7 +161,7 @@ const ConnectionAvatarsIface = {
}
]
};
let ConnectionAvatars = makeProxyClass(ConnectionAvatarsIface);
let ConnectionAvatars = DBus.makeProxyClass(ConnectionAvatarsIface);
const CONNECTION_CONTACTS_NAME = CONNECTION_NAME + '.Interface.Contacts';
const ConnectionContactsIface = {
@ -186,7 +173,7 @@ const ConnectionContactsIface = {
}
]
};
let ConnectionContacts = makeProxyClass(ConnectionContactsIface);
let ConnectionContacts = DBus.makeProxyClass(ConnectionContactsIface);
const CONNECTION_REQUESTS_NAME = CONNECTION_NAME + '.Interface.Requests';
const ConnectionRequestsIface = {
@ -215,7 +202,7 @@ const ConnectionRequestsIface = {
}
]
};
let ConnectionRequests = makeProxyClass(ConnectionRequestsIface);
let ConnectionRequests = DBus.makeProxyClass(ConnectionRequestsIface);
const CONNECTION_SIMPLE_PRESENCE_NAME = CONNECTION_NAME + '.Interface.SimplePresence';
const ConnectionSimplePresenceIface = {
@ -234,7 +221,7 @@ const ConnectionSimplePresenceIface = {
inSignature: 'a{u(uss)}' }
]
};
let ConnectionSimplePresence = makeProxyClass(ConnectionSimplePresenceIface);
let ConnectionSimplePresence = DBus.makeProxyClass(ConnectionSimplePresenceIface);
const ConnectionPresenceType = {
UNSET: 0,
@ -264,7 +251,7 @@ const ChannelIface = {
inSignature: '' }
]
};
let Channel = makeProxyClass(ChannelIface);
let Channel = DBus.makeProxyClass(ChannelIface);
const CHANNEL_TEXT_NAME = CHANNEL_NAME + '.Type.Text';
const ChannelTextIface = {
@ -288,7 +275,7 @@ const ChannelTextIface = {
inSignature: 'uuuuus' }
]
};
let ChannelText = makeProxyClass(ChannelTextIface);
let ChannelText = DBus.makeProxyClass(ChannelTextIface);
const ChannelTextMessageType = {
NORMAL: 0,
@ -315,7 +302,7 @@ const ChannelGroupIface = {
inSignature: 'sauauauauuu' }
]
};
let ChannelGroup = makeProxyClass(ChannelGroupIface);
let ChannelGroup = DBus.makeProxyClass(ChannelGroupIface);
const ACCOUNT_MANAGER_NAME = TELEPATHY + '.AccountManager';
const AccountManagerIface = {
@ -330,7 +317,7 @@ const AccountManagerIface = {
inSignature: 'ob' }
]
};
let AccountManager = makeProxyClass(AccountManagerIface);
let AccountManager = DBus.makeProxyClass(AccountManagerIface);
const ACCOUNT_NAME = TELEPATHY + '.Account';
const AccountIface = {
@ -341,7 +328,7 @@ const AccountIface = {
access: 'read' }
]
};
let Account = makeProxyClass(AccountIface);
let Account = DBus.makeProxyClass(AccountIface);
const CHANNEL_DISPATCHER_NAME = TELEPATHY + '.ChannelDispatcher';
const ChannelDispatcherIface = {
@ -352,7 +339,7 @@ const ChannelDispatcherIface = {
outSignature: 'o' }
]
};
let ChannelDispatcher = makeProxyClass(ChannelDispatcherIface);
let ChannelDispatcher = DBus.makeProxyClass(ChannelDispatcherIface);
const CHANNEL_REQUEST_NAME = TELEPATHY + '.ChannelRequest';
const ChannelRequestIface = {
@ -369,4 +356,4 @@ const ChannelRequestIface = {
signature: '' }
]
};
let ChannelRequest = makeProxyClass(ChannelRequestIface);
let ChannelRequest = DBus.makeProxyClass(ChannelRequestIface);

View File

@ -501,11 +501,10 @@ AppWellIcon.prototype = {
}
}));
this._menuManager.addMenu(this._menu, true);
this._menuManager.addMenu(this._menu);
}
this._menu.popup();
this._menuManager.grab();
return false;
},

View File

@ -678,9 +678,8 @@ LookingGlass.prototype = {
let toolbar = new St.BoxLayout({ name: 'Toolbar' });
this.actor.add_actor(toolbar);
let inspectIcon = St.TextureCache.get_default().load_icon_name('gtk-color-picker',
St.IconType.SYMBOLIC,
24);
let inspectIcon = new St.Icon({ icon_name: 'gtk-color-picker',
icon_size: 24 });
toolbar.add_actor(inspectIcon);
inspectIcon.reactive = true;
inspectIcon.connect('button-press-event', Lang.bind(this, function () {
@ -940,7 +939,9 @@ LookingGlass.prototype = {
global.stage.set_key_focus(this._entry);
Tweener.addTween(this.actor, { time: 0.5,
// We inverse compensate for the slow-down so you can change the factor
// through LookingGlass without long waits.
Tweener.addTween(this.actor, { time: 0.5 / St.get_slow_down_factor(),
transition: 'easeOutQuad',
y: this._targetY
});
@ -967,7 +968,7 @@ LookingGlass.prototype = {
Main.popModal(this.actor);
Tweener.addTween(this.actor, { time: 0.5,
Tweener.addTween(this.actor, { time: 0.5 / St.get_slow_down_factor(),
transition: 'easeOutQuad',
y: this._hiddenY,
onComplete: Lang.bind(this, function () {

View File

@ -15,8 +15,8 @@ const MagnifierDBus = imports.ui.magnifierDBus;
const MouseTrackingMode = {
NONE: 0,
CENTERED: 1,
PUSH: 2,
PROPORTIONAL: 3
PROPORTIONAL: 2,
PUSH: 3
};
const ScreenPosition = {
@ -681,7 +681,7 @@ ZoomRegion.prototype = {
* @mode: One of the enum MouseTrackingMode values.
*/
setMouseTrackingMode: function(mode) {
if (mode >= MouseTrackingMode.NONE && mode <= MouseTrackingMode.PROPORTIONAL)
if (mode >= MouseTrackingMode.NONE && mode <= MouseTrackingMode.PUSH)
this._mouseTrackingMode = mode;
},

View File

@ -390,6 +390,7 @@ function pushModal(actor) {
}
modalActorFocusStack.push([actor, curFocus]);
global.stage.set_key_focus(null);
return true;
}

View File

@ -22,10 +22,12 @@ const SUMMARY_TIMEOUT = 1;
const HIDE_TIMEOUT = 0.2;
const LONGER_HIDE_TIMEOUT = 0.6;
const BUTTON_ICON_SIZE = 36;
const MAX_SOURCE_TITLE_WIDTH = 180;
// We delay hiding of the tray if the mouse is within MOUSE_LEFT_ACTOR_THRESHOLD
// range from the point where it left the tray.
const MOUSE_LEFT_ACTOR_THRESHOLD = 20;
const State = {
HIDDEN: 0,
SHOWING: 1,
@ -98,6 +100,7 @@ Notification.prototype = {
this.source = source;
this.urgent = false;
this.expanded = false;
this._useActionIcons = false;
this._customContent = false;
this._bannerBodyText = null;
this._titleFitsInBannerMode = true;
@ -342,9 +345,9 @@ Notification.prototype = {
let button = new St.Button();
if (Gtk.IconTheme.get_default().has_icon(id)) {
if (this._useActionIcons && Gtk.IconTheme.get_default().has_icon(id)) {
button.add_style_class_name('notification-icon-button');
button.child = St.TextureCache.get_default().load_icon_name(id, St.IconType.SYMBOLIC, BUTTON_ICON_SIZE);
button.child = new St.Icon({ icon_name: id });
} else {
button.add_style_class_name('notification-button');
button.label = label;
@ -359,6 +362,10 @@ Notification.prototype = {
this.urgent = urgent;
},
setUseActionIcons: function(useIcons) {
this._useActionIcons = useIcons;
},
_styleChanged: function() {
this._spacing = this.actor.get_theme_node().get_length('spacing-columns');
},
@ -1146,6 +1153,8 @@ MessageTray.prototype = {
if (this._trayLeftTimeoutId) {
Mainloop.source_remove(this._trayLeftTimeoutId);
this._trayLeftTimeoutId = 0;
this._trayLeftMouseX = -1;
this._trayLeftMouseY = -1;
return;
}
@ -1167,6 +1176,14 @@ MessageTray.prototype = {
this._pointerInTray = true;
this._updateState();
} else {
// We record the position of the mouse the moment it leaves the tray. These coordinates are used in
// this._onTrayLeftTimeout() to determine if the mouse has moved far enough during the initial timeout for us
// to consider that the user intended to leave the tray and therefore hide the tray. If the mouse is still
// close to its previous position, we extend the timeout once.
let [x, y, mods] = global.get_pointer();
this._trayLeftMouseX = x;
this._trayLeftMouseY = y;
// We wait just a little before hiding the message tray in case the user quickly moves the mouse back into it.
// We wait for a longer period if the notification popped up where the mouse pointer was already positioned.
// That gives the user more time to mouse away from the notification and mouse back in in order to expand it.
@ -1176,12 +1193,25 @@ MessageTray.prototype = {
},
_onTrayLeftTimeout: function() {
this._useLongerTrayLeftTimeout = false;
this._trayLeftTimeoutId = 0;
this._pointerInTray = false;
this._pointerInSummary = false;
this._updateNotificationTimeout(0);
this._updateState();
let [x, y, mods] = global.get_pointer();
// We extend the timeout once if the mouse moved no further than MOUSE_LEFT_ACTOR_THRESHOLD to either side or up.
// We don't check how far down the mouse moved because any point above the tray, but below the exit coordinate,
// is close to the tray.
if (this._trayLeftMouseX > -1 &&
y > this._trayLeftMouseY - MOUSE_LEFT_ACTOR_THRESHOLD &&
x < this._trayLeftMouseX + MOUSE_LEFT_ACTOR_THRESHOLD &&
x > this._trayLeftMouseX - MOUSE_LEFT_ACTOR_THRESHOLD) {
this._trayLeftMouseX = -1;
this._trayLeftTimeoutId = Mainloop.timeout_add(LONGER_HIDE_TIMEOUT * 1000,
Lang.bind(this, this._onTrayLeftTimeout));
} else {
this._trayLeftTimeoutId = 0;
this._useLongerTrayLeftTimeout = false;
this._pointerInTray = false;
this._pointerInSummary = false;
this._updateNotificationTimeout(0);
this._updateState();
}
return false;
},

View File

@ -150,7 +150,9 @@ NotificationDaemon.prototype = {
let uri = GLib.filename_to_uri(icon, null);
return textureCache.load_uri_async(uri, size, size);
} else
return textureCache.load_icon_name(icon, St.IconType.FULLCOLOR, size);
return new St.Icon({ icon_name: icon,
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
} else if (hints.icon_data) {
let [width, height, rowStride, hasAlpha,
bitsPerSample, nChannels, data] = hints.icon_data;
@ -167,7 +169,9 @@ NotificationDaemon.prototype = {
stockIcon = 'gtk-dialog-error';
break;
}
return textureCache.load_icon_name(stockIcon, St.IconType.FULLCOLOR, size);
return new St.Icon({ icon_name: stockIcon,
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
}
},
@ -294,6 +298,7 @@ NotificationDaemon.prototype = {
}
if (actions.length) {
notification.setUseActionIcons(hints['action-icons'] == true);
for (let i = 0; i < actions.length - 1; i += 2)
notification.addButton(actions[i], actions[i + 1]);
}
@ -317,6 +322,7 @@ NotificationDaemon.prototype = {
GetCapabilities: function() {
return [
'actions',
'action-icons',
'body',
// 'body-hyperlinks',
// 'body-images',
@ -325,7 +331,6 @@ NotificationDaemon.prototype = {
'icon-static',
'persistence',
// 'sound',
'x-gnome-icon-buttons'
];
},

View File

@ -404,9 +404,9 @@ AppMenuButton.prototype = {
},
_onQuit: function() {
if (this._focusedApp == null)
if (this._targetApp == null)
return;
this._focusedApp.request_quit();
this._targetApp.request_quit();
},
_onAppStateChanged: function(tracker, app) {
@ -739,8 +739,9 @@ Panel.prototype = {
/* Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview". */
let label = new St.Label({ text: _("Activities") });
this.button = new St.Clickable({ name: 'panelActivities',
style_class: 'panel-button',
reactive: true });
style_class: 'panel-button',
reactive: true,
can_focus: true });
this.button.set_child(label);
this._leftBox.add(this.button);
@ -892,7 +893,8 @@ Panel.prototype = {
},
_onTrayIconRemoved: function(o, icon) {
this._trayBox.remove_actor(icon);
if (icon.get_parent() != null)
this._trayBox.remove_actor(icon);
},
_addRipple : function(delay, time, startScale, startOpacity, finalScale, finalOpacity) {

View File

@ -1,5 +1,6 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Clutter = imports.gi.Clutter;
const St = imports.gi.St;
const Lang = imports.lang;
const PopupMenu = imports.ui.popupMenu;
@ -13,11 +14,13 @@ Button.prototype = {
_init: function(menuAlignment) {
this.actor = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
this.actor._delegate = this;
this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPress));
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP, /* FIXME */ 0);
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
Main.chrome.addActor(this.menu.actor, { visibleInOverview: true,
@ -29,10 +32,27 @@ Button.prototype = {
this.menu.toggle();
},
_onKeyPress: function(actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.menu.toggle();
return true;
} else if (symbol == Clutter.KEY_Down) {
if (!this.menu.isOpen)
this.menu.toggle();
this.menu.activateFirst();
return true;
} else
return false;
},
_onOpenStateChanged: function(menu, open) {
if (open)
if (open) {
this.actor.add_style_pseudo_class('pressed');
else
let focus = global.stage.get_key_focus();
if (!focus || (focus != this.actor && !menu.contains(focus)))
this.actor.grab_key_focus();
} else
this.actor.remove_style_pseudo_class('pressed');
}
};
@ -61,7 +81,8 @@ SystemStatusButton.prototype = {
this._iconName = iconName;
if (this._iconActor)
this._iconActor.destroy();
this._iconActor = St.TextureCache.get_default().load_icon_name(this._iconName, St.IconType.SYMBOLIC, 24);
this._iconActor = new St.Icon({ icon_name: this._iconName,
style_class: 'system-status-icon' });
this.actor.set_child(this._iconActor);
},

View File

@ -158,7 +158,9 @@ PlacesManager.prototype = {
this._connect = new PlaceInfo('special:connect', _("Connect to..."),
function (size) {
return St.TextureCache.get_default().load_icon_name('applications-internet', St.IconType.FULLCOLOR, size);
return new St.Icon({ icon_name: 'applications-internet',
icon_type: St.IconType.FULLCOLOR,
icon_size: size });
},
function () {
new Shell.Process({ args: ['nautilus-connect-server'] }).run();
@ -432,7 +434,9 @@ DashPlaceDisplayItem.prototype = {
box.add(text, { expand: true, x_fill: true });
if (info.isRemovable()) {
let removeIcon = St.TextureCache.get_default().load_icon_name ('media-eject', St.IconType.FULLCOLOR, PLACES_ICON_SIZE);
let removeIcon = new St.Icon({ icon_name: 'media-eject',
icon_type: St.IconType.FULLCOLOR,
icon_size: PLACES_ICON_SIZE });
let removeIconBox = new St.Clickable({ child: removeIcon,
reactive: true });
box.add(removeIconBox);

View File

@ -58,7 +58,8 @@ PopupBaseMenuItem.prototype = {
hover: true });
this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item',
reactive: params.reactive,
track_hover: params.reactive });
track_hover: params.reactive,
can_focus: params.reactive });
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate', Lang.bind(this, this._allocate));
@ -72,21 +73,39 @@ PopupBaseMenuItem.prototype = {
this.active = false;
if (params.reactive && params.activate) {
this.actor.connect('button-release-event', Lang.bind(this, function (actor, event) {
this.emit('activate', event);
}));
this.actor.connect('button-release-event', Lang.bind(this, this._onButtonReleaseEvent));
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
}
if (params.reactive && params.hover)
this.actor.connect('notify::hover', Lang.bind(this, this._hoverChanged));
this.actor.connect('notify::hover', Lang.bind(this, this._onHoverChanged));
if (params.reactive)
this.actor.connect('key-focus-in', Lang.bind(this, this._onKeyFocusIn));
},
_onStyleChanged: function (actor) {
let themeNode = actor.get_theme_node();
let [found, spacing] = themeNode.get_length('spacing', false);
this._spacing = found ? spacing : 0;
this._spacing = actor.get_theme_node().get_length('spacing');
},
_hoverChanged: function (actor) {
_onButtonReleaseEvent: function (actor, event) {
this.emit('activate', event);
return true;
},
_onKeyPressEvent: function (actor, event) {
let symbol = event.get_key_symbol();
if (symbol == Clutter.KEY_space || symbol == Clutter.KEY_Return) {
this.emit('activate', event);
return true;
}
return false;
},
_onKeyFocusIn: function (actor) {
this.setActive(true);
},
_onHoverChanged: function (actor) {
this.setActive(actor.hover);
},
@ -99,9 +118,10 @@ PopupBaseMenuItem.prototype = {
if (activeChanged) {
this.active = active;
if (active)
if (active) {
this.actor.add_style_pseudo_class('active');
else
this.actor.grab_key_focus();
} else
this.actor.remove_style_pseudo_class('active');
this.emit('active-changed', active);
}
@ -112,10 +132,6 @@ PopupBaseMenuItem.prototype = {
this.emit('destroy');
},
handleKeyPress: function(event) {
return false;
},
// true if non descendant content includes @actor
contains: function(actor) {
return false;
@ -139,20 +155,24 @@ PopupBaseMenuItem.prototype = {
this._children.push({ actor: child,
column: column,
span: span });
this.actor.connect('destroy', Lang.bind(this, function () { this.removeActor(child); }));
this.actor.connect('destroy', Lang.bind(this, function () { this._removeChild(child); }));
this.actor.add_actor(child);
},
removeActor: function(child) {
_removeChild: function(child) {
for (let i = 0; i < this._children.length; i++) {
if (this._children[i].actor == child) {
this._children.splice(i, 1);
this.actor.remove_actor(child);
return;
}
}
},
removeActor: function(child) {
this.actor.remove_actor(child);
this._removeChild(child);
},
setShowDot: function(show) {
if (show) {
if (this._dot)
@ -339,6 +359,8 @@ PopupSliderMenuItem.prototype = {
_init: function(value) {
PopupBaseMenuItem.prototype._init.call(this, { activate: false });
this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The slider value must be a number');
@ -348,7 +370,7 @@ PopupSliderMenuItem.prototype = {
this.addActor(this._slider, 0, -1);
this._slider.connect('repaint', Lang.bind(this, this._sliderRepaint));
this._slider.connect('button-press-event', Lang.bind(this, this._startDragging));
this._slider.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
this.actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
this._releaseId = this._motionId = 0;
this._dragging = false;
@ -484,10 +506,10 @@ PopupSliderMenuItem.prototype = {
return this._value;
},
handleKeyPress: function(event) {
_onKeyPressEvent: function (actor, event) {
let key = event.get_key_symbol();
if (key == Clutter.Right || key == Clutter.Left) {
let delta = key == Clutter.Right ? 0.1 : -0.1;
if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
this._value = Math.max(0, Math.min(this._value + delta, 1));
this._slider.queue_repaint();
this.emit('value-changed', this._value);
@ -544,22 +566,16 @@ PopupImageMenuItem.prototype = {
_init: function (text, iconName) {
PopupBaseMenuItem.prototype._init.call(this);
this._size = 16;
this.label = new St.Label({ text: text });
this.addActor(this.label);
this._imageBin = new St.Bin({ width: this._size, height: this._size });
this.addActor(this._imageBin);
this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
this.addActor(this._icon);
this.setIcon(iconName);
},
setIcon: function(name) {
if (this._imageBin.child)
this._imageBin.child.destroy();
let img = St.TextureCache.get_default().load_icon_name(name, St.IconType.SYMBOLIC, this._size);
this._imageBin.set_child(img);
this._icon.icon_name = name;
}
};
@ -613,6 +629,14 @@ PopupMenu.prototype = {
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;
},
@ -711,12 +735,10 @@ PopupMenu.prototype = {
}
},
open: function(submenu) {
open: function() {
if (this.isOpen)
return;
this.emit('opening');
let primary = global.get_primary_monitor();
// We need to show it now to force an allocation,
@ -732,7 +754,7 @@ PopupMenu.prototype = {
let menuWidth = natWidth, menuHeight = natHeight;
// Position the non-pointing axis
if (submenu) {
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)
@ -765,8 +787,6 @@ PopupMenu.prototype = {
if (!this.isOpen)
return;
this.emit('closing');
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this.actor.reactive = false;
@ -775,7 +795,6 @@ PopupMenu.prototype = {
this.emit('open-state-changed', false);
},
toggle: function() {
if (this.isOpen)
this.close();
@ -783,35 +802,15 @@ PopupMenu.prototype = {
this.open();
},
handleKeyPress: function(event, submenu) {
if (!this.isOpen || (submenu && !this._activeMenuItem))
return false;
if (this._activeMenuItem && this._activeMenuItem.handleKeyPress(event))
_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;
switch (event.get_key_symbol()) {
case Clutter.space:
case Clutter.Return:
if (this._activeMenuItem)
this._activeMenuItem.activate(event);
return true;
case Clutter.Down:
case Clutter.Up:
let items = this._box.get_children().filter(function (child) { return child.visible && child.reactive; });
let current = this._activeMenuItem ? this._activeMenuItem.actor : null;
let direction = event.get_key_symbol() == Clutter.Down ? 1 : -1;
let next = findNextInCycle(items, current, direction);
if (next) {
next._delegate.setActive(true);
return true;
}
break;
case Clutter.Left:
if (submenu) {
this._activeMenuItem.setActive(false);
return true;
}
break;
}
return false;
@ -846,6 +845,7 @@ PopupSubMenuMenuItem.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));
this.label = new St.Label({ text: text });
this.addActor(this.label);
@ -890,7 +890,7 @@ PopupSubMenuMenuItem.prototype = {
setActive: function(active) {
if (this.menu) {
if (active)
this.menu.open(true);
this.menu.open();
else
this.menu.close();
}
@ -898,14 +898,14 @@ PopupSubMenuMenuItem.prototype = {
PopupBaseMenuItem.prototype.setActive.call(this, active);
},
handleKeyPress: function(event) {
_onKeyPressEvent: function(actor, event) {
if (!this.menu)
return false;
if (event.get_key_symbol() == Clutter.Right) {
if (event.get_key_symbol() == Clutter.KEY_Right) {
this.menu.activateFirst();
return true;
}
return this.menu.handleKeyPress(event, true);
return false;
},
contains: function(actor) {
@ -931,6 +931,7 @@ PopupMenuManager.prototype = {
this.grabbed = false;
this._eventCaptureId = 0;
this._keyPressEventId = 0;
this._enterEventId = 0;
this._leaveEventId = 0;
this._activeMenu = null;
@ -938,21 +939,20 @@ PopupMenuManager.prototype = {
this._delayedMenus = [];
},
addMenu: function(menu, noGrab, position) {
addMenu: function(menu, position) {
let menudata = {
menu: menu,
openStateChangeId: menu.connect('open-state-changed', Lang.bind(this, this._onMenuOpenState)),
activateId: menu.connect('activate', Lang.bind(this, this._onMenuActivated)),
destroyId: menu.connect('destroy', Lang.bind(this, this._onMenuDestroy)),
enterId: 0,
buttonPressId: 0
focusId: 0
};
let source = menu.sourceActor;
if (source) {
menudata.enterId = source.connect('enter-event', Lang.bind(this, this._onMenuSourceEnter, menu));
if (!noGrab)
menudata.buttonPressId = source.connect('button-press-event', Lang.bind(this, this._onMenuSourcePress, menu));
menudata.enterId = source.connect('enter-event', Lang.bind(this, function() { this._onMenuSourceEnter(menu); }));
menudata.focusId = source.connect('key-focus-in', Lang.bind(this, function() { this._onMenuSourceEnter(menu); }));
}
if (position == undefined)
@ -976,8 +976,8 @@ PopupMenuManager.prototype = {
if (menudata.enterId)
menu.sourceActor.disconnect(menudata.enterId);
if (menudata.buttonPressId)
menu.sourceActor.disconnect(menudata.buttonPressId);
if (menudata.focusId)
menu.sourceActor.disconnect(menudata.focusId);
this._menus.splice(position, 1);
},
@ -986,6 +986,7 @@ PopupMenuManager.prototype = {
Main.pushModal(this._owner.actor);
this._eventCaptureId = global.stage.connect('captured-event', Lang.bind(this, this._onEventCapture));
this._keyPressEventId = global.stage.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
// captured-event doesn't see enter/leave events
this._enterEventId = global.stage.connect('enter-event', Lang.bind(this, this._onEventCapture));
this._leaveEventId = global.stage.connect('leave-event', Lang.bind(this, this._onEventCapture));
@ -996,24 +997,30 @@ PopupMenuManager.prototype = {
ungrab: function() {
global.stage.disconnect(this._eventCaptureId);
this._eventCaptureId = 0;
global.stage.disconnect(this._keyPressEventId);
this._keyPressEventId = 0;
global.stage.disconnect(this._enterEventId);
this._enterEventId = 0;
global.stage.disconnect(this._leaveEventId);
this._leaveEventId = 0;
Main.popModal(this._owner.actor);
this.grabbed = false;
Main.popModal(this._owner.actor);
},
_onMenuOpenState: function(menu, open) {
if (!open && menu == this._activeMenu)
this._activeMenu = null;
else if (open)
if (open) {
this._activeMenu = menu;
if (!this.grabbed)
this.grab();
} else if (menu == this._activeMenu) {
this._activeMenu = null;
if (this.grabbed)
this.ungrab();
}
},
_onMenuSourceEnter: function(actor, event, menu) {
_onMenuSourceEnter: function(menu) {
if (!this.grabbed || menu == this._activeMenu)
return false;
@ -1023,13 +1030,6 @@ PopupMenuManager.prototype = {
return false;
},
_onMenuSourcePress: function(actor, event, menu) {
if (this.grabbed)
return false;
this.grab();
return false;
},
_onMenuActivated: function(menu, item) {
if (this.grabbed)
this.ungrab();
@ -1086,23 +1086,6 @@ PopupMenuManager.prototype = {
|| (eventType == Clutter.EventType.KEY_PRESS && event.get_key_symbol() == Clutter.Escape)) {
this._closeMenu();
return true;
} else if (eventType == Clutter.EventType.KEY_PRESS
&& this._activeMenu != null
&& this._activeMenu.handleKeyPress(event, false)) {
return true;
} else if (eventType == Clutter.EventType.KEY_PRESS
&& this._activeMenu != null
&& (event.get_key_symbol() == Clutter.Left
|| event.get_key_symbol() == Clutter.Right)) {
let direction = event.get_key_symbol() == Clutter.Right ? 1 : -1;
let pos = this._findMenu(this._activeMenu);
let next = this._menus[mod(pos + direction, this._menus.length)].menu;
if (next != this._activeMenu) {
this._activeMenu.close();
next.open(false);
next.activateFirst();
}
return true;
} else if (activeMenuContains || this._eventIsOnAnyMenuSource(event)) {
return false;
}
@ -1110,9 +1093,32 @@ PopupMenuManager.prototype = {
return true;
},
_onKeyPressEvent: function(actor, event) {
if (!this.grabbed || !this._activeMenu)
return false;
if (!this._eventIsOnActiveMenu(event))
return false;
let symbol = event.get_key_symbol();
if (symbol == Clutter.Left || symbol == Clutter.Right) {
let direction = symbol == Clutter.Right ? 1 : -1;
let pos = this._findMenu(this._activeMenu);
let next = this._menus[mod(pos + direction, this._menus.length)].menu;
if (next != this._activeMenu) {
let oldMenu = this._activeMenu;
this._activeMenu = next;
oldMenu.close();
next.open();
next.activateFirst();
}
return true;
}
return false;
},
_closeMenu: function() {
if (this._activeMenu != null)
this._activeMenu.close();
this.ungrab();
}
};

View File

@ -17,16 +17,18 @@ const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const KEY_A11Y_DIR = "/desktop/gnome/accessibility";
const KEY_STICKY_KEYS_ENABLED = KEY_A11Y_DIR + "/keyboard/stickykeys_enable";
const KEY_BOUNCE_KEYS_ENABLED = KEY_A11Y_DIR + "/keyboard/bouncekeys_enable";
const KEY_SLOW_KEYS_ENABLED = KEY_A11Y_DIR + "/keyboard/slowkeys_enable";
const KEY_MOUSE_KEYS_ENABLED = KEY_A11Y_DIR + "/keyboard/mousekeys_enable";
const A11Y_SCHEMA = "org.gnome.desktop.a11y.keyboard";
const KEY_STICKY_KEYS_ENABLED = "stickykeys-enable";
const KEY_BOUNCE_KEYS_ENABLED = "bouncekeys-enable";
const KEY_SLOW_KEYS_ENABLED = "slowkeys-enable";
const KEY_MOUSE_KEYS_ENABLED = "mousekeys-enable";
const AT_SCREEN_KEYBOARD_SCHEMA = "org.gnome.desktop.default-applications.at.mobility";
const AT_SCREEN_READER_SCHEMA = "org.gnome.desktop.default-applications.at.visual";
const KEY_FONT_DPI = "/desktop/gnome/font_rendering/dpi";
const XSETTINGS_SCHEMA = "org.gnome.settings-daemon.plugins.xsettings";
const KEY_DPI = "dpi";
const DPI_LOW_REASONABLE_VALUE = 50;
const DPI_HIGH_REASONABLE_VALUE = 500;
@ -71,8 +73,6 @@ ATIndicator.prototype = {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'preferences-desktop-accessibility', null);
let client = GConf.Client.get_default();
client.add_dir(KEY_A11Y_DIR, GConf.ClientPreloadType.PRELOAD_ONELEVEL, null);
client.notify_add(KEY_A11Y_DIR, Lang.bind(this, this._keyChanged), null, null);
client.add_dir(KEY_META_DIR, GConf.ClientPreloadType.PRELOAD_ONELEVEL, null);
client.notify_add(KEY_META_DIR, Lang.bind(this, this._keyChanged), null, null);
@ -82,7 +82,7 @@ ATIndicator.prototype = {
let magnifier = this._buildMagItem();
this.menu.addMenuItem(magnifier);
let textZoom = this._buildFontItem(client);
let textZoom = this._buildFontItem();
this.menu.addMenuItem(textZoom);
let screenReader = this._buildItem(_("Screen Reader"), AT_SCREEN_READER_SCHEMA, 'startup');
@ -94,16 +94,16 @@ ATIndicator.prototype = {
let visualBell = this._buildItemGConf(_("Visual Alerts"), client, KEY_VISUAL_BELL);
this.menu.addMenuItem(visualBell);
let stickyKeys = this._buildItemGConf(_("Sticky Keys"), client, KEY_STICKY_KEYS_ENABLED);
let stickyKeys = this._buildItem(_("Sticky Keys"), A11Y_SCHEMA, KEY_STICKY_KEYS_ENABLED);
this.menu.addMenuItem(stickyKeys);
let slowKeys = this._buildItemGConf(_("Slow Keys"), client, KEY_SLOW_KEYS_ENABLED);
let slowKeys = this._buildItem(_("Slow Keys"), A11Y_SCHEMA, KEY_SLOW_KEYS_ENABLED);
this.menu.addMenuItem(slowKeys);
let bounceKeys = this._buildItemGConf(_("Bounce Keys"), client, KEY_BOUNCE_KEYS_ENABLED);
let bounceKeys = this._buildItem(_("Bounce Keys"), A11Y_SCHEMA, KEY_BOUNCE_KEYS_ENABLED);
this.menu.addMenuItem(bounceKeys);
let mouseKeys = this._buildItemGConf(_("Mouse Keys"), client, KEY_MOUSE_KEYS_ENABLED);
let mouseKeys = this._buildItem(_("Mouse Keys"), A11Y_SCHEMA, KEY_MOUSE_KEYS_ENABLED);
this.menu.addMenuItem(mouseKeys);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
@ -189,31 +189,32 @@ ATIndicator.prototype = {
return highContrast;
},
_buildFontItem: function(client) {
let first_gconf_value = client.get_without_default(KEY_FONT_DPI);
let default_value = getDPIFromX();
let first_value = first_gconf_value ? first_gconf_value.get_float() : default_value;
_buildFontItem: function() {
let settings = new Gio.Settings({ schema: XSETTINGS_SCHEMA });
// we assume this never changes (which is not true if resolution
// is changed, but we would need XRandR events for that)
let x_value = getDPIFromX();
let user_value;
function on_get() {
let u_dpi = client.get_float(KEY_FONT_DPI);
let x_dpi = getDPIFromX();
return (u_dpi - (DPI_FACTOR_LARGE * x_dpi) > -1);
user_value = settings.get_double(KEY_DPI);
return (user_value - (DPI_FACTOR_LARGE * x_value) > -1);
}
let initial_setting = on_get();
let default_value = initial_setting ? x_value : user_value;
let widget = this._buildItemExtended(_("Large Text"),
initial_setting,
client.key_is_writable(KEY_FONT_DPI),
settings.is_writable(KEY_DPI),
function (enabled) {
if (enabled)
client.set_float(KEY_FONT_DPI, DPI_FACTOR_LARGE * getDPIFromX());
settings.set_double(KEY_DPI, DPI_FACTOR_LARGE * default_value);
else
client.set_float(KEY_FONT_DPI, (first_value && !initial_setting) ? first_value : default_value);
settings.set_double(KEY_DPI, default_value);
});
this.connect('gconf-changed', function() {
settings.connect('changed::' + KEY_DPI, function() {
let active = on_get();
if (!active)
// setting was modified manually, update it
first_value = client.get_float(KEY_FONT_DPI);
widget.setToggleState(on_get());
default_value = active ? x_value : user_value;
widget.setToggleState(active);
});
return widget;
},

View File

@ -38,7 +38,7 @@ Indicator.prototype = {
this._output = null;
this._outputVolumeId = 0;
this._outputMutedId = 0;
this._outputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Output: Muted"), false);
this._outputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Volume: Muted"), false);
this._outputSwitch.connect('toggled', Lang.bind(this, this._switchToggled, '_output'));
this._outputSlider = new PopupMenu.PopupSliderMenuItem(0);
this._outputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_output'));
@ -52,7 +52,7 @@ Indicator.prototype = {
this._input = null;
this._inputVolumeId = 0;
this._inputMutedId = 0;
this._inputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Input: Muted"), false);
this._inputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Microphone: Muted"), false);
this._inputSwitch.connect('toggled', Lang.bind(this, this._switchToggled, '_input'));
this._inputSlider = new PopupMenu.PopupSliderMenuItem(0);
this._inputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_input'));
@ -61,7 +61,7 @@ Indicator.prototype = {
this.menu.addMenuItem(this._inputSlider);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Sound Preferences"), function() {
this.menu.addAction(_("Sound Settings"), function() {
let p = new Shell.Process({ args: ['gnome-control-center', 'sound'] });
p.run();
});
@ -103,7 +103,7 @@ Indicator.prototype = {
this._mutedChanged (null, null, '_output');
this._volumeChanged (null, null, '_output');
} else {
this._outputSwitch.label.text = _("Output: Muted");
this._outputSwitch.label.text = _("Volume: Muted");
this._outputSwitch.setToggleState(false);
this.setIcon('audio-volume-muted-symbolic');
}
@ -214,9 +214,9 @@ Indicator.prototype = {
_updateLabel: function(property) {
let label;
if (this[property].is_muted)
label = (property == '_output' ? _("Output: Muted") : _("Input: Muted"));
label = (property == '_output' ? _("Volume: Muted") : _("Microphone: Muted"));
else
label = (property == '_output' ? _("Output: %3.0f%%") : _("Input: %3.0f%%")).format(this[property].volume / VOLUME_MAX * 100);
label = (property == '_output' ? _("Volume: %3.0f%%") : _("Microphone: %3.0f%%")).format(this[property].volume / VOLUME_MAX * 100);
this[property+'Switch'].label.text = label;
}
};

View File

@ -9,7 +9,9 @@ const NotificationDaemon = imports.ui.notificationDaemon;
const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'bluetooth-applet': 'bluetooth',
'gnome-volume-control-applet': 'volume',
'gnome-volume-control-applet': 'volume', // renamed to gnome-sound-applet
// when moved to control center
'gnome-sound-applet': 'volume',
'nm-applet': 'network',
'gnome-power-manager': 'battery',
'keyboard': 'keyboard',

View File

@ -43,10 +43,10 @@ StatusMenuButton.prototype = {
box.add(this._iconBox, { y_align: St.Align.MIDDLE, y_fill: false });
let textureCache = St.TextureCache.get_default();
this._availableIcon = textureCache.load_icon_name('user-available', St.IconType.SYMBOLIC, 16);
this._busyIcon = textureCache.load_icon_name('user-busy', St.IconType.SYMBOLIC, 16);
this._invisibleIcon = textureCache.load_icon_name('user-invisible', St.IconType.SYMBOLIC, 16);
this._idleIcon = textureCache.load_icon_name('user-idle', St.IconType.SYMBOLIC, 16);
this._availableIcon = new St.Icon({ icon_name: 'user-available', style_class: 'popup-menu-icon' });
this._busyIcon = new St.Icon({ icon_name: 'user-busy', style_class: 'popup-menu-icon' });
this._invisibleIcon = new St.Icon({ icon_name: 'user-invisible', style_class: 'popup-menu-icon' });
this._idleIcon = new St.Icon({ icon_name: 'user-idle', style_class: 'popup-menu-icon' });
this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
@ -108,11 +108,6 @@ StatusMenuButton.prototype = {
this.menu.addMenuItem(item);
this._presenceItems[GnomeSession.PresenceStatus.BUSY] = item;
item = new PopupMenu.PopupImageMenuItem(_("Invisible"), 'user-invisible', true);
item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.INVISIBLE));
this.menu.addMenuItem(item);
this._presenceItems[GnomeSession.PresenceStatus.INVISIBLE] = item;
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
@ -120,7 +115,7 @@ StatusMenuButton.prototype = {
item.connect('activate', Lang.bind(this, this._onMyAccountActivate));
this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("System Preferences..."));
item = new PopupMenu.PopupMenuItem(_("System Settings..."));
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
this.menu.addMenuItem(item);
@ -147,10 +142,6 @@ StatusMenuButton.prototype = {
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Restart..."));
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
this.menu.addMenuItem(item);
item = new PopupMenu.PopupMenuItem(_("Shut Down..."));
item.connect('activate', Lang.bind(this, this._onShutDownActivate));
this.menu.addMenuItem(item);

View File

@ -347,7 +347,9 @@ ContactManager.prototype = {
let uri = GLib.filename_to_uri(file, null);
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size);
} else {
iconBox.child = textureCache.load_icon_name('stock_person', St.IconType.FULLCOLOR, iconBox._size);
iconBox.child = St.Icon({ icon_name: 'stock_person',
icon_type: St.IconType.FULLCOLOR,
icon_size: iconBox._size });
}
},