mirror of
https://github.com/gosticks/PaperWM.git
synced 2026-10-05 19:56:53 +00:00
339 lines
10 KiB
JavaScript
339 lines
10 KiB
JavaScript
/*
|
|
Functionality related to the top bar, often called the statusbar.
|
|
*/
|
|
|
|
var Extension = imports.misc.extensionUtils.extensions['paperwm@hedning:matrix.org'];
|
|
var Meta = imports.gi.Meta;
|
|
var St = imports.gi.St;
|
|
var Gio = imports.gi.Gio;
|
|
var PanelMenu = imports.ui.panelMenu;
|
|
var PopupMenu = imports.ui.popupMenu;
|
|
var Clutter = imports.gi.Clutter;
|
|
var Main = imports.ui.main;
|
|
var Tweener = imports.ui.tweener;
|
|
|
|
var Tiling = Extension.imports.tiling;
|
|
|
|
var prefs = Extension.imports.prefs.prefs;
|
|
|
|
var panelBox = Main.layoutManager.panelBox;
|
|
|
|
var screen = global.screen;
|
|
|
|
|
|
// From https://developer.gnome.org/hig-book/unstable/design-color.html.en
|
|
var colors = [
|
|
'#9DB8D2', '#7590AE', '#4B6983', '#314E6C',
|
|
'#EAE8E3', '#BAB5AB', '#807D74', '#565248',
|
|
'#C5D2C8', '#83A67F', '#5D7555', '#445632',
|
|
'#E0B6AF', '#C1665A', '#884631', '#663822',
|
|
'#ADA7C8', '#887FA3', '#625B81', '#494066',
|
|
'#EFE0CD', '#E0C39E', '#B39169', '#826647',
|
|
'#DF421E', '#990000', '#EED680', '#D1940C',
|
|
'#46A046', '#267726', '#ffffff', '#000000'
|
|
];
|
|
|
|
class PopupMenuEntry {
|
|
constructor (text, label) {
|
|
this.actor = new St.Entry({text});
|
|
this.entry = this.actor;
|
|
this.actor.set_style('margin: 4px 0 4px 0');
|
|
|
|
this.button = new St.Button({label,
|
|
style_class: 'modal-dialog-button button'});
|
|
this.actor.set_secondary_icon(this.button);
|
|
|
|
this.entry.clutter_text.set_activatable(true);
|
|
this.entry.clutter_text.connect('activate', () => {
|
|
this.button.emit('clicked', null);
|
|
});
|
|
}
|
|
}
|
|
|
|
class Color {
|
|
constructor(color, container) {
|
|
this.container = container;
|
|
this.color = color;
|
|
this.actor = new St.Button();
|
|
let icon = new St.Widget();
|
|
this.actor.add_actor(icon);
|
|
icon.set_style(`background: ${color}`);
|
|
icon.set_size(20, 20);
|
|
icon.set_position(4, 4);
|
|
this.actor.set_size(24, 24);
|
|
|
|
this.actor.connect('clicked', this.clicked.bind(this));
|
|
}
|
|
|
|
clicked() {
|
|
this.container.entry.actor.text = this.color;
|
|
this.container.clicked();
|
|
}
|
|
}
|
|
|
|
class ColorEntry {
|
|
constructor() {
|
|
this.actor = new St.BoxLayout({vertical: true});
|
|
|
|
let flowbox = new St.Widget();
|
|
let flowLayout = new Clutter.FlowLayout();
|
|
let flow = new St.Widget();
|
|
flowbox.add_actor(flow);
|
|
flow.layout_manager = flowLayout;
|
|
flow.width = 24*16;
|
|
for (let c of colors) {
|
|
flow.add_actor(new Color(c, this).actor);
|
|
}
|
|
|
|
this.entry = new PopupMenuEntry('', 'Set color');
|
|
this.entry.actor.clutter_text.connect(
|
|
'text-changed', () => {
|
|
let color = this.entry.actor.text;
|
|
this.entry.actor.set_style(`color: ${color}; `);
|
|
});
|
|
|
|
this.entry.button.connect('clicked', this.clicked.bind(this));
|
|
|
|
this.actor.add_actor(this.entry.actor);
|
|
this.actor.add_actor(flowbox);
|
|
}
|
|
|
|
clicked() {
|
|
let index = global.screen.get_active_workspace_index();
|
|
var settings = Extension.imports.convenience.getSettings();
|
|
let colors = prefs.workspace_colors;
|
|
|
|
if (index >= colors.length) {
|
|
for (let i=colors.length; i < index; i++) {
|
|
colors[i] = '';
|
|
}
|
|
}
|
|
|
|
let color = this.entry.actor.text;
|
|
colors[index] = color;
|
|
settings.set_strv('workspace-colors', colors);
|
|
|
|
let space = Tiling.spaces.spaceOf(global.screen.get_active_workspace());
|
|
space.setColor(color);
|
|
}
|
|
}
|
|
|
|
class WorkspaceMenu extends PanelMenu.Button {
|
|
constructor(panel) {
|
|
super(0.5, 'WorkspaceMenu', false);
|
|
|
|
this.actor.name = 'workspace-button';
|
|
|
|
this._label = new St.Label({
|
|
text: Meta.prefs_get_workspace_name(global.screen.get_active_workspace_index()),
|
|
y_align: Clutter.ActorAlign.CENTER });
|
|
|
|
this.actor.add_actor(this._label);
|
|
|
|
this._workspaceSwitchedSignal = global.screen.connect(
|
|
'workspace-switched', this.workspaceSwitched.bind(this));
|
|
|
|
this.entry = new PopupMenuEntry(this._label.text, 'Set name');
|
|
function clicked() {
|
|
let settings = new Gio.Settings({
|
|
schema_id: 'org.gnome.desktop.wm.preferences'});
|
|
let name = this.entry.text;
|
|
let index = global.screen.get_active_workspace_index();
|
|
let names = settings.get_strv('workspace-names');
|
|
|
|
if (index >= names.length) {
|
|
// workspace-names can't contain undefined names
|
|
// Set the missing names to the default name.
|
|
for(let i = names.length; i < index; i++) {
|
|
names[i] = Meta.prefs_get_workspace_name(i);
|
|
}
|
|
}
|
|
|
|
names[index] = name;
|
|
settings.set_strv('workspace-names', names);
|
|
}
|
|
this.entry.button.connect('clicked', clicked.bind(this.entry));
|
|
|
|
this.colors = new ColorEntry();
|
|
|
|
this.contentBox = new St.BoxLayout({vertical: true});
|
|
this.contentBox.layout_manager.spacing = 10;
|
|
this.contentBox.set_style('margin: 10px 20px;');
|
|
this.contentBox.add_actor(this.entry.actor);
|
|
this.contentBox.add_actor(this.colors.actor);
|
|
this.menu.box.add_actor(this.contentBox);
|
|
|
|
this.entry.actor.width = this.colors.actor.width;
|
|
this.colors.entry.actor.width = this.colors.actor.width;
|
|
}
|
|
|
|
namesChanged(settings, key) {
|
|
if (key !== 'workspace-names')
|
|
return;
|
|
let index = global.screen.get_active_workspace_index();
|
|
let name = Meta.prefs_get_workspace_name(index);
|
|
this._label.text = name;
|
|
let space = Tiling.spaces.spaceOf(global.screen.get_active_workspace());
|
|
space.label.text = name;
|
|
}
|
|
|
|
_onOpenStateChanged(menu, open) {
|
|
if (!open)
|
|
return;
|
|
|
|
if (!this.namesChangedId) {
|
|
let settings = new Gio.Settings({
|
|
schema_id: 'org.gnome.desktop.wm.preferences'});
|
|
this.namesChangedId = [
|
|
settings,
|
|
settings.connect('changed', this.namesChanged.bind(this))
|
|
];
|
|
}
|
|
|
|
let index = global.screen.get_active_workspace_index();
|
|
let name = Meta.prefs_get_workspace_name(index);
|
|
let colors = prefs.workspace_colors;
|
|
let color = colors[index % colors.length];
|
|
this.entry.actor.text = name;
|
|
|
|
this.colors.entry.actor.text = color;
|
|
}
|
|
|
|
workspaceSwitched(screen, fromIndex, toIndex) {
|
|
this._label.set_text(Meta.prefs_get_workspace_name(toIndex));
|
|
}
|
|
|
|
destroy() {
|
|
super.destroy();
|
|
global.screen.disconnect(this._workspaceSwitchedSignal);
|
|
if (this.namesChangedId) {
|
|
this.namesChangedId[0].disconnect(this.namesChangedId[1]);
|
|
}
|
|
}
|
|
};
|
|
|
|
var menu;
|
|
var orginalActivitiesText;
|
|
var screenSignals;
|
|
function init () {
|
|
let label = Main.panel.statusArea.activities.actor.first_child;
|
|
orginalActivitiesText = label.text;
|
|
screenSignals = [];
|
|
}
|
|
|
|
var panelBoxShowId, panelBoxHideId;
|
|
function enable () {
|
|
Main.panel.statusArea.activities.actor.hide();
|
|
|
|
menu = new WorkspaceMenu();
|
|
Main.panel.addToStatusArea('WorkspaceMenu', menu, 0, 'left');
|
|
menu.actor.show();
|
|
let id = panelBox.connect('parent-set', (actor) => {
|
|
log(`id: ${id}`);
|
|
actor.disconnect(id);
|
|
updateWorkspaceIndicator(global.screen.get_active_workspace());
|
|
});
|
|
|
|
// Force transparency
|
|
Main.panel.actor.set_style('background-color: rgba(0, 0, 0, 0.35);');
|
|
[Main.panel._rightCorner, Main.panel._leftCorner]
|
|
.forEach(c => c.actor.opacity = 0);
|
|
|
|
screenSignals.push(
|
|
screen.connect_after('workspace-switched',
|
|
(screen, from, to) => {
|
|
updateWorkspaceIndicator(to);
|
|
}));
|
|
|
|
panelBoxShowId = panelBox.connect('show', show);
|
|
panelBoxHideId = panelBox.connect('hide', () => {
|
|
if (global.display.focus_window.fullscreen) {
|
|
hide();
|
|
} else {
|
|
panelBox.show();
|
|
}
|
|
});
|
|
// Update the worksapce name on startup
|
|
updateWorkspaceIndicator(screen.get_active_workspace_index());
|
|
}
|
|
|
|
function disable() {
|
|
menu.destroy();
|
|
Main.panel.statusArea.activities.actor.show();
|
|
Main.panel.actor.set_style('');
|
|
[Main.panel._rightCorner, Main.panel._leftCorner]
|
|
.forEach(c => c.actor.opacity = 255);
|
|
|
|
screenSignals.forEach(id => screen.disconnect(id));
|
|
screenSignals = [];
|
|
|
|
panelBox.scale_y = 1;
|
|
panelBox.disconnect(panelBoxShowId);
|
|
panelBox.disconnect(panelBoxHideId);
|
|
}
|
|
|
|
function show() {
|
|
panelBox.show();
|
|
Tweener.addTween(panelBox, {
|
|
scale_y: 1,
|
|
time: 0.25,
|
|
onOverwrite: () => {
|
|
panelBox.scale_y = 1;
|
|
}
|
|
});
|
|
}
|
|
|
|
function hide() {
|
|
Tweener.addTween(panelBox, {
|
|
scale_y: 0,
|
|
time: 0.25,
|
|
onOverwrite: () => {
|
|
panelBox.scale_y = 0;
|
|
},
|
|
onComplete: () => {
|
|
panelBox.scale_y = 0;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
Override the activities label with the workspace name.
|
|
let workspaceIndex = 0
|
|
*/
|
|
function updateWorkspaceIndicator (workspaceIndex) {
|
|
let name = Meta.prefs_get_workspace_name(workspaceIndex);
|
|
setWorkspaceName(name);
|
|
};
|
|
|
|
function updateIndicatorPosition(workspace) {
|
|
if (!Tiling.spaces)
|
|
return;
|
|
let space = Tiling.spaces.spaceOf(workspace);
|
|
if (!space)
|
|
return;
|
|
if (!menu._label)
|
|
return;
|
|
space.label.show();
|
|
let p = menu._label.get_position();
|
|
let point = new Clutter.Vertex({
|
|
x: p[0],
|
|
y: p[1]
|
|
});
|
|
if (!menu._label || !menu._label.get_parent())
|
|
return;
|
|
let r = menu._label.get_parent().apply_relative_transform_to_point(Main.panel.actor,
|
|
point);
|
|
|
|
space.label.set_position(r.x, r.y);
|
|
}
|
|
|
|
function setWorkspaceName (name) {
|
|
menu._label.text = name;
|
|
}
|
|
|
|
function setMonitor(monitor) {
|
|
let panelBox = Main.layoutManager.panelBox;
|
|
panelBox.set_position(monitor.x, monitor.y);
|
|
panelBox.width = monitor.width;
|
|
}
|