2403fd0680
The specs call for a 2 pixel gap between the panel and its menus, though we need to specify this as 4 pixels, since it's relative to the bottom of the icon/title, not the bottom of the panel (up until now, the point of the menu arrow was actually overlapping the menu's highlight underline). Also, move the gap specification into the CSS, since it makes more sense there. https://bugzilla.gnome.org/show_bug.cgi?id=655627
127 lines
4.5 KiB
JavaScript
127 lines
4.5 KiB
JavaScript
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
const Clutter = imports.gi.Clutter;
|
|
const Gtk = imports.gi.Gtk;
|
|
const St = imports.gi.St;
|
|
|
|
const Lang = imports.lang;
|
|
const PopupMenu = imports.ui.popupMenu;
|
|
const Main = imports.ui.main;
|
|
|
|
function Button(menuAlignment) {
|
|
this._init(menuAlignment);
|
|
}
|
|
|
|
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._onSourceKeyPress));
|
|
this.menu = new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP);
|
|
this.menu.actor.add_style_class_name('panel-menu');
|
|
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
|
|
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
|
|
Main.chrome.addActor(this.menu.actor, { affectsStruts: false });
|
|
this.menu.actor.hide();
|
|
},
|
|
|
|
_onButtonPress: function(actor, event) {
|
|
if (!this.menu.isOpen) {
|
|
// Setting the max-height won't do any good if the minimum height of the
|
|
// menu is higher then the screen; it's useful if part of the menu is
|
|
// scrollable so the minimum height is smaller than the natural height
|
|
let monitor = Main.layoutManager.primaryMonitor;
|
|
this.menu.actor.style = ('max-height: ' +
|
|
Math.round(monitor.height - Main.panel.actor.height) +
|
|
'px;');
|
|
}
|
|
this.menu.toggle();
|
|
},
|
|
|
|
_onSourceKeyPress: 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_Escape && this.menu.isOpen) {
|
|
this.menu.close();
|
|
return true;
|
|
} else if (symbol == Clutter.KEY_Down) {
|
|
if (!this.menu.isOpen)
|
|
this.menu.toggle();
|
|
this.menu.actor.navigate_focus(this.actor, Gtk.DirectionType.DOWN, false);
|
|
return true;
|
|
} else
|
|
return false;
|
|
},
|
|
|
|
_onMenuKeyPress: function(actor, event) {
|
|
let symbol = event.get_key_symbol();
|
|
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
|
|
let focusManager = St.FocusManager.get_for_stage(global.stage);
|
|
let group = focusManager.get_group(this.actor);
|
|
if (group) {
|
|
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
|
|
group.navigate_focus(this.actor, direction, false);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
_onOpenStateChanged: function(menu, open) {
|
|
if (open)
|
|
this.actor.add_style_pseudo_class('active');
|
|
else
|
|
this.actor.remove_style_pseudo_class('active');
|
|
}
|
|
};
|
|
|
|
/* SystemStatusButton:
|
|
*
|
|
* This class manages one System Status indicator (network, keyboard,
|
|
* volume, bluetooth...), which is just a PanelMenuButton with an
|
|
* icon and a tooltip
|
|
*/
|
|
function SystemStatusButton() {
|
|
this._init.apply(this, arguments);
|
|
}
|
|
|
|
SystemStatusButton.prototype = {
|
|
__proto__: Button.prototype,
|
|
|
|
_init: function(iconName,tooltipText) {
|
|
Button.prototype._init.call(this, 0.0);
|
|
this._iconActor = new St.Icon({ icon_name: iconName,
|
|
icon_type: St.IconType.SYMBOLIC,
|
|
style_class: 'system-status-icon' });
|
|
this.actor.set_child(this._iconActor);
|
|
this.setTooltip(tooltipText);
|
|
},
|
|
|
|
setIcon: function(iconName) {
|
|
this._iconActor.icon_name = iconName;
|
|
},
|
|
|
|
setGIcon: function(gicon) {
|
|
this._iconActor.gicon = gicon;
|
|
},
|
|
|
|
setTooltip: function(text) {
|
|
if (text != null) {
|
|
this.tooltip = text;
|
|
this.actor.has_tooltip = true;
|
|
this.actor.tooltip_text = text;
|
|
} else {
|
|
this.actor.has_tooltip = false;
|
|
this.tooltip = null;
|
|
}
|
|
}
|
|
};
|