You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.3 KiB

/* extension.js
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/* exported init */
const GETTEXT_DOMAIN = 'activities-icon-and-label';
const { Atk, Clutter, GLib, GObject, Meta, Shell, St, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
var BUTTON_DND_ACTIVATION_TIMEOUT = 250;
const ActivitiesIndicator = GObject.registerClass(
class ActivitiesIndicator extends PanelMenu.Button {
_init() {
super._init(0.0, _('Activities Icon and Label'));
this.accessible_role = Atk.Role.TOGGLE_BUTTON;
this.name = 'panelActivities';
/* Translators: If there is no suitable word for "Activities"
in your language, you can use the word for "Overview". */
const box = new St.BoxLayout();
this.add_child(box);
this._icon = new St.Icon({ icon_name: 'calculate',
style_class: 'panel-logo-icon', });
box.add_child(this._icon);
this._label = new St.Label({
text: _('Activities'),
y_align: Clutter.ActorAlign.CENTER,
});
box.add_child(this._label);
this.label_actor = this._label;
this._showingSignal = Main.overview.connect('showing', () => {
this.add_style_pseudo_class('overview');
this.add_accessible_state(Atk.StateType.CHECKED);
});
this._hidingSignal = Main.overview.connect('hiding', () => {
this.remove_style_pseudo_class('overview');
this.remove_accessible_state(Atk.StateType.CHECKED);
});
this._xdndTimeOut = 0;
}
handleDragOver(source, _actor, _x, _y, _time) {
if (source != Main.xdndHandler)
return DND.DragMotionResult.CONTINUE;
if (this._xdndTimeOut != 0)
GLib.source_remove(this._xdndTimeOut);
this._xdndTimeOut = GLib.timeout_add(GLib.PRIORITY_DEFAULT, BUTTON_DND_ACTIVATION_TIMEOUT, () => {
this._xdndToggleOverview();
});
GLib.Source.set_name_by_id(this._xdndTimeOut, '[gnome-shell] this._xdndToggleOverview');
return DND.DragMotionResult.CONTINUE;
}
vfunc_captured_event(event) {
if (event.type() == Clutter.EventType.BUTTON_PRESS ||
event.type() == Clutter.EventType.TOUCH_BEGIN) {
if (!Main.overview.shouldToggleByCornerOrButton())
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
}
vfunc_event(event) {
if (event.type() == Clutter.EventType.TOUCH_END ||
event.type() == Clutter.EventType.BUTTON_RELEASE) {
if (Main.overview.shouldToggleByCornerOrButton())
Main.overview.toggle();
}
return Clutter.EVENT_PROPAGATE;
}
vfunc_key_release_event(keyEvent) {
let symbol = keyEvent.keyval;
if (symbol == Clutter.KEY_Return || symbol == Clutter.KEY_space) {
if (Main.overview.shouldToggleByCornerOrButton()) {
Main.overview.toggle();
return Clutter.EVENT_STOP;
}
}
return Clutter.EVENT_PROPAGATE;
}
_xdndToggleOverview() {
let [x, y] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.REACTIVE, x, y);
if (pickedActor == this && Main.overview.shouldToggleByCornerOrButton())
Main.overview.toggle();
GLib.source_remove(this._xdndTimeOut);
this._xdndTimeOut = 0;
return GLib.SOURCE_REMOVE;
}
_onDestroy() {
if (this._showingSignal) {
Main.overview.disconnect(this._showingSignal);
this._showingSignal = null;
}
if (this._hidingSignal) {
Main.overview.disconnect(this._hidingSignal);
this._hidingSignal = null;
}
if (this._xdndTimeOut) {
GLib.Source.remove(this._xdndTimeOut);
this._xdndTimeOut = null;
}
super.destroy();
}
});
class Extension {
constructor(uuid) {
this._uuid = uuid;
}
enable() {
Main.panel.statusArea['activities'].hide();
this._indicator = new ActivitiesIndicator();
Main.panel.addToStatusArea(this._uuid, this._indicator, 0, 'left');
}
disable() {
this._indicator.destroy();
this._indicator = null;
if (Main.sessionMode.currentMode !== 'unlock-dialog')
Main.panel.statusArea['activities'].show();
}
}
function init(meta) {
return new Extension(meta.uuid);
}