a few changes for the new release

This commit is contained in:
Tio 2021-05-11 00:03:41 +02:00
parent 4dc2310ed1
commit edb0bf05c1
89 changed files with 2751 additions and 2613 deletions

View File

@ -1,6 +1,7 @@
#sonar sonar-release
>i686 archlinux32-keyring
>multilib gcc-libs-multilib
haveged
acpi
acpid
amd-ucode

View File

@ -1,17 +1,17 @@
#AUR
vdhcoapp
webtorrent-desktop-bin
zafiro-icon-theme
zafiro-icon-theme-git
vimix-kde-git
vimix-gtk-themes-git
kvantum-theme-vimix-git
imageburner
bitmask
gnome-fuzzy-app-search-git
openrgb
#FILES
parole
libreoffice-fresh
@ -32,6 +32,7 @@ deja-dup
flameshot
keepassxc
gnome-weather
mintstick
@ -57,7 +58,7 @@ rebuild-detector
#COMMUNICATE and SHARE
syncthing-gtk
syncthing
qtox
firefox

View File

@ -1,60 +0,0 @@
GRUB_DEFAULT=saved
GRUB_TIMEOUT=5
GRUB_TIMEOUT_STYLE=hidden
GRUB_DISTRIBUTOR="TROMjaro"
GRUB_CMDLINE_LINUX_DEFAULT="quiet udev.log_priority=3"
GRUB_CMDLINE_LINUX=""
# If you want to enable the save default function, uncomment the following
# line, and set GRUB_DEFAULT to saved.
GRUB_SAVEDEFAULT=true
# Preload both GPT and MBR modules so that they are not missed
GRUB_PRELOAD_MODULES="part_gpt part_msdos"
# Uncomment to enable booting from LUKS encrypted devices
#GRUB_ENABLE_CRYPTODISK=y
# Uncomment to use basic console
GRUB_TERMINAL_INPUT=console
# Uncomment to disable graphical terminal
#GRUB_TERMINAL_OUTPUT=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command 'videoinfo'
GRUB_GFXMODE=auto
# Uncomment to allow the kernel use the same resolution used by grub
GRUB_GFXPAYLOAD_LINUX=keep
# Uncomment if you want GRUB to pass to the Linux kernel the old parameter
# format "root=/dev/xxx" instead of "root=/dev/disk/by-uuid/xxx"
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
GRUB_DISABLE_RECOVERY=true
# Uncomment this option to enable os-prober execution in the grub-mkconfig command
GRUB_DISABLE_OS_PROBER=false
# Uncomment and set to the desired menu colors. Used by normal and wallpaper
# modes only. Entries specified as foreground/background.
GRUB_COLOR_NORMAL="light-gray/black"
GRUB_COLOR_HIGHLIGHT="green/black"
# Uncomment one of them for the gfx desired, a image background or a gfxtheme
#GRUB_BACKGROUND="/usr/share/grub/background.png"
#GRUB_THEME="/path/to/gfxtheme"
# Uncomment to get a beep at GRUB start
#GRUB_INIT_TUNE="480 440 1"
# Uncomment to ensure that the root filesystem is mounted read-only so that
# systemd-fsck can run the check automatically. We use 'fsck' by default, which
# needs 'rw' as boot parameter, to avoid delay in boot-time. 'fsck' needs to be
# removed from 'mkinitcpio.conf' to make 'systemd-fsck' work.
# See also Arch-Wiki: https://wiki.archlinux.org/index.php/Fsck#Boot_time_checking
#GRUB_ROOT_FS_RO=true

View File

@ -0,0 +1,110 @@
/* 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
* 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 {boxpointer, main, popupMenu} = imports.ui;
const {Shell} = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
// inspired by tweaks in system menu
// https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/
class Extension {
constructor() {
}
enable() {
this.settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.extensions-in-system-menu");
this.settings.connect("changed::extensions", () => this.updateItems());
this.settings.connect("changed::tweaks", () => this.updateItems());
this.settings.connect("changed::extensions-pos", () => this.updateItems());
this.settings.connect("changed::tweaks-pos", () => this.updateItems());
this.updateItems();
}
disable() {
this.extensionsItem && this.extensionsItem.destroy();
this.extensionsItem = null;
this.tweaksItem && this.tweaksItem.destroy();
this.tweaksItem = null;
this.settings.run_dispose();
this.settings = null;
}
updateItems() {
this.extensionsItem = this.extensionsItem && this.extensionsItem.destroy();
this.tweaksItem = this.tweaksItem && this.tweaksItem.destroy();
const extensionsPos = this.settings.get_int("extensions-pos");
const tweaksPos = this.settings.get_int("tweaks-pos");
const createExtensions = function() {
if (this.settings.get_boolean("extensions"))
this.extensionsItem = this.createSystemMenuItem("org.gnome.Extensions.desktop", extensionsPos);
}
const createTweaks = function() {
if (this.settings.get_boolean("tweaks"))
this.tweaksItem = this.createSystemMenuItem("org.gnome.tweaks.desktop", tweaksPos);
}
if (extensionsPos < tweaksPos)
createExtensions.call(this) || createTweaks.call(this);
else
createTweaks.call(this) || createExtensions.call(this);
}
createSystemMenuItem(appID, pos) {
const app = Shell.AppSystem.get_default().lookup_app(appID);
if (!app)
return this.notifyNotInstalled(appID);
const [name, icon] = [app.get_name(), app.app_info.get_icon().names[0]];
const item = new popupMenu.PopupImageMenuItem(name, icon);
const systemMenu = main.panel.statusArea.aggregateMenu._system;
systemMenu.menu.addMenuItem(item);
systemMenu.menu.moveMenuItem(item, pos);
item.connect("activate", this.onActivate.bind(this, appID));
return item;
}
onActivate(appID) {
const app = Shell.AppSystem.get_default().lookup_app(appID);
if (!app) // app got uninstalled while this extension was active
return this.notifyNotInstalled(appID);
main.overview.hide();
const systemMenu = main.panel.statusArea.aggregateMenu._system;
systemMenu.menu.itemActivated(boxpointer.PopupAnimation.NONE);
app.activate();
}
notifyNotInstalled(appID) {
const missingAppTitle = "Extension & Tweaks in system menu";
const missingAppMsg = `Install the GNOME ${appID.split(".")[2]} app and re-enable this setting`;
log(`--- ${missingAppTitle}: ${missingAppMsg} ---`);
main.notify(missingAppTitle, missingAppMsg);
}
}
function init() {
return new Extension();
}

View File

@ -0,0 +1,14 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "No longer maintained. Starting with GNOME 40 'Tweaks-in-system-menu' also supports the extensions app. Please use that https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/\n\n--------------------\n\nPut the Extensions and/or the Tweaks app into the system menu.",
"name": "Extensions & Tweaks in system menu",
"shell-version": [
"3.36",
"3.38",
"40.0",
"40.beta"
],
"url": "https://github.com/Leleat/extensions-in-system-menu",
"uuid": "extensions-in-system-menu@leleat-on-github",
"version": 6
}

View File

@ -0,0 +1,70 @@
"use strict";
const {Gio, GObject, Gtk} = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const shellVersion = parseFloat(imports.misc.config.PACKAGE_VERSION);
function init() {
}
function buildPrefsWidget() {
const prefsWidget = new PrefsWidget();
shellVersion < 40 && prefsWidget.show_all();
return prefsWidget;
}
const PrefsWidget = GObject.registerClass(
class ExtensionsSystemMenuPrefsWidget extends Gtk.Box {
_init(params) {
super._init(params);
this.builder = new Gtk.Builder();
this.builder.add_from_file(Me.path + "/prefs.ui");
const mainPrefs = this.builder.get_object("main_prefs");
shellVersion < 40 ? this.add(mainPrefs) : this.append(mainPrefs);
const gschema = Gio.SettingsSchemaSource.new_from_directory(Me.dir.get_child("schemas").get_path(), Gio.SettingsSchemaSource.get_default(), false);
const settingsSchema = gschema.lookup("org.gnome.shell.extensions.extensions-in-system-menu", true);
this.settings = new Gio.Settings({settings_schema: settingsSchema});
this.bindWidgetsToSettings(settingsSchema.list_keys());
this.bindWidgetsTogether();
}
bindWidgetsToSettings(keys) {
// widgets in prefs.ui need to have same ID
// as the keys in the gschema.xml file
const getBindProperty = function(key) {
const ints = ["extensions-pos", "tweaks-pos"];
const bools = ["extensions", "tweaks"];
if (ints.includes(key))
return "value"; // Gtk.Spinbox.value
else if (bools.includes(key))
return "active"; // Gtk.Switch.active
else
return null;
};
keys.forEach(key => {
const bindProperty = getBindProperty(key);
const widget = this.builder.get_object(key);
if (widget && bindProperty)
this.settings.bind(key, widget, bindProperty, Gio.SettingsBindFlags.DEFAULT);
});
}
bindWidgetsTogether() {
const extensionsToggle = this.builder.get_object("extensions");
const extensionsPos = this.builder.get_object("extensions-pos-box");
extensionsToggle.bind_property("active", extensionsPos, "sensitive", GObject.BindingFlags.DEFAULT);
const tweaksToggle = this.builder.get_object("tweaks");
const tweaksPos = this.builder.get_object("tweaks-pos-box");
tweaksToggle.bind_property("active", tweaksPos, "sensitive", GObject.BindingFlags.DEFAULT);
}
}
)

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="extensions-adjustment">
<property name="upper">10</property>
<property name="value">1</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkAdjustment" id="tweaks-adjustment">
<property name="upper">10</property>
<property name="value">2</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkBox" id="main_prefs">
<property name="name">main_prefs</property>
<property name="can-focus">1</property>
<property name="margin-start">30</property>
<property name="margin-end">30</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="orientation">vertical</property>
<property name="spacing">15</property>
<property name="baseline-position">top</property>
<child>
<object class="GtkBox" id="extensions-box">
<property name="can-focus">1</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Extensions</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="extensions">
<property name="can-focus">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="extensions-pos-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Extensions position</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="extensions-pos">
<property name="width-request">175</property>
<property name="adjustment">extensions-adjustment</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="tweaks-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Tweaks</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="tweaks">
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="tweaks-pos-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Tweaks position</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="tweaks-pos">
<property name="width-request">175</property>
<property name="adjustment">tweaks-adjustment</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema id="org.gnome.shell.extensions.extensions-in-system-menu" path="/org/gnome/shell/extensions/extensions-in-system-menu/">
<key name="extensions" type="b">
<default>true</default>
</key>
<key name="tweaks" type="b">
<default>false</default>
</key>
<key name="extensions-pos" type="i">
<default>2</default>
</key>
<key name="tweaks-pos" type="i">
<default>3</default>
</key>
</schema>
</schemalist>

View File

@ -1,35 +0,0 @@
'use strict';
// User Menu and Volume Indicator
const AggregateMenu = imports.ui.main.panel.statusArea.aggregateMenu;
const VolumeIndicator = AggregateMenu._volume;
// Scroll Signal Id
var _onScrollEventId = 0;
function init() {
}
function enable() {
// Make the User Menu indicator box reactive so it emits ::scroll-event
AggregateMenu._indicators.reactive = true;
// Connect the same handler from the volume indicator to ::scroll-event
_onScrollEventId = AggregateMenu._indicators.connect(
'scroll-event',
VolumeIndicator.vfunc_scroll_event.bind(VolumeIndicator)
);
}
function disable() {
// Undo the above
if (_onScrollEventId) {
AggregateMenu._indicators.reactive = false;
AggregateMenu._indicators.disconnect(_onScrollEventId);
_onScrollEventId = 0;
}
}

View File

@ -1,12 +0,0 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Change the volume by scrolling anywhere on the System Tray.\n\nWith this extension, you can scroll over Night Light, WiFi, Volume, Battery or any other icon in the system status tray to change the volume, instead of just the Volume icon.",
"extension-id": "scrovol",
"name": "Scrovol",
"shell-version": [
"3.36"
],
"url": "https://github.com/andyholmes/gnome-shell-extension-scrovol/",
"uuid": "scrovol@andyholmes.github.io",
"version": 3
}

View File

@ -1,93 +0,0 @@
/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (c) 2011-2012, Giovanni Campagna <scampa.giovanni@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the GNOME nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = ExtensionUtils.getCurrentExtension();
domain = domain || extension.metadata['gettext-domain'];
// check if this extension was built with "make zip-file", and thus
// has the locale files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and return a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is not provided, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = ExtensionUtils.getCurrentExtension();
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// check if this extension was built with "make zip-file", and thus
// has the schema files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell (and therefore schemas are available
// in the standard folders)
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error('Schema ' + schema + ' could not be found for extension '
+ extension.metadata.uuid + '. Please check your installation.');
return new Gio.Settings({ settings_schema: schemaObj });
}

View File

@ -1,255 +0,0 @@
// tweaks-system-menu - Put Gnome Tweaks in the system menu.
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const Lang = imports.lang;
const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Shell = imports.gi.Shell;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Logger = Me.imports.logger;
const TweaksSystemMenuExtension = class TweaksSystemMenuExtension {
constructor() {
this._logger = null;
this._settings = null;
this._debugSettingChangedConnection = null;
this._positionSettingChangedConnection = null;
this._systemMenu = null;
this._applications = {
'tweaks': {
appName: 'org.gnome.tweaks.desktop',
check: Lang.bind(this, function() {
return true;
}),
getDefaultPosition: Lang.bind(this, function() {
return this._findMenuItemPosition(this._systemMenu._settingsItem)+1;
}),
preUpdatePosition: Lang.bind(this, function () {
if (this._applications['extensions'].menuItem !== undefined) {
this._moveMenuItemToEnd(this._applications['extensions'].menuItem);
}
}),
postUpdatePosition: Lang.bind(this, function () {
if (this._applications['extensions'].menuItem !== undefined) {
this._on_position_change('extensions');
}
})
},
'extensions': {
appName: 'org.gnome.Extensions.desktop',
check: Lang.bind(this, function() {
let gnome_shell_version = imports.misc.config.PACKAGE_VERSION;
let gnome_shell_major = /^([0-9]+)\.([0-9]+)(\.([0-9]+)(\..*)?)?$/.exec(gnome_shell_version)[1];
return gnome_shell_major >= 40;
}),
getDefaultPosition: Lang.bind(this, function() {
if (this._applications['tweaks'].menuItem !== undefined) {
return this._findMenuItemPosition(this._applications['tweaks'].menuItem)+1;
} else {
return this._applications['tweaks'].getDefaultPosition();
}
}),
preUpdatePosition: Lang.bind(this, function () { return; }),
postUpdatePosition: Lang.bind(this, function () { return; })
}
};
this._tweaksApp = null;
this._tweaksItem = null;
this._tweaksActivateConnection = null;
}
// Utilities
_findMenuItemPosition(item) {
let items = this._systemMenu.menu._getMenuItems();
for (let i=0; i < items.length; ++i) {
if (items[i] == item) {
this._logger.log_debug('_findMenuItemPosition('+item+') = '+i);
return i;
}
}
this._logger.log_debug('_findMenuItemPosition('+item+') = <null>');
return null;
}
_moveMenuItemToEnd(item) {
this._systemMenu.menu.moveMenuItem(item, this._systemMenu.menu._getMenuItems().length-1);
}
_getEnableSettingsName(appKey) {
return appKey+'-enable';
}
_getPositionSettingsName(appKey) {
return appKey+'-position';
}
// Enable/disable
enable() {
this._logger = new Logger.Logger('Tweaks-System-Menu');
this._settings = Convenience.getSettings();
this._on_debug_change();
this._logger.log_debug('enable()');
this._debugSettingChangedConnection = this._settings.connect('changed::debug',
this._on_debug_change.bind(this));
this._systemMenu = Main.panel.statusArea.aggregateMenu._system;
for (let appKey in this._applications) {
this._enableApp(appKey);
}
this._logger.log_debug('extension enabled');
}
_enableApp(appKey) {
let appData = this._applications[appKey];
if (! appData.check()) return;
this._logger.log_debug('_enableApp('+appKey+')');
appData.enableSettingChangedConnection = this._settings.connect('changed::'+this._getEnableSettingsName(appKey),
Lang.bind(this, function() {
this._on_enable_change(appKey);
}));
appData.positionSettingChangedConnection = this._settings.connect('changed::'+this._getPositionSettingsName(appKey),
Lang.bind(this, function() {
this._on_position_change(appKey);
}));
if (this._settings.get_boolean(this._getEnableSettingsName(appKey))) {
this._showItem(appKey);
}
}
disable() {
this._logger.log_debug('disable()');
for (let appKey in this._applications) {
this._disableApp(appKey);
}
this._systemMenu = null;
this._settings.disconnect(this._debugSettingChangedConnection);
this._debugSettingChangedConnection = null;
this._settings = null;
this._logger.log_debug('extension disabled');
this._logger = null;
}
_disableApp(appKey) {
let appData = this._applications[appKey];
if (! appData.check()) return;
this._logger.log_debug('_disableApp('+appKey+')');
this._hideItem(appKey);
if (appData.enableSettingChangedConnection !== undefined) {
this._settings.disconnect(appData.enableSettingChangedConnection);
delete appData.enableSettingChangedConnection;
}
if (appData.positionSettingChangedConnection !== undefined) {
this._settings.disconnect(appData.positionSettingChangedConnection);
delete appData.positionSettingChangedConnection;
}
}
// Show/hide item
_showItem(appKey) {
this._logger.log_debug('_showItem('+appKey+')');
let appData = this._applications[appKey];
appData.appInfo = Shell.AppSystem.get_default().lookup_app(appData.appName);
if (appData.appInfo) {
let name = appData.appInfo.get_name();
let icon = appData.appInfo.app_info.get_icon().names[0];
appData.menuItem = new PopupMenu.PopupImageMenuItem(name, icon);
appData.activateConnection = appData.menuItem.connect('activate', Lang.bind(this, function() {
this._on_activate(appKey);
}));
this._systemMenu.menu.addMenuItem(appData.menuItem);
this._on_position_change(appKey);
} else {
this._logger.log(appData.appName+' is missing');
}
}
_hideItem(appKey) {
this._logger.log_debug('_hideItem('+appKey+')');
let appData = this._applications[appKey];
if (appData.menuItem !== undefined) {
appData.menuItem.disconnect(appData.activateConnection);
delete appData.activateConnection;
this._systemMenu.menu._getMenuItems().splice(this._findMenuItemPosition(appData.menuItem), 1);
appData.menuItem.destroy();
delete appData.menuItem;
}
}
// Event handlers
_on_debug_change() {
this._logger.set_debug(this._settings.get_boolean('debug'));
this._logger.log_debug('debug = '+this._logger.get_debug());
}
_on_enable_change(appKey) {
let appData = this._applications[appKey];
let enable = this._settings.get_boolean(this._getEnableSettingsName(appKey));
this._logger.log_debug('_on_enable_change('+appKey+'): enable=' + enable);
if (enable) {
this._showItem(appKey);
} else {
this._hideItem(appKey);
}
}
_on_position_change(appKey) {
let appData = this._applications[appKey];
let position = this._settings.get_int(this._getPositionSettingsName(appKey));
this._logger.log_debug('_on_position_change('+appKey+'): settings position=' + position);
this._moveMenuItemToEnd(appData.menuItem);
appData.preUpdatePosition();
if (position == -1) {
position = appData.getDefaultPosition();
this._logger.log_debug('_on_position_change('+appKey+'): automatic position=' + position);
}
// let curPosition = this._findMenuItemPosition(appData.menuItem);
// if (curPosition < position) {
// position -= 1;
// }
// this._logger.log_debug('_on_position_change('+appKey+'): ajusted position=' + position);
this._systemMenu.menu.moveMenuItem(appData.menuItem, position);
appData.postUpdatePosition();
}
_on_activate(appKey) {
let appData = this._applications[appKey];
this._logger.log_debug('_on_activate('+appKey+')');
this._systemMenu.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
Main.overview.hide();
appData.appInfo.activate();
}
};
function init() {
return new TweaksSystemMenuExtension();
}

View File

@ -1,73 +0,0 @@
// meson-gse - Library for gnome-shell extensions
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const ExtensionUtils = imports.misc.extensionUtils;
const GLib = imports.gi.GLib;
const Me = ExtensionUtils.getCurrentExtension();
var Logger = class MesonGseLogger {
constructor(title) {
this._first_log = true;
this._title = title;
this._debug = false;
}
get_version() {
return Me.metadata['version']+' / git '+Me.metadata['vcs_revision'];
}
log(text) {
if (this._first_log) {
this._first_log = false;
let msg = 'version ' + this.get_version();
let gnomeShellVersion = imports.misc.config.PACKAGE_VERSION;
if (gnomeShellVersion != undefined) {
msg += ' on Gnome-Shell ' + gnomeShellVersion;
}
let gjsVersion = imports.system.version;
if (gjsVersion != undefined) {
let gjsVersionMajor = Math.floor(gjsVersion / 10000);
let gjsVersionMinor = Math.floor((gjsVersion % 10000) / 100);
let gjsVersionPatch = gjsVersion % 100;
msg +=( ' / gjs ' + gjsVersionMajor
+ '.' +gjsVersionMinor
+ '.' +gjsVersionPatch
+ ' ('+gjsVersion+')');
}
let sessionType = GLib.getenv('XDG_SESSION_TYPE');
if (sessionType != undefined) {
msg += ' / ' + sessionType;
}
this.log(msg);
}
log(''+this._title+': '+text);
}
log_debug(text) {
if (this._debug) {
this.log(text);
}
}
set_debug(debug) {
this._debug = debug;
}
get_debug() {
return this._debug;
}
};

View File

@ -1,17 +0,0 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Put Gnome Tweaks and Extensions (on Shell 40 and later) in the System menu.",
"gettext-domain": "tweaks-system-menu",
"name": "Tweaks & Extensions in System Menu",
"settings-schema": "org.gnome.shell.extensions.tweaks-system-menu",
"shell-version": [
"3.36",
"3.35.92",
"3.38",
"40.0"
],
"url": "https://github.com/F-i-f/tweaks-system-menu",
"uuid": "tweaks-system-menu@extensions.gnome-shell.fifi.org",
"vcs_revision": "v15-0-ge3b04c7",
"version": 15
}

View File

@ -1,181 +0,0 @@
// Tweaks-system-menu - Put Gnome Tweaks in the system menu.
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const Logger = Me.imports.logger;
const TweaksSystemMenuSettings = GObject.registerClass(class TweaksSystemMenuSettings extends Gtk.Grid {
_addEntry(ypos, setting_prefix, enable_label_val, position_label_val) {
let enable_setting = setting_prefix + '-enable';
let enable_sschema = this._settings.settings_schema.get_key(enable_setting);
let descr = _(enable_sschema.get_description());
let enable_label = new Gtk.Label({
label: enable_label_val,
halign: Gtk.Align.START
});
enable_label.set_tooltip_text(descr);
let enable_control = new Gtk.Switch({halign: Gtk.Align.END});
enable_control.set_tooltip_text(descr);
this.attach(enable_label, 1, ypos, 1, 1);
this.attach(enable_control, 2, ypos, 1, 1);
this._settings.bind(enable_setting, enable_control,
'active', Gio.SettingsBindFlags.DEFAULT);
ypos += 1
let position_setting = setting_prefix + '-position';
let position_sschema = this._settings.settings_schema.get_key(position_setting);
descr = _(position_sschema.get_description());
let position_label = new Gtk.Label({
label: position_label_val,
halign: Gtk.Align.START,
margin_start: 25
});
position_label.set_tooltip_text(descr);
let position_range = position_sschema.get_range().deep_unpack()[1].deep_unpack()
let position_control = new Gtk.SpinButton({
adjustment: new Gtk.Adjustment({
lower: position_range[0],
upper: position_range[1],
step_increment: 1
}),
halign: Gtk.Align.END
});
position_control.set_tooltip_text(descr);
this.attach(position_label, 1, ypos, 1, 1);
this.attach(position_control, 2, ypos, 1, 1);
this._settings.bind(position_setting, position_control,
'value', Gio.SettingsBindFlags.DEFAULT);
ypos += 1
this._settings.connect('changed::'+enable_setting, Lang.bind(this, function(settings, name) {
let val = settings.get_boolean(name);
position_label.set_sensitive(val);
position_control.set_sensitive(val);
}));
return ypos;
}
setup() {
let gnome_shell_version = imports.misc.config.PACKAGE_VERSION;
let gnome_shell_major = /^([0-9]+)\.([0-9]+)(\.([0-9]+)(\..*)?)?$/.exec(gnome_shell_version)[1];
this.margin_top = 12;
this.margin_bottom = this.margin_top;
this.margin_start = 48;
this.margin_end = this.margin_start;
this.row_spacing = 6;
this.column_spacing = this.row_spacing;
this.orientation = Gtk.Orientation.VERTICAL;
this._settings = Convenience.getSettings();
this._logger = new Logger.Logger('Tweaks-System-Menu/prefs');
this._logger.set_debug(this._settings.get_boolean('debug'));
let ypos = 1;
let descr;
this.title_label = new Gtk.Label({
use_markup: true,
label: '<span size="large" weight="heavy">'
+_('Tweaks &amp; Extensions in System Menu')+'</span>',
hexpand: true,
halign: Gtk.Align.CENTER
});
this.attach(this.title_label, 1, ypos, 2, 1);
ypos += 1;
this.version_label = new Gtk.Label({
use_markup: true,
label: '<span size="small">'+_('Version')
+ ' ' + this._logger.get_version() + '</span>',
hexpand: true,
halign: Gtk.Align.CENTER,
});
this.attach(this.version_label, 1, ypos, 2, 1);
ypos += 1;
this.link_label = new Gtk.Label({
use_markup: true,
label: '<span size="small"><a href="'+Me.metadata.url+'">'
+ Me.metadata.url + '</a></span>',
hexpand: true,
halign: Gtk.Align.CENTER,
margin_bottom: this.margin_bottom
});
this.attach(this.link_label, 1, ypos, 2, 1);
ypos += 1;
ypos = this._addEntry(ypos, 'tweaks', _("Show Tweaks:"), _("Tweaks position:"));
if (gnome_shell_major >= 40) {
ypos = this._addEntry(ypos, 'extensions', _("Show Extensions:"), _("Extensions position:"));
}
descr = _(this._settings.settings_schema.get_key('debug').get_description());
this.debug_label = new Gtk.Label({label: _("Debug:"), halign: Gtk.Align.START});
this.debug_label.set_tooltip_text(descr);
this.debug_control = new Gtk.Switch({halign: Gtk.Align.END});
this.debug_control.set_tooltip_text(descr);
this.attach(this.debug_label, 1, ypos, 1, 1);
this.attach(this.debug_control, 2, ypos, 1, 1);
this._settings.bind('debug', this.debug_control, 'active', Gio.SettingsBindFlags.DEFAULT);
ypos += 1;
this.copyright_label = new Gtk.Label({
use_markup: true,
label: '<span size="small">'
+ _('Copyright © 2019-2021 Philippe Troin (<a href="https://github.com/F-i-f">F-i-f</a> on GitHub)')
+ '</span>',
hexpand: true,
halign: Gtk.Align.CENTER,
margin_top: this.margin_bottom
});
this.attach(this.copyright_label, 1, ypos, 2, 1);
ypos += 1;
}
});
function init() {
Convenience.initTranslations();
}
function buildPrefsWidget() {
let widget = new TweaksSystemMenuSettings();
widget.setup();
// show_all() is only available/necessary on GTK < 4.0.
if (widget.show_all !== undefined) {
widget.show_all();
}
return widget;
}

View File

@ -1,38 +0,0 @@
<schemalist gettext-domain="tweaks-system-menu">
<schema id="org.gnome.shell.extensions.tweaks-system-menu" path="/org/gnome/shell/extensions/tweaks-system-menu/">
<key name="tweaks-enable" type="b">
<default>true</default>
<summary>Tweaks should be shown.</summary>
<description>If set, the Gnome Tweaks button is
shown.</description>
</key>
<key name="tweaks-position" type="i">
<default>-1</default>
<range min="-1" max="99"/>
<summary>Position of the Tweaks button.</summary>
<description>If set to -1, the position is automatic: Tweaks
will show up after Settings. If set to zero or more, the actual
launcher position on the system menu.</description>
</key>
<key name="extensions-enable" type="b">
<default>true</default>
<summary>Extensions should be shown.</summary>
<description>If set, the Shell Extensions button is
shown.</description>
</key>
<key name="extensions-position" type="i">
<default>-1</default>
<range min="-1" max="99"/>
<summary>Position of the Extensions button.</summary>
<description>If set to -1, the position is automatic: Extensions
will show up after Tweaks (if shown), or Settings. If set to
zero or more, the actual launcher position on the system
menu.</description>
</key>
<key name="debug" type="b">
<default>false</default>
<summary>Debugging.</summary>
<description>Enable debugging for the extension.</description>
</key>
</schema>
</schemalist>

View File

@ -17,6 +17,7 @@ var DesktopLabel = GObject.registerClass(
this.label_actor = this._label
this.setText(text || 'Desktop')
this.add_style_class_name('desktop-name-label')
}
setText(text) {
@ -41,6 +42,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' })
this.add_child(this._indicators)
this.add_style_class_name('system-tray-icons')
this._sync()
}
@ -62,7 +64,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators.add_child(ibtn)
icon.connect('destroy', () => { ibtn.destroy() })
ibtn.connect('button-release-event', (actor, event) => { icon.click(event) })
ibtn.connect('button-release-event', (actor, event) => icon.click(event))
icon.set_reactive(true)
icon.set_height(this.size)
@ -83,7 +85,7 @@ var TrayIndicator = GObject.registerClass(
}
forEach(callback) {
this._icons.forEach(icon => { callback.call(null, icon) })
this._icons.forEach(icon => callback.call(null, icon))
}
}
)
@ -97,6 +99,7 @@ var WindowControls = GObject.registerClass(
this.add_child(this._controls)
this.add_style_class_name('window-controls')
this.remove_style_class_name('panel-button')
}
_addButton(action) {

View File

@ -1 +0,0 @@
var VERSION = parseInt(imports.misc.config.PACKAGE_VERSION.replace(/^3\./, '').split('.')[0])

View File

@ -2,7 +2,7 @@ const Gettext = imports.gettext
const GObject = imports.gi.GObject
const Gio = imports.gi.Gio
const Config = imports.misc.config
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
var SettingsManager = GObject.registerClass(
class UniteSettings extends Gio.Settings {
@ -89,22 +89,23 @@ var PreferencesManager = GObject.registerClass(
)
function initTranslations(domain) {
let textDomain = domain || Unite.metadata['gettext-domain']
let localeDir = Unite.dir.get_child('locale')
let textDomain = domain || Me.metadata['gettext-domain']
let localeDir = Me.dir.get_child('locale')
if (localeDir.query_exists(null))
if (localeDir.query_exists(null)) {
localeDir = localeDir.get_path()
else
} else {
localeDir = Config.LOCALEDIR
}
Gettext.bindtextdomain(textDomain, localeDir)
}
function getSettings(schema) {
schema = schema || Unite.metadata['settings-schema']
schema = schema || Me.metadata['settings-schema']
let gioSSS = Gio.SettingsSchemaSource
let schemaDir = Unite.dir.get_child('schemas')
let schemaDir = Me.dir.get_child('schemas')
let schemaSource = gioSSS.get_default()
if (schemaDir.query_exists(null)) {
@ -115,7 +116,7 @@ function getSettings(schema) {
let schemaObj = schemaSource.lookup(schema, true)
if (!schemaObj) {
let metaId = Unite.metadata.uuid
let metaId = Me.metadata.uuid
let message = `Schema ${schema} could not be found for extension ${metaId}.`
throw new Error(`${message} Please check your installation.`)

View File

@ -1,9 +1,9 @@
const GObject = imports.gi.GObject
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const PanelManager = Unite.imports.panel.PanelManager
const LayoutManager = Unite.imports.layout.LayoutManager
const WindowManager = Unite.imports.window.WindowManager
const Me = imports.misc.extensionUtils.getCurrentExtension()
const PanelManager = Me.imports.panel.PanelManager
const LayoutManager = Me.imports.layout.LayoutManager
const WindowManager = Me.imports.window.WindowManager
var UniteExtension = GObject.registerClass(
class UniteExtension extends GObject.Object {

View File

@ -2,22 +2,33 @@ const Bytes = imports.byteArray
const Gio = imports.gi.Gio
const GLib = imports.gi.GLib
const St = imports.gi.St
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Unite.imports.convenience
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const SETTINGS = Convenience.getSettings()
const WM_PREFS = Convenience.getPreferences()
const USER_CONFIG = GLib.get_user_config_dir()
const USER_STYLES_GTK3 = `${USER_CONFIG}/gtk-3.0/gtk.css`
const USER_STYLES_GTK4 = `${USER_CONFIG}/gtk-4.0/gtk.css`
const GTK_VERSIONS = [3, 4]
const USER_CONFIGS = GLib.get_user_config_dir()
function filePath(parts) {
const parse = part => part ? part.replace(/^@/, '') : ''
const paths = [Me.path].concat(parts).map(parse)
return GLib.build_filenamev(paths)
}
function userStylesPath(version) {
return GLib.build_filenamev([USER_CONFIGS, `gtk-${version}.0`, 'gtk.css'])
}
function fileExists(path) {
return GLib.file_test(path, GLib.FileTest.EXISTS)
}
function getGioFile(path) {
const absPath = GLib.build_filenamev([Unite.path, path])
const absPath = filePath(path)
if (fileExists(absPath)) {
return Gio.file_new_for_path(absPath)
@ -42,13 +53,16 @@ function setFileContents(path, contents) {
GLib.file_set_contents(path, contents)
}
function resetGtkStyles(filepath) {
function resetGtkStyles() {
GTK_VERSIONS.forEach(version => {
const filepath = userStylesPath(version)
let style = getFileContents(filepath)
style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '')
style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '')
setFileContents(filepath, style)
})
}
var Signals = class Signals {
@ -116,7 +130,70 @@ var Settings = class Settings extends Signals {
}
}
var ShellStyle = class ShellStyle {
var Feature = class Feature {
constructor(setting, callback) {
this._settingsKey = setting
this._checkActive = callback
}
}
var Features = class Features {
constructor() {
this.features = []
this.settings = new Settings()
}
add(klass) {
const feature = new klass()
this.features.push(feature)
const setting = feature._settingsKey
const checkCb = feature._checkActive
feature.activated = false
const isActive = () => {
return checkCb.call(null, this.settings.get(setting))
}
const onChange = () => {
const active = isActive()
if (active && !feature.activated) {
feature.activated = true
return feature.activate()
}
if (!active && feature.activated) {
feature.activated = false
return feature.destroy()
}
}
feature._doActivate = () => {
this.settings.connect(setting, onChange.bind(feature))
onChange()
}
feature._doDestroy = () => {
if (feature.activated) {
feature.destroy()
feature.activated = false
}
}
}
activate() {
this.features.forEach(feature => feature._doActivate())
}
destroy() {
this.features.forEach(feature => feature._doDestroy())
this.settings.disconnectAll()
}
}
class ShellStyle {
constructor(path) {
this.file = getGioFile(path)
}
@ -138,7 +215,7 @@ var ShellStyle = class ShellStyle {
}
}
var WidgetStyle = class WidgetStyle {
class WidgetStyle {
constructor(widget, style) {
this.widget = widget
this.style = style
@ -159,16 +236,27 @@ var WidgetStyle = class WidgetStyle {
}
}
var GtkStyle = class GtkStyle {
constructor(filepath, name, contents) {
this.filepath = filepath
this.contents = `/* UNITE ${name} */\n${contents}\n/* ${name} UNITE */\n`
class GtkStyle {
constructor(version, name, data) {
const content = this.parse(data, version)
this.filepath = userStylesPath(version)
this.contents = `/* UNITE ${name} */\n${content}\n/* ${name} UNITE */\n`
}
get existing() {
return getFileContents(this.filepath)
}
parse(data, ver) {
if (data.startsWith('@/')) {
const path = filePath(['styles', `gtk${ver}`, data])
return `@import url('${path}');`
} else {
return data
}
}
load() {
const style = this.contents + this.existing
setFileContents(this.filepath, style)
@ -180,6 +268,21 @@ var GtkStyle = class GtkStyle {
}
}
class GtkStyles {
constructor(name, data, versions) {
const items = [].concat(versions).filter(ver => GTK_VERSIONS.includes(ver))
this.styles = items.map(ver => new GtkStyle(ver, name, data))
}
load() {
this.styles.forEach(style => style.load())
}
unload() {
this.styles.forEach(style => style.unload())
}
}
var Styles = class Styles {
constructor() {
this.styles = new Map()
@ -211,9 +314,13 @@ var Styles = class Styles {
}
}
addShellStyle(name, path) {
addShellStyle(name, data) {
if (data.startsWith('@/')) {
this.deleteStyle(name)
this.setStyle(name, ShellStyle, path)
this.setStyle(name, ShellStyle, data)
} else {
this.addWidgetStyle(name, Main.uiGroup, data)
}
}
addWidgetStyle(name, widget, styles) {
@ -221,14 +328,9 @@ var Styles = class Styles {
this.setStyle(name, WidgetStyle, widget, styles)
}
addGtk3Style(name, contents) {
addGtkStyle(name, contents, versions = GTK_VERSIONS) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK3, name, contents)
}
addGtk4Style(name, contents) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK4, name, contents)
this.setStyle(name, GtkStyles, name, contents, versions)
}
removeAll() {
@ -238,5 +340,4 @@ var Styles = class Styles {
}
}
resetGtkStyles(USER_STYLES_GTK3)
resetGtkStyles(USER_STYLES_GTK4)
resetGtkStyles()

View File

@ -1,276 +1,220 @@
const GObject = imports.gi.GObject
const St = imports.gi.St
const Clutter = imports.gi.Clutter
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
function actorHasClass(actor, name) {
return actor.has_style_class_name && actor.has_style_class_name(name)
var WidgetArrow = class WidgetArrow {
constructor(widget) {
this.widget = widget || {}
if (!this.widget.hasOwnProperty('_arrow')) {
this._findActor(this.widget)
}
}
get arrow() {
return this.widget._arrow || {}
}
_findActor(widget) {
if (widget.hasOwnProperty('_arrow')) {
return this.widget._arrow = widget._arrow
}
const actor = widget.last_child
const klass = actor && actor.has_style_class_name
const cname = name => klass && actor.has_style_class_name(name)
if (cname('popup-menu-arrow')) {
return this.widget._arrow = actor
}
actor && this._findActor(actor)
}
hide() {
if (!this.widget._arrowRemoved) {
this.arrow.visible = false
this.widget._arrowRemoved = true
}
}
show() {
if (this.widget._arrowRemoved) {
this.arrow.visible = true
delete this.widget._arrowRemoved
}
}
}
function getWidgetArrow(widget) {
let arrow = widget._arrow
var Messages = class Messages extends Handlers.Feature {
constructor() {
super('notifications-position', setting => setting != 'center')
}
if (!arrow) {
const last = widget.get_n_children() - 1
const actor = widget.get_children()[last]
activate() {
this.settings = new Handlers.Settings()
if (actor) {
if (actorHasClass(actor, 'popup-menu-arrow')) {
arrow = actor
this.settings.connect(
'notifications-position', this._onPositionChange.bind(this)
)
this._onPositionChange()
}
get position() {
const mapping = { left: 'START', right: 'END' }
const setting = this.settings.get('notifications-position')
return mapping[setting]
}
_onPositionChange() {
const banner = Main.messageTray._bannerBin
const context = St.ThemeContext.get_for_stage(global.stage)
const position = Clutter.ActorAlign[this.position]
banner.set_x_align(position)
banner.set_width(390 * context.scale_factor)
}
destroy() {
const banner = Main.messageTray._bannerBin
const position = Clutter.ActorAlign.CENTER
banner.set_x_align(position)
banner.set_width(-1)
this.settings.disconnectAll()
}
}
var AppMenuIcon = class AppMenuIcon extends Handlers.Feature {
constructor() {
super('hide-app-menu-icon', setting => setting == true)
Override.inject(this, 'layout', 'AppMenuIconClassic')
}
activate() {
AppMenu._iconBox.hide()
}
destroy() {
AppMenu._iconBox.show()
}
}
var DropdownArrows = class DropdownArrows extends Handlers.Feature {
constructor() {
super('hide-dropdown-arrows', setting => setting == true)
Override.inject(this, 'layout', 'DropdownArrows')
}
activate() {
this.signals = new Handlers.Signals()
for (const box of Main.panel.get_children()) {
this.signals.connect(box, 'actor_added', this._onActorAdded.bind(this))
}
this._onActorAdded()
}
get arrows() {
const items = Main.panel.statusArea
const names = Object.keys(items).filter(this._handleWidget.bind(this))
return names.map(name => new WidgetArrow(items[name]))
}
_handleWidget(name) {
return !name.startsWith('unite')
}
_onActorAdded() {
this.arrows.forEach(arrow => arrow.hide())
}
destroy() {
this.arrows.forEach(arrow => arrow.show())
this.signals.disconnectAll()
}
}
var PanelSpacing = class PanelSpacing extends Handlers.Feature {
constructor() {
super('reduce-panel-spacing', setting => setting == true)
Override.inject(this, 'layout', 'PanelSpacing')
Override.inject(this, 'layout', 'PanelSpacingClassic')
}
activate() {
this.styles = new Handlers.Styles()
this._injectStyles()
Main.panel._addStyleClassName('reduce-spacing')
this._syncLayout()
}
_injectStyles() {
this.styles.addShellStyle('spacing', '@/styles/shell/spacing.css')
}
_syncLayout() {
// Fix dateMenu paddings when reduce spacing enabled
// when returning from lock screen
const dateMenu = Main.panel.statusArea.dateMenu
const paddings = this._dateMenuPadding
if (!paddings) {
this._dateMenuPadding = [dateMenu._minHPadding, dateMenu._natHPadding]
dateMenu._minHPadding = 0
dateMenu._natHPadding = 0
} else {
arrow = getWidgetArrow(actor)
}
}
dateMenu._minHPadding = paddings[0]
dateMenu._natHPadding = paddings[1]
this._dateMenuPadding = null
}
if (arrow && !widget.hasOwnProperty('_arrow')) {
widget._arrow = arrow
dateMenu.queue_relayout()
}
return arrow
}
destroy() {
Main.panel._removeStyleClassName('reduce-spacing')
this.styles.removeAll()
function toggleWidgetArrow(widget, hide) {
const arrow = widget && getWidgetArrow(widget)
if (arrow) {
if (hide && !widget._arrowHandled) {
arrow.visible = false
widget._arrowHandled = true
}
if (!hide && widget._arrowHandled) {
arrow.visible = true
delete widget._arrowHandled
}
this._syncLayout()
}
}
var LayoutManager = GObject.registerClass(
class UniteLayoutManager extends GObject.Object {
_init() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.styles = new Handlers.Styles()
this.features = new Handlers.Features()
this.signals.connect(
Main.panel._leftBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.features.add(Messages)
this.features.add(AppMenuIcon)
this.features.add(DropdownArrows)
this.features.add(PanelSpacing)
this.signals.connect(
Main.panel._centerBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.signals.connect(
Main.panel._rightBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.settings.connect(
'notifications-position', this._onNotificationsChange.bind(this)
)
this.settings.connect(
'hide-app-menu-icon', this._onHideAppMenuIcon.bind(this)
)
if (VERSION < 40) {
this.settings.connect(
'hide-app-menu-arrow', this._onHideAppMenuArrow.bind(this)
)
this.settings.connect(
'hide-aggregate-menu-arrow', this._onHideAggMenuArrow.bind(this)
)
this.settings.connect(
'hide-dropdown-arrows', this._onHideDropdownArrows.bind(this)
)
}
this.settings.connect(
'reduce-panel-spacing', this._onChangeStyles.bind(this)
)
if (VERSION < 36) {
this.settings.connect(
'use-system-fonts', this._onChangeStyles.bind(this)
)
this.signals.connect(
GtkSettings, 'notify::gtk-font-name', this._onChangeStyles.bind(this)
)
}
}
_onNotificationsChange() {
const setting = this.settings.get('notifications-position')
if (setting != 'center') {
const context = St.ThemeContext.get_for_stage(global.stage)
const banner = Main.messageTray._bannerBin
const mappings = { left: 'START', right: 'END' }
const position = mappings[setting]
banner.set_x_align(Clutter.ActorAlign[position])
banner.set_width(390 * context.scale_factor)
} else {
this._resetNotifications()
}
}
_onHideAppMenuIcon() {
const setting = this.settings.get('hide-app-menu-icon')
if (setting) {
AppMenu._iconBox.hide()
} else {
this._resetAppMenuIcon()
}
}
_onHideAppMenuArrow() {
const setting = this.settings.get('hide-app-menu-arrow')
if (setting) {
toggleWidgetArrow(AppMenu, true)
} else {
this._resetAppMenuArrow()
}
}
_onHideAggMenuArrow() {
const setting = this.settings.get('hide-aggregate-menu-arrow')
if (setting) {
toggleWidgetArrow(AggMenu, true)
} else {
this._resetAggMenuArrow()
}
}
_onHideDropdownArrows() {
const setting = this.settings.get('hide-dropdown-arrows')
if (setting) {
for (const [name, widget] of Object.entries(Main.panel.statusArea)) {
if (name != 'aggregateMenu' && name != 'appMenu') {
toggleWidgetArrow(widget, true)
}
}
} else {
this._resetDropdownArrows()
}
}
_onChangeStyles() {
const fonts = this.settings.get('use-system-fonts')
const space = this.settings.get('reduce-panel-spacing')
this._resetStyles()
if (VERSION < 36 && fonts) {
const font = GtkSettings.gtk_font_name.replace(/\s\d+$/, '')
this.styles.addWidgetStyle('uiGroup', Main.uiGroup, `font-family: ${font};`)
this.styles.addWidgetStyle('panel', Main.panel, 'font-size: 11.25pt;')
}
if (space) {
Main.panel._addStyleClassName('small-spacing')
}
if (VERSION < 34) {
Main.panel._addStyleClassName('extra-spacing')
}
this._syncStyles()
}
_resetNotifications() {
const banner = Main.messageTray._bannerBin
banner.set_x_align(Clutter.ActorAlign.CENTER)
banner.set_width(-1)
}
_resetAppMenuIcon() {
AppMenu._iconBox.show()
}
_resetAppMenuArrow() {
toggleWidgetArrow(AppMenu, false)
}
_resetAggMenuArrow() {
toggleWidgetArrow(AggMenu, false)
}
_resetDropdownArrows() {
for (const [name, widget] of Object.entries(Main.panel.statusArea)) {
if (name != 'aggregateMenu' && name != 'appMenu') {
toggleWidgetArrow(widget, false)
}
}
}
_resetStyles() {
Main.panel._removeStyleClassName('small-spacing')
Main.panel._removeStyleClassName('extra-spacing')
this.styles.deleteStyle('uiGroup')
this.styles.deleteStyle('panel')
}
// Fix for panel spacing not applied until mouse-over
// Issue: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1708
_syncStyles() {
const space = this.settings.get('reduce-panel-spacing')
if (VERSION >= 34 && space) {
Object.values(Main.panel.statusArea).forEach((item) => {
if (item !== null) {
item.add_style_pseudo_class('hover')
item.remove_style_pseudo_class('hover')
}
})
}
Override.inject(this, 'layout', 'LayoutManager')
}
activate() {
this._onNotificationsChange()
this._onHideAppMenuIcon()
if (VERSION < 40) {
this._onHideAppMenuArrow()
this._onHideAggMenuArrow()
this._onHideDropdownArrows()
}
this._onChangeStyles()
this.features.activate()
}
destroy() {
this._resetNotifications()
this._resetAppMenuIcon()
if (VERSION < 40) {
this._resetAppMenuArrow()
this._resetAggMenuArrow()
this._resetDropdownArrows()
}
this._resetStyles()
this._syncStyles()
this.signals.disconnectAll()
this.settings.disconnectAll()
this.styles.removeAll()
this.features.destroy()
}
}
)

View File

@ -9,9 +9,9 @@
"3.32",
"3.36",
"3.38",
"40.0"
"40"
],
"url": "https://github.com/hardpixel/unite-shell",
"uuid": "unite@hardpixel.eu",
"version": 48
"version": 53
}

View File

@ -0,0 +1,49 @@
const Config = imports.misc.config
const Me = imports.misc.extensionUtils.getCurrentExtension()
var VERSION = parseInt(Config.PACKAGE_VERSION.replace(/^3\./, '').split('.')[0])
var Injection = class Injection {
__override__(ctx) {
if (!this.active) return
this._replace = (key, fn) => {
const method = fn || this[key]
ctx[key] = (...args) => method.call(ctx, ...args)
}
this._prepend = (key, fn) => {
const method = fn || this[key]
const target = ctx[key]
ctx[key] = (...args) => {
method.call(ctx, ...args)
return target.call(ctx, ...args)
}
}
this._append = (key, fn) => {
const method = fn || this[key]
const target = ctx[key]
ctx[key] = (...args) => {
target.call(ctx, ...args)
return method.call(ctx, ...args)
}
}
this._init(ctx)
}
}
function inject(ctx, path, name) {
const klass = Me.imports.overrides[path][name]
if (klass) {
const instance = new klass()
instance.__override__(ctx)
} else {
const extension = Me.metadata.name
throw new Error(`${extension} Error: Override ${path}.${name} does not exist!`)
}
}

View File

@ -0,0 +1,197 @@
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu
const Handlers = Me.imports.handlers
const WidgetArrow = Me.imports.layout.WidgetArrow
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
const CLASSIC = global.session_mode == 'classic'
var AppMenuArrow = class AppMenuArrow extends Handlers.Feature {
constructor() {
super('hide-app-menu-arrow', setting => setting == true)
}
activate() {
this.arrow = new WidgetArrow(AppMenu)
this.arrow.hide()
}
destroy() {
this.arrow.show()
}
}
var AggMenuArrow = class AggMenuArrow extends Handlers.Feature {
constructor() {
super('hide-aggregate-menu-arrow', setting => setting == true)
}
activate() {
this.arrow = new WidgetArrow(AggMenu)
this.arrow.hide()
}
destroy() {
this.arrow.show()
}
}
var SystemFonts = class SystemFonts extends Handlers.Feature {
constructor() {
super('use-system-fonts', setting => setting == true)
}
activate() {
this.signals = new Handlers.Signals()
this.styles = new Handlers.Styles()
this.signals.connect(
GtkSettings, 'notify::gtk-font-name', this._onFontsChange.bind(this)
)
this._onFontsChange()
}
get fontName() {
return GtkSettings.gtk_font_name.replace(/\s\d+$/, '')
}
_resetStyles() {
Main.panel._removeStyleClassName('system-fonts')
this.styles.removeAll()
}
_onFontsChange() {
this._resetStyles()
this.styles.addWidgetStyle('uiGroup', Main.uiGroup, `font-family: ${this.fontName};`)
this.styles.addWidgetStyle('panel', Main.panel, 'font-size: 11.25pt;')
Main.panel._addStyleClassName('system-fonts')
}
destroy() {
this.signals.disconnectAll()
this._resetStyles()
}
}
var DropdownArrows = class DropdownArrows extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._replace('_handleWidget')
}
_handleWidget(name) {
const ignored = ['aggregateMenu', 'appMenu']
return !name.startsWith('unite') && !ignored.includes(name)
}
}
var PanelSpacing = class PanelSpacing extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._prepend('activate', this._onActivate)
this._prepend('destroy', this._onDestroy)
this._replace('_injectStyles')
this._replace('_syncLayout')
}
_injectStyles() {
this.styles.addShellStyle('spacingLegacy', '@/overrides/styles/spacing-legacy.css')
}
_syncLayout() {
// Fix for panel spacing not applied until mouse-over
// Issue: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1708
if (VERSION >= 34) {
Object.values(Main.panel.statusArea).forEach(item => {
if (item !== null) {
item.add_style_pseudo_class('hover')
item.remove_style_pseudo_class('hover')
}
})
}
}
_onActivate() {
if (CLASSIC == true) {
Main.panel._addStyleClassName('classic-spacing')
}
if (VERSION < 34) {
Main.panel._addStyleClassName('extra-spacing')
}
}
_onDestroy() {
Main.panel._removeStyleClassName('classic-spacing')
Main.panel._removeStyleClassName('extra-spacing')
}
}
var PanelSpacingClassic = class PanelSpacingClassic extends Override.Injection {
get active() {
return CLASSIC == true
}
_init() {
this._prepend('activate', this._onActivate)
this._prepend('destroy', this._onDestroy)
this._prepend('_injectStyles')
}
_injectStyles() {
this.styles.addShellStyle('spacingClassic', '@/overrides/styles/spacing-classic.css')
}
_onActivate() {
AppMenu.add_style_class_name('app-menu-button')
AppMenu._iconBox.hide()
}
_onDestroy() {
AppMenu.remove_style_class_name('app-menu-button')
}
}
var AppMenuIconClassic = class AppMenuIconClassic extends Override.Injection {
get active() {
return CLASSIC == true
}
_init() {
this._prepend('activate', this._resizeAppIcon)
}
_resizeAppIcon() {
AppMenu._iconBox.set_size(16, 16)
}
}
var LayoutManager = class LayoutManager extends Override.Injection {
get active() {
return true
}
_init(ctx) {
if (VERSION < 40) {
ctx.features.add(AppMenuArrow)
ctx.features.add(AggMenuArrow)
}
if (VERSION < 36) {
ctx.features.add(SystemFonts)
}
}
}

View File

@ -0,0 +1,27 @@
const Gi = imports._gi
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var ExtendLeftBox = class ExtendLeftBox extends Override.Injection {
get active() {
return VERSION < 38
}
_init() {
this._replace('_injectAllocate')
this._replace('_boxAllocate')
}
_injectAllocate() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box, flags) => {
Main.panel.vfunc_allocate.call(Main.panel, box, flags)
this._allocate(Main.panel, box, flags)
})
}
_boxAllocate(box, childBox, flags) {
box.allocate(childBox, flags)
}
}

View File

@ -0,0 +1,31 @@
const GLib = imports.gi.GLib
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var PrefsWidget = class PrefsWidget extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._replace('_loadTemplate')
}
_loadTemplate() {
const template = GLib.build_filenamev([Me.path, 'overrides', 'settings.ui'])
this._buildable.add_from_file(template)
this._container = this._getWidget('prefs_widget')
this.add(this._container)
if (VERSION >= 36) {
const fonts = this._getWidget('use-system-fonts-section')
fonts.set_no_show_all(true)
fonts.set_visible(false)
}
this.show_all()
}
}

View File

@ -0,0 +1,20 @@
#panelLeft .panel-button {
-natural-hpadding: 10px;
-minimum-hpadding: 8px;
padding-left: 10px;
padding-right: 10px;
}
#panel .app-menu-button {
-natural-hpadding: 4px;
-minimum-hpadding: 4px;
padding-left: 4px;
padding-right: 4px;
}
#panel #panelLeft #appMenu {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
padding-left: 0px;
padding-right: 0px;
}

View File

@ -0,0 +1,36 @@
#panel .panel-button {
-natural-hpadding: 8px;
-minimum-hpadding: 6px;
}
#panel .panel-button .system-status-icon {
padding-left: 0px;
padding-right: 0px;
}
#panel .panel-button .panel-status-indicators-box {
spacing: 12px;
}
#panel .panel-button .panel-status-indicators-box .panel-status-indicators-box {
spacing: 4px;
}
#panelRight .window-controls-container {
margin-left: 8px;
margin-right: 8px;
}
#panelRight .window-controls-container:last-child {
margin-right: 0px;
}
#panel.extra-spacing .panel-button .panel-status-indicators-box {
spacing: 10px;
}
#panel.classic-spacing #appMenu,
#panel.extra-spacing #appMenu, {
margin-left: 8px;
margin-right: 8px;
}

View File

@ -0,0 +1,23 @@
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var WindowManager = class WindowManager extends Override.Injection {
get active() {
return VERSION < 36
}
_init(ctx) {
ctx.signals.connect(
AppMenu._label, 'notify::text', this._onAppmenuChanged.bind(ctx)
)
}
_onAppmenuChanged() {
if (this.focusWindow) {
this.focusWindow.syncAppmenu()
}
}
}

View File

@ -10,56 +10,19 @@ const Shell = imports.gi.Shell
const AppSystem = imports.gi.Shell.AppSystem.get_default()
const WinTracker = imports.gi.Shell.WindowTracker.get_default()
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Activities = Main.panel.statusArea.activities
const Buttons = Unite.imports.buttons
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Buttons = Me.imports.buttons
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
var PanelExtension = class PanelExtension {
constructor(settings, key, callback) {
this.activated = false
const isActive = () => {
return callback.call(null, settings.get(key))
var WindowButtons = class WindowButtons extends Handlers.Feature {
constructor() {
super('show-window-buttons', setting => setting != 'never')
}
const onChange = () => {
const active = isActive()
if (active && !this.activated) {
this.activated = true
return this._init()
}
if (!active && this.activated) {
this.activated = false
return this._destroy()
}
}
this.activate = () => {
settings.connect(key, onChange.bind(this))
onChange()
}
this.destroy = () => {
if (this.activated) {
this._destroy()
this.activated = false
}
}
}
}
var WindowButtons = class WindowButtons extends PanelExtension {
constructor({ settings }) {
const active = val => val != 'never'
super(settings, 'show-window-buttons', active)
}
_init() {
activate() {
this.theme = 'default-dark'
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -148,17 +111,14 @@ var WindowButtons = class WindowButtons extends PanelExtension {
_onPositionChange() {
const controls = this.controls.container
const container = controls.get_parent()
if (controls.reparent) {
controls.reparent(this.container)
} else {
const currentParent = controls.get_parent()
controls.add_style_class_name('window-controls-container')
if (currentParent) {
currentParent.remove_child(controls)
if (container) {
container.remove_child(controls)
this.container.add_child(controls)
}
}
if (this.index != null) {
this.container.set_child_at_index(controls, this.index)
@ -173,7 +133,7 @@ var WindowButtons = class WindowButtons extends PanelExtension {
this.controls.remove_style_class_name(this.theme)
this.theme = this.settings.get('window-buttons-theme')
const path = `themes/${this.theme}/stylesheet.css`
const path = `@/themes/${this.theme}/stylesheet.css`
this.styles.addShellStyle('windowButtons', path)
this.controls.add_style_class_name(this.theme)
@ -191,7 +151,7 @@ var WindowButtons = class WindowButtons extends PanelExtension {
}
}
_destroy() {
destroy() {
this.controls.destroy()
this.signals.disconnectAll()
@ -200,37 +160,30 @@ var WindowButtons = class WindowButtons extends PanelExtension {
}
}
var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'extend-left-box', active)
var ExtendLeftBox = class ExtendLeftBox extends Handlers.Feature {
constructor() {
super('extend-left-box', setting => setting == true)
Override.inject(this, 'panel', 'ExtendLeftBox')
}
_init() {
activate() {
this._default = Main.panel.__proto__.vfunc_allocate
this._injectAllocate()
if (VERSION < 37) {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box, flags) => {
Main.panel.vfunc_allocate.call(Main.panel, box, flags)
this._allocate(Main.panel, box, flags)
})
} else {
Main.panel.queue_relayout()
}
_injectAllocate() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box) => {
Main.panel.vfunc_allocate.call(Main.panel, box)
this._allocate(Main.panel, box)
})
}
Main.panel.queue_relayout()
}
_boxAllocate(box, childBox, flags) {
if (VERSION < 37) {
box.allocate(childBox, flags)
} else {
box.allocate(childBox)
}
}
_allocate(actor, box, flags) {
let leftBox = Main.panel._leftBox
@ -287,7 +240,7 @@ var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
this._boxAllocate(rightBox, childBox, flags)
}
_destroy() {
destroy() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', this._default)
this._default = null
@ -295,13 +248,12 @@ var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
}
}
var ActivitiesButton = class ActivitiesButton extends PanelExtension {
constructor({ settings }) {
const active = val => val != 'never'
super(settings, 'hide-activities-button', active)
var ActivitiesButton = class ActivitiesButton extends Handlers.Feature {
constructor() {
super('hide-activities-button', setting => Activities && setting != 'never')
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -352,7 +304,7 @@ var ActivitiesButton = class ActivitiesButton extends PanelExtension {
}
}
_destroy() {
destroy() {
if (!Main.overview.isDummy) {
Activities.container.show()
}
@ -362,13 +314,12 @@ var ActivitiesButton = class ActivitiesButton extends PanelExtension {
}
}
var DesktopName = class DesktopName extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'show-desktop-name', active)
var DesktopName = class DesktopName extends Handlers.Feature {
constructor() {
super('show-desktop-name', setting => setting == true)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.label = new Buttons.DesktopLabel()
@ -413,7 +364,7 @@ var DesktopName = class DesktopName extends PanelExtension {
this.label.setText(text)
}
_destroy() {
destroy() {
this.label.destroy()
this.signals.disconnectAll()
@ -421,13 +372,12 @@ var DesktopName = class DesktopName extends PanelExtension {
}
}
var TrayIcons = class TrayIcons extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'show-legacy-tray', active)
var TrayIcons = class TrayIcons extends Handlers.Feature {
constructor() {
super('show-legacy-tray', setting => setting == true)
}
_init() {
activate() {
this.tray = new Shell.TrayManager()
this.settings = new Handlers.Settings()
this.indicators = new Buttons.TrayIndicator()
@ -480,7 +430,7 @@ var TrayIcons = class TrayIcons extends PanelExtension {
this.indicators.forEach(this._desaturateIcon.bind(this))
}
_destroy() {
destroy() {
this.tray = null
System.gc()
@ -489,13 +439,12 @@ var TrayIcons = class TrayIcons extends PanelExtension {
}
}
var TitlebarActions = class TitlebarActions extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'enable-titlebar-actions', active)
var TitlebarActions = class TitlebarActions extends Handlers.Feature {
constructor() {
super('enable-titlebar-actions', setting => setting == true)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -505,25 +454,19 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
}
_onButtonPressEvent(actor, event) {
if (Main.modalCount > 0 || actor != event.get_source()) {
return Clutter.EVENT_PROPAGATE
}
const focusWindow = global.unite.focusWindow
if (!focusWindow || !focusWindow.hideTitlebars) {
return Clutter.EVENT_PROPAGATE
}
const [mouseX, mouseY] = event.get_coords()
const ccount = event.get_click_count()
const button = event.get_button()
const clickOnChildren = Main.panel.get_children().some(({ x, y, width, height }) => {
return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height
})
if (clickOnChildren) {
return Clutter.EVENT_PROPAGATE
}
let action = null
if (button == 1 && ccount == 2) {
@ -539,8 +482,7 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
}
if (action == 'menu') {
this._openWindowMenu(focusWindow.win, mouseX)
return Clutter.EVENT_STOP
return this._openWindowMenu(focusWindow.win, event.get_coords()[0])
}
if (action && action != 'none') {
@ -560,37 +502,37 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
'lower': 'lower'
}
const method = mapping[action]
const method = win[mapping[action]]
if (method) {
win[method].call(win)
return Clutter.EVENT_STOP
if (typeof method !== 'function') {
return Clutter.EVENT_PROPAGATE
}
return Clutter.EVENT_PROPAGATE
method.call(win)
return Clutter.EVENT_STOP
}
_openWindowMenu(win, x) {
const size = Main.panel.height + 4
const rect = { x, y: 0, width: size, height: size }
const rect = { x: x - size, y: 0, width: size * 2, height: size }
const type = Meta.WindowMenuType.WM
Main.wm._windowMenuManager.showWindowMenuForWindow(win, type, rect)
return Clutter.EVENT_STOP
}
_destroy() {
destroy() {
this.signals.disconnectAll()
this.settings.disconnectAll()
}
}
var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
constructor({ settings }) {
const active = val => val > 0
super(settings, 'app-menu-max-width', active)
var AppMenuCustomizer = class AppMenuCustomizer extends Handlers.Feature {
constructor() {
super('app-menu-max-width', setting => setting > 0)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.tooltip = new St.Label({ visible: false, style_class: 'dash-label' })
@ -672,7 +614,7 @@ var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
this.setTextEllipsizeMode(this.ellipsizeMode)
}
_destroy() {
destroy() {
this.tooltip.destroy()
this.setLabelMaxWidth(null)
@ -686,36 +628,23 @@ var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
var PanelManager = GObject.registerClass(
class UnitePanelManager extends GObject.Object {
_init() {
this.settings = new Handlers.Settings()
this.buttons = new WindowButtons(this)
this.extender = new ExtendLeftBox(this)
this.activities = new ActivitiesButton(this)
this.desktop = new DesktopName(this)
this.tray = new TrayIcons(this)
this.titlebar = new TitlebarActions(this)
this.appmenu = new AppMenuCustomizer(this)
this.features = new Handlers.Features()
this.features.add(WindowButtons)
this.features.add(ExtendLeftBox)
this.features.add(ActivitiesButton)
this.features.add(DesktopName)
this.features.add(TrayIcons)
this.features.add(TitlebarActions)
this.features.add(AppMenuCustomizer)
}
activate() {
this.buttons.activate()
this.extender.activate()
this.activities.activate()
this.desktop.activate()
this.tray.activate()
this.titlebar.activate()
this.appmenu.activate()
this.features.activate()
}
destroy() {
this.buttons.destroy()
this.extender.destroy()
this.activities.destroy()
this.desktop.destroy()
this.tray.destroy()
this.titlebar.destroy()
this.appmenu.destroy()
this.settings.disconnectAll()
this.features.destroy()
}
}
)

View File

@ -1,27 +1,21 @@
const GLib = imports.gi.GLib
const GObject = imports.gi.GObject
const Gtk = imports.gi.Gtk
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Unite.imports.convenience
const VERSION = Unite.imports.constants.VERSION
const TEMPLATE = VERSION < 40 ? 'settings-gtk3.ui' : 'settings-gtk4.ui'
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const Override = Me.imports.overrides.helper
var PrefsWidget = GObject.registerClass(
class UnitePrefsWidget extends Gtk.Box {
_init(params) {
this._settings = Convenience.getSettings()
super._init(params)
this._settings = Convenience.getSettings()
this._buildable = new Gtk.Builder()
this._buildable.add_from_file(`${Unite.path}/${TEMPLATE}`)
this._container = this._getWidget('prefs_widget')
if (VERSION < 40) {
this.add(this._container)
} else {
this.append(this._container)
}
Override.inject(this, 'prefs', 'PrefsWidget')
this._loadTemplate()
this._bindStrings()
this._bindSelects()
this._bindBooleans()
@ -29,20 +23,12 @@ var PrefsWidget = GObject.registerClass(
this._bindIntegers()
}
startup() {
if (VERSION < 40) {
this.show_all()
}
_loadTemplate() {
const template = GLib.build_filenamev([Me.path, 'settings.ui'])
this._buildable.add_from_file(template)
if (VERSION >= 36) {
this._hideSetting('use-system-fonts')
}
if (VERSION >= 40) {
this._disableSetting('hide-dropdown-arrows')
this._disableSetting('hide-aggregate-menu-arrow')
this._disableSetting('hide-app-menu-arrow')
}
this._container = this._getWidget('prefs_widget')
this.append(this._container)
}
_getWidget(name) {
@ -50,16 +36,6 @@ var PrefsWidget = GObject.registerClass(
return this._buildable.get_object(widgetName)
}
_hideSetting(name) {
const widget = this._getWidget(`${name}_section`)
widget.set_visible(false)
}
_disableSetting(name) {
const widget = this._getWidget(`${name}_section`)
widget.set_sensitive(false)
}
_bindInput(setting, prop) {
let widget = this._getWidget(setting)
this._settings.bind(setting, widget, prop, this._settings.DEFAULT_BINDING)
@ -69,34 +45,34 @@ var PrefsWidget = GObject.registerClass(
let widget = this._getWidget(setting)
widget.set_active(this._settings.get_enum(setting))
widget.connect('changed', (combobox) => {
widget.connect('changed', combobox => {
this._settings.set_enum(setting, combobox.get_active())
})
}
_bindStrings() {
let settings = this._settings.getTypeSettings('string')
settings.forEach(setting => { this._bindInput(setting, 'text') })
settings.forEach(setting => this._bindInput(setting, 'text'))
}
_bindSelects() {
let settings = this._settings.getTypeSettings('select')
settings.forEach(setting => { this._bindInput(setting, 'active-id') })
settings.forEach(setting => this._bindInput(setting, 'active-id'))
}
_bindBooleans() {
let settings = this._settings.getTypeSettings('boolean')
settings.forEach(setting => { this._bindInput(setting, 'active') })
settings.forEach(setting => this._bindInput(setting, 'active'))
}
_bindEnumerations() {
let settings = this._settings.getTypeSettings('enum')
settings.forEach(setting => { this._bindEnum(setting) })
settings.forEach(setting => this._bindEnum(setting))
}
_bindIntegers() {
let settings = this._settings.getTypeSettings('int')
settings.forEach(setting => { this._bindInput(setting, 'value') })
settings.forEach(setting => this._bindInput(setting, 'value'))
}
}
)
@ -106,8 +82,5 @@ function init() {
}
function buildPrefsWidget() {
let widget = new PrefsWidget()
widget.startup()
return widget
return new PrefsWidget()
}

View File

@ -14,7 +14,6 @@
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox" id="general_prefs">
<property name="can-focus">0</property>
<property name="valign">start</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
@ -25,7 +24,6 @@
<property name="homogeneous">1</property>
<child>
<object class="GtkBox" id="extend_left_box_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -46,7 +44,6 @@
</child>
<child>
<object class="GtkBox" id="autofocus_windows_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -67,7 +64,6 @@
</child>
<child>
<object class="GtkBox" id="show_legacy_tray_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -88,7 +84,6 @@
</child>
<child>
<object class="GtkBox" id="show_desktop_name_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -109,7 +104,6 @@
</child>
<child>
<object class="GtkBox" id="enable_titlebar_actions_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -130,7 +124,6 @@
</child>
<child>
<object class="GtkBox" id="restrict_to_primary_screen_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -151,7 +144,6 @@
</child>
<child>
<object class="GtkBox" id="hide_activities_button_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -164,7 +156,6 @@
<object class="GtkComboBoxText" id="hide_activities_button">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">1</property>
<items>
@ -178,7 +169,6 @@
</child>
<child>
<object class="GtkBox" id="hide_window_titlebars_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -191,7 +181,6 @@
<object class="GtkComboBoxText" id="hide_window_titlebars">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -207,7 +196,6 @@
</child>
<child>
<object class="GtkBox" id="show_window_title_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -220,7 +208,6 @@
<object class="GtkComboBoxText" id="show_window_title">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -236,7 +223,6 @@
</child>
<child>
<object class="GtkBox" id="show_window_buttons_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -249,7 +235,6 @@
<object class="GtkComboBoxText" id="show_window_buttons">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -265,7 +250,6 @@
</child>
<child>
<object class="GtkBox" id="notifications_position_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -278,7 +262,6 @@
<object class="GtkComboBoxText" id="notifications_position">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -305,7 +288,6 @@
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox" id="appearance_prefs">
<property name="can-focus">0</property>
<property name="valign">start</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
@ -316,8 +298,8 @@
<property name="homogeneous">1</property>
<child>
<object class="GtkBox" id="use_system_fonts_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<property name="visible">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -337,7 +319,6 @@
</child>
<child>
<object class="GtkBox" id="greyscale_tray_icons_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -357,7 +338,6 @@
</child>
<child>
<object class="GtkBox" id="hide_dropdown_arrows_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -378,7 +358,7 @@
</child>
<child>
<object class="GtkBox" id="hide_aggregate_menu_arrow_section">
<property name="can-focus">0</property>
<property name="sensitive">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -398,7 +378,7 @@
</child>
<child>
<object class="GtkBox" id="hide_app_menu_arrow_section">
<property name="can-focus">0</property>
<property name="sensitive">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -419,7 +399,6 @@
</child>
<child>
<object class="GtkBox" id="hide_app_menu_icon_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -440,7 +419,6 @@
</child>
<child>
<object class="GtkBox" id="reduce_panel_spacing_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -461,7 +439,6 @@
</child>
<child>
<object class="GtkBox" id="desktop_name_text_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -482,7 +459,6 @@
</child>
<child>
<object class="GtkBox" id="app_menu_max_width_section">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -503,7 +479,6 @@
</child>
<child>
<object class="GtkBox" id="app_menu_ellipsize_mode_section">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -515,7 +490,6 @@
<object class="GtkComboBoxText" id="app_menu_ellipsize_mode">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -529,7 +503,6 @@
</child>
<child>
<object class="GtkBox" id="window_buttons_placement_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -542,7 +515,6 @@
<object class="GtkComboBoxText" id="window_buttons_placement">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">auto</property>
<items>
@ -558,7 +530,6 @@
</child>
<child>
<object class="GtkBox" id="window_buttons_theme_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -571,7 +542,6 @@
<object class="GtkComboBoxText" id="window_buttons_theme">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">0</property>
<items>

View File

@ -0,0 +1,61 @@
#panelLeft,
#panelCenter,
#panelRight {
spacing: 0px;
}
#panel .panel-button {
-natural-hpadding: 6px;
-minimum-hpadding: 4px;
padding-left: 6px;
padding-right: 6px;
}
#panel .panel-button > .system-status-icon {
padding-left: 0px;
padding-right: 0px;
}
#panel .panel-button .panel-status-indicators-box {
spacing: 4px;
}
#panel #panelActivities,
#panel .system-tray-icons,
#panel .desktop-name-label {
-natural-hpadding: 10px;
-minimum-hpadding: 8px;
}
#panel .system-tray-icons .panel-status-indicators-box {
spacing: 10px;
}
#panel .panel-button.clock-display {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
padding-left: 0px;
padding-right: 0px;
}
#panel .clock-display-box .clock {
padding-left: 8px;
padding-right: 8px;
}
#panel .clock-display-box StIcon:last-child {
margin-right: 3px;
}
#panel .window-controls-container {
margin-left: 4px;
margin-right: 4px;
}
#panelLeft .window-controls-container:first-child {
margin-left: 0px;
}
#panelRight .window-controls-container:last-child {
margin-right: 0px;
}

View File

@ -1,28 +1,3 @@
#panel.small-spacing .panel-button {
-natural-hpadding: 8px;
-minimum-hpadding: 6px;
}
#panel.small-spacing .panel-button .system-status-icon {
padding: 0;
}
#panel.small-spacing .panel-button .panel-status-indicators-box {
spacing: 12px;
}
#panel.small-spacing .panel-button .panel-status-indicators-box .panel-status-indicators-box {
spacing: 4px;
}
#panel.small-spacing.extra-spacing .panel-button .panel-status-indicators-box {
spacing: 10px;
}
#panel.small-spacing.extra-spacing #appMenu {
margin: 0 8px;
}
#panel .panel-button.window-controls {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
@ -36,11 +11,11 @@
width: 22px;
}
#panelLeft .window-controls-box:first-child .window-button:first-child {
#panelLeft .window-controls-container:first-child .window-button:first-child {
padding-left: 3px;
}
#panelRight .window-controls-box:last-child .window-button:last-child {
#panelRight .window-controls-container:last-child .window-button:last-child {
padding-right: 3px;
}

View File

@ -5,10 +5,10 @@ const Meta = imports.gi.Meta
const WinTracker = imports.gi.Shell.WindowTracker.get_default()
const Main = imports.ui.main
const Util = imports.misc.util
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
const VALID_TYPES = [
Meta.WindowType.NORMAL,
@ -390,11 +390,7 @@ var WindowManager = GObject.registerClass(
'button-layout', this._onStylesChange.bind(this)
)
if (VERSION < 36) {
this.signals.connect(
AppMenu._label, 'notify::text', this._onAppmenuChanged.bind(this)
)
}
Override.inject(this, 'window', 'WindowManager')
}
get focusWindow() {
@ -460,12 +456,6 @@ var WindowManager = GObject.registerClass(
}
}
_onAppmenuChanged() {
if (this.focusWindow) {
this.focusWindow.syncAppmenu()
}
}
_onAttention(actor, win) {
const auto = this.settings.get('autofocus-windows')
const time = global.get_current_time()
@ -475,15 +465,12 @@ var WindowManager = GObject.registerClass(
_onStylesChange() {
if (this.hideTitlebars != 'never') {
const variant = this.settings.get('window-buttons-position')
const folder = path => `${Unite.path}/styles/${path}/buttons-${variant}`
const content = path => `@import url('${folder(path)}/${this.hideTitlebars}.css');`
const side = this.settings.get('window-buttons-position')
const path = `@/buttons-${side}/${this.hideTitlebars}.css`
this.styles.addGtk3Style('windowDecorationsGTK3', content('gtk3'))
this.styles.addGtk4Style('windowDecorationsGTK4', content('gtk4'))
this.styles.addGtkStyle('windowDecorations', path)
} else {
this.styles.deleteStyle('windowDecorationsGTK3')
this.styles.deleteStyle('windowDecorationsGTK4')
this.styles.deleteStyle('windowDecorations')
}
}
@ -491,6 +478,8 @@ var WindowManager = GObject.registerClass(
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
const actors = global.get_window_actors()
actors.forEach(actor => this._onMapWindow(null, actor))
return GLib.SOURCE_REMOVE
})
this._onStylesChange()

View File

@ -0,0 +1,138 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Main = imports.ui.main;
const Volume = imports.ui.status.volume;
let volume_scroller = null;
const VolumeScrollerIcons =
[
'audio-volume-muted-symbolic',
'audio-volume-low-symbolic',
'audio-volume-medium-symbolic',
'audio-volume-high-symbolic'
];
class VolumeScroller
{
constructor()
{
this.controller = Volume.getMixerControl();
this.panel = Main.panel;
this.enabled = false;
this.sink = null;
this.volume_max = this.controller.get_vol_max_norm();
this.volume_step = 0.05 * this.volume_max;
this.scroll_binding = null;
this.sink_binding = null;
}
enable()
{
if (this.enabled)
{
this.disable();
}
this.enabled = true;
this.sink = this.controller.get_default_sink();
this.scroll_binding = this.panel.connect(
'scroll-event',
(actor, event) => this._handle_scroll(actor, event));
this.sink_binding = this.controller.connect(
'default-sink-changed',
(controller, id) => this._handle_sink_change(controller, id));
}
disable()
{
if (this.enabled)
{
this.enabled = false;
this.sink = null;
this.panel.disconnect(this.scroll_binding);
this.scroll_binding = null;
this.controller.disconnect(this.sink_binding);
this.sink_binding = null;
}
}
_handle_scroll(actor, event)
{
let volume = this.sink.volume;
switch (event.get_scroll_direction())
{
case Clutter.ScrollDirection.UP:
volume += this.volume_step;
break;
case Clutter.ScrollDirection.DOWN:
volume -= this.volume_step;
break;
default:
return Clutter.EVENT_PROPAGATE;
}
volume = Math.min(volume, this.volume_max);
volume = Math.max(volume, 0);
this.sink.volume = volume;
this.sink.push_volume();
this._show_volume(volume);
return Clutter.EVENT_STOP;
}
_handle_sink_change(controller, id)
{
this.sink = controller.lookup_stream_id(id);
}
_show_volume(volume)
{
const percentage = volume / this.volume_max;
let n;
if (volume === 0)
{
n = 0;
}
else
{
n = parseInt(3 * percentage + 1);
n = Math.max(1, n);
n = Math.min(3, n);
}
const monitor = -1; // Display volume window on all monitors.
const icon = Gio.Icon.new_for_string(VolumeScrollerIcons[n]);
const label = this.sink.get_port().human_port;
Main.osdWindowManager.show(monitor, icon, label, percentage);
}
};
function enable()
{
volume_scroller = new VolumeScroller();
volume_scroller.enable();
}
function disable()
{
if (volume_scroller !== null)
{
volume_scroller.disable();
volume_scroller = null;
}
}

View File

@ -0,0 +1,13 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Scroll up or down in the Top Bar to adjust volume.",
"name": "Volume Scroller",
"original-author": "trflynn89@pm.me",
"shell-version": [
"3.36",
"3.38"
],
"url": "https://github.com/trflynn89/gnome-shell-volume-scroller",
"uuid": "volume_scroller@trflynn89.pm.me",
"version": 2
}

View File

@ -0,0 +1,2 @@
export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_STYLE_OVERRIDE="kvantum-dark"

View File

@ -0,0 +1,110 @@
/* 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
* 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 {boxpointer, main, popupMenu} = imports.ui;
const {Shell} = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
// inspired by tweaks in system menu
// https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/
class Extension {
constructor() {
}
enable() {
this.settings = ExtensionUtils.getSettings("org.gnome.shell.extensions.extensions-in-system-menu");
this.settings.connect("changed::extensions", () => this.updateItems());
this.settings.connect("changed::tweaks", () => this.updateItems());
this.settings.connect("changed::extensions-pos", () => this.updateItems());
this.settings.connect("changed::tweaks-pos", () => this.updateItems());
this.updateItems();
}
disable() {
this.extensionsItem && this.extensionsItem.destroy();
this.extensionsItem = null;
this.tweaksItem && this.tweaksItem.destroy();
this.tweaksItem = null;
this.settings.run_dispose();
this.settings = null;
}
updateItems() {
this.extensionsItem = this.extensionsItem && this.extensionsItem.destroy();
this.tweaksItem = this.tweaksItem && this.tweaksItem.destroy();
const extensionsPos = this.settings.get_int("extensions-pos");
const tweaksPos = this.settings.get_int("tweaks-pos");
const createExtensions = function() {
if (this.settings.get_boolean("extensions"))
this.extensionsItem = this.createSystemMenuItem("org.gnome.Extensions.desktop", extensionsPos);
}
const createTweaks = function() {
if (this.settings.get_boolean("tweaks"))
this.tweaksItem = this.createSystemMenuItem("org.gnome.tweaks.desktop", tweaksPos);
}
if (extensionsPos < tweaksPos)
createExtensions.call(this) || createTweaks.call(this);
else
createTweaks.call(this) || createExtensions.call(this);
}
createSystemMenuItem(appID, pos) {
const app = Shell.AppSystem.get_default().lookup_app(appID);
if (!app)
return this.notifyNotInstalled(appID);
const [name, icon] = [app.get_name(), app.app_info.get_icon().names[0]];
const item = new popupMenu.PopupImageMenuItem(name, icon);
const systemMenu = main.panel.statusArea.aggregateMenu._system;
systemMenu.menu.addMenuItem(item);
systemMenu.menu.moveMenuItem(item, pos);
item.connect("activate", this.onActivate.bind(this, appID));
return item;
}
onActivate(appID) {
const app = Shell.AppSystem.get_default().lookup_app(appID);
if (!app) // app got uninstalled while this extension was active
return this.notifyNotInstalled(appID);
main.overview.hide();
const systemMenu = main.panel.statusArea.aggregateMenu._system;
systemMenu.menu.itemActivated(boxpointer.PopupAnimation.NONE);
app.activate();
}
notifyNotInstalled(appID) {
const missingAppTitle = "Extension & Tweaks in system menu";
const missingAppMsg = `Install the GNOME ${appID.split(".")[2]} app and re-enable this setting`;
log(`--- ${missingAppTitle}: ${missingAppMsg} ---`);
main.notify(missingAppTitle, missingAppMsg);
}
}
function init() {
return new Extension();
}

View File

@ -0,0 +1,14 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "No longer maintained. Starting with GNOME 40 'Tweaks-in-system-menu' also supports the extensions app. Please use that https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/\n\n--------------------\n\nPut the Extensions and/or the Tweaks app into the system menu.",
"name": "Extensions & Tweaks in system menu",
"shell-version": [
"3.36",
"3.38",
"40.0",
"40.beta"
],
"url": "https://github.com/Leleat/extensions-in-system-menu",
"uuid": "extensions-in-system-menu@leleat-on-github",
"version": 6
}

View File

@ -0,0 +1,70 @@
"use strict";
const {Gio, GObject, Gtk} = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const shellVersion = parseFloat(imports.misc.config.PACKAGE_VERSION);
function init() {
}
function buildPrefsWidget() {
const prefsWidget = new PrefsWidget();
shellVersion < 40 && prefsWidget.show_all();
return prefsWidget;
}
const PrefsWidget = GObject.registerClass(
class ExtensionsSystemMenuPrefsWidget extends Gtk.Box {
_init(params) {
super._init(params);
this.builder = new Gtk.Builder();
this.builder.add_from_file(Me.path + "/prefs.ui");
const mainPrefs = this.builder.get_object("main_prefs");
shellVersion < 40 ? this.add(mainPrefs) : this.append(mainPrefs);
const gschema = Gio.SettingsSchemaSource.new_from_directory(Me.dir.get_child("schemas").get_path(), Gio.SettingsSchemaSource.get_default(), false);
const settingsSchema = gschema.lookup("org.gnome.shell.extensions.extensions-in-system-menu", true);
this.settings = new Gio.Settings({settings_schema: settingsSchema});
this.bindWidgetsToSettings(settingsSchema.list_keys());
this.bindWidgetsTogether();
}
bindWidgetsToSettings(keys) {
// widgets in prefs.ui need to have same ID
// as the keys in the gschema.xml file
const getBindProperty = function(key) {
const ints = ["extensions-pos", "tweaks-pos"];
const bools = ["extensions", "tweaks"];
if (ints.includes(key))
return "value"; // Gtk.Spinbox.value
else if (bools.includes(key))
return "active"; // Gtk.Switch.active
else
return null;
};
keys.forEach(key => {
const bindProperty = getBindProperty(key);
const widget = this.builder.get_object(key);
if (widget && bindProperty)
this.settings.bind(key, widget, bindProperty, Gio.SettingsBindFlags.DEFAULT);
});
}
bindWidgetsTogether() {
const extensionsToggle = this.builder.get_object("extensions");
const extensionsPos = this.builder.get_object("extensions-pos-box");
extensionsToggle.bind_property("active", extensionsPos, "sensitive", GObject.BindingFlags.DEFAULT);
const tweaksToggle = this.builder.get_object("tweaks");
const tweaksPos = this.builder.get_object("tweaks-pos-box");
tweaksToggle.bind_property("active", tweaksPos, "sensitive", GObject.BindingFlags.DEFAULT);
}
}
)

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkAdjustment" id="extensions-adjustment">
<property name="upper">10</property>
<property name="value">1</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkAdjustment" id="tweaks-adjustment">
<property name="upper">10</property>
<property name="value">2</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
<object class="GtkBox" id="main_prefs">
<property name="name">main_prefs</property>
<property name="can-focus">1</property>
<property name="margin-start">30</property>
<property name="margin-end">30</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="orientation">vertical</property>
<property name="spacing">15</property>
<property name="baseline-position">top</property>
<child>
<object class="GtkBox" id="extensions-box">
<property name="can-focus">1</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Extensions</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="extensions">
<property name="can-focus">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="extensions-pos-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Extensions position</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="extensions-pos">
<property name="width-request">175</property>
<property name="adjustment">extensions-adjustment</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="tweaks-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Tweaks</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="tweaks">
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="tweaks-pos-box">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
<property name="label" translatable="yes">Tweaks position</property>
<property name="hexpand">1</property>
<property name="halign">start</property>
</object>
</child>
<child>
<object class="GtkSpinButton" id="tweaks-pos">
<property name="width-request">175</property>
<property name="adjustment">tweaks-adjustment</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema id="org.gnome.shell.extensions.extensions-in-system-menu" path="/org/gnome/shell/extensions/extensions-in-system-menu/">
<key name="extensions" type="b">
<default>true</default>
</key>
<key name="tweaks" type="b">
<default>false</default>
</key>
<key name="extensions-pos" type="i">
<default>2</default>
</key>
<key name="tweaks-pos" type="i">
<default>3</default>
</key>
</schema>
</schemalist>

View File

@ -1,35 +0,0 @@
'use strict';
// User Menu and Volume Indicator
const AggregateMenu = imports.ui.main.panel.statusArea.aggregateMenu;
const VolumeIndicator = AggregateMenu._volume;
// Scroll Signal Id
var _onScrollEventId = 0;
function init() {
}
function enable() {
// Make the User Menu indicator box reactive so it emits ::scroll-event
AggregateMenu._indicators.reactive = true;
// Connect the same handler from the volume indicator to ::scroll-event
_onScrollEventId = AggregateMenu._indicators.connect(
'scroll-event',
VolumeIndicator.vfunc_scroll_event.bind(VolumeIndicator)
);
}
function disable() {
// Undo the above
if (_onScrollEventId) {
AggregateMenu._indicators.reactive = false;
AggregateMenu._indicators.disconnect(_onScrollEventId);
_onScrollEventId = 0;
}
}

View File

@ -1,12 +0,0 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Change the volume by scrolling anywhere on the System Tray.\n\nWith this extension, you can scroll over Night Light, WiFi, Volume, Battery or any other icon in the system status tray to change the volume, instead of just the Volume icon.",
"extension-id": "scrovol",
"name": "Scrovol",
"shell-version": [
"3.36"
],
"url": "https://github.com/andyholmes/gnome-shell-extension-scrovol/",
"uuid": "scrovol@andyholmes.github.io",
"version": 3
}

View File

@ -1,93 +0,0 @@
/* -*- mode: js; js-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
Copyright (c) 2011-2012, Giovanni Campagna <scampa.giovanni@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the GNOME nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const Config = imports.misc.config;
const ExtensionUtils = imports.misc.extensionUtils;
/**
* initTranslations:
* @domain: (optional): the gettext domain to use
*
* Initialize Gettext to load translations from extensionsdir/locale.
* If @domain is not provided, it will be taken from metadata['gettext-domain']
*/
function initTranslations(domain) {
let extension = ExtensionUtils.getCurrentExtension();
domain = domain || extension.metadata['gettext-domain'];
// check if this extension was built with "make zip-file", and thus
// has the locale files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell
let localeDir = extension.dir.get_child('locale');
if (localeDir.query_exists(null))
Gettext.bindtextdomain(domain, localeDir.get_path());
else
Gettext.bindtextdomain(domain, Config.LOCALEDIR);
}
/**
* getSettings:
* @schema: (optional): the GSettings schema id
*
* Builds and return a GSettings schema for @schema, using schema files
* in extensionsdir/schemas. If @schema is not provided, it is taken from
* metadata['settings-schema'].
*/
function getSettings(schema) {
let extension = ExtensionUtils.getCurrentExtension();
schema = schema || extension.metadata['settings-schema'];
const GioSSS = Gio.SettingsSchemaSource;
// check if this extension was built with "make zip-file", and thus
// has the schema files in a subfolder
// otherwise assume that extension has been installed in the
// same prefix as gnome-shell (and therefore schemas are available
// in the standard folders)
let schemaDir = extension.dir.get_child('schemas');
let schemaSource;
if (schemaDir.query_exists(null))
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
GioSSS.get_default(),
false);
else
schemaSource = GioSSS.get_default();
let schemaObj = schemaSource.lookup(schema, true);
if (!schemaObj)
throw new Error('Schema ' + schema + ' could not be found for extension '
+ extension.metadata.uuid + '. Please check your installation.');
return new Gio.Settings({ settings_schema: schemaObj });
}

View File

@ -1,255 +0,0 @@
// tweaks-system-menu - Put Gnome Tweaks in the system menu.
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const Lang = imports.lang;
const BoxPointer = imports.ui.boxpointer;
const Main = imports.ui.main;
const PopupMenu = imports.ui.popupMenu;
const Shell = imports.gi.Shell;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Logger = Me.imports.logger;
const TweaksSystemMenuExtension = class TweaksSystemMenuExtension {
constructor() {
this._logger = null;
this._settings = null;
this._debugSettingChangedConnection = null;
this._positionSettingChangedConnection = null;
this._systemMenu = null;
this._applications = {
'tweaks': {
appName: 'org.gnome.tweaks.desktop',
check: Lang.bind(this, function() {
return true;
}),
getDefaultPosition: Lang.bind(this, function() {
return this._findMenuItemPosition(this._systemMenu._settingsItem)+1;
}),
preUpdatePosition: Lang.bind(this, function () {
if (this._applications['extensions'].menuItem !== undefined) {
this._moveMenuItemToEnd(this._applications['extensions'].menuItem);
}
}),
postUpdatePosition: Lang.bind(this, function () {
if (this._applications['extensions'].menuItem !== undefined) {
this._on_position_change('extensions');
}
})
},
'extensions': {
appName: 'org.gnome.Extensions.desktop',
check: Lang.bind(this, function() {
let gnome_shell_version = imports.misc.config.PACKAGE_VERSION;
let gnome_shell_major = /^([0-9]+)\.([0-9]+)(\.([0-9]+)(\..*)?)?$/.exec(gnome_shell_version)[1];
return gnome_shell_major >= 40;
}),
getDefaultPosition: Lang.bind(this, function() {
if (this._applications['tweaks'].menuItem !== undefined) {
return this._findMenuItemPosition(this._applications['tweaks'].menuItem)+1;
} else {
return this._applications['tweaks'].getDefaultPosition();
}
}),
preUpdatePosition: Lang.bind(this, function () { return; }),
postUpdatePosition: Lang.bind(this, function () { return; })
}
};
this._tweaksApp = null;
this._tweaksItem = null;
this._tweaksActivateConnection = null;
}
// Utilities
_findMenuItemPosition(item) {
let items = this._systemMenu.menu._getMenuItems();
for (let i=0; i < items.length; ++i) {
if (items[i] == item) {
this._logger.log_debug('_findMenuItemPosition('+item+') = '+i);
return i;
}
}
this._logger.log_debug('_findMenuItemPosition('+item+') = <null>');
return null;
}
_moveMenuItemToEnd(item) {
this._systemMenu.menu.moveMenuItem(item, this._systemMenu.menu._getMenuItems().length-1);
}
_getEnableSettingsName(appKey) {
return appKey+'-enable';
}
_getPositionSettingsName(appKey) {
return appKey+'-position';
}
// Enable/disable
enable() {
this._logger = new Logger.Logger('Tweaks-System-Menu');
this._settings = Convenience.getSettings();
this._on_debug_change();
this._logger.log_debug('enable()');
this._debugSettingChangedConnection = this._settings.connect('changed::debug',
this._on_debug_change.bind(this));
this._systemMenu = Main.panel.statusArea.aggregateMenu._system;
for (let appKey in this._applications) {
this._enableApp(appKey);
}
this._logger.log_debug('extension enabled');
}
_enableApp(appKey) {
let appData = this._applications[appKey];
if (! appData.check()) return;
this._logger.log_debug('_enableApp('+appKey+')');
appData.enableSettingChangedConnection = this._settings.connect('changed::'+this._getEnableSettingsName(appKey),
Lang.bind(this, function() {
this._on_enable_change(appKey);
}));
appData.positionSettingChangedConnection = this._settings.connect('changed::'+this._getPositionSettingsName(appKey),
Lang.bind(this, function() {
this._on_position_change(appKey);
}));
if (this._settings.get_boolean(this._getEnableSettingsName(appKey))) {
this._showItem(appKey);
}
}
disable() {
this._logger.log_debug('disable()');
for (let appKey in this._applications) {
this._disableApp(appKey);
}
this._systemMenu = null;
this._settings.disconnect(this._debugSettingChangedConnection);
this._debugSettingChangedConnection = null;
this._settings = null;
this._logger.log_debug('extension disabled');
this._logger = null;
}
_disableApp(appKey) {
let appData = this._applications[appKey];
if (! appData.check()) return;
this._logger.log_debug('_disableApp('+appKey+')');
this._hideItem(appKey);
if (appData.enableSettingChangedConnection !== undefined) {
this._settings.disconnect(appData.enableSettingChangedConnection);
delete appData.enableSettingChangedConnection;
}
if (appData.positionSettingChangedConnection !== undefined) {
this._settings.disconnect(appData.positionSettingChangedConnection);
delete appData.positionSettingChangedConnection;
}
}
// Show/hide item
_showItem(appKey) {
this._logger.log_debug('_showItem('+appKey+')');
let appData = this._applications[appKey];
appData.appInfo = Shell.AppSystem.get_default().lookup_app(appData.appName);
if (appData.appInfo) {
let name = appData.appInfo.get_name();
let icon = appData.appInfo.app_info.get_icon().names[0];
appData.menuItem = new PopupMenu.PopupImageMenuItem(name, icon);
appData.activateConnection = appData.menuItem.connect('activate', Lang.bind(this, function() {
this._on_activate(appKey);
}));
this._systemMenu.menu.addMenuItem(appData.menuItem);
this._on_position_change(appKey);
} else {
this._logger.log(appData.appName+' is missing');
}
}
_hideItem(appKey) {
this._logger.log_debug('_hideItem('+appKey+')');
let appData = this._applications[appKey];
if (appData.menuItem !== undefined) {
appData.menuItem.disconnect(appData.activateConnection);
delete appData.activateConnection;
this._systemMenu.menu._getMenuItems().splice(this._findMenuItemPosition(appData.menuItem), 1);
appData.menuItem.destroy();
delete appData.menuItem;
}
}
// Event handlers
_on_debug_change() {
this._logger.set_debug(this._settings.get_boolean('debug'));
this._logger.log_debug('debug = '+this._logger.get_debug());
}
_on_enable_change(appKey) {
let appData = this._applications[appKey];
let enable = this._settings.get_boolean(this._getEnableSettingsName(appKey));
this._logger.log_debug('_on_enable_change('+appKey+'): enable=' + enable);
if (enable) {
this._showItem(appKey);
} else {
this._hideItem(appKey);
}
}
_on_position_change(appKey) {
let appData = this._applications[appKey];
let position = this._settings.get_int(this._getPositionSettingsName(appKey));
this._logger.log_debug('_on_position_change('+appKey+'): settings position=' + position);
this._moveMenuItemToEnd(appData.menuItem);
appData.preUpdatePosition();
if (position == -1) {
position = appData.getDefaultPosition();
this._logger.log_debug('_on_position_change('+appKey+'): automatic position=' + position);
}
// let curPosition = this._findMenuItemPosition(appData.menuItem);
// if (curPosition < position) {
// position -= 1;
// }
// this._logger.log_debug('_on_position_change('+appKey+'): ajusted position=' + position);
this._systemMenu.menu.moveMenuItem(appData.menuItem, position);
appData.postUpdatePosition();
}
_on_activate(appKey) {
let appData = this._applications[appKey];
this._logger.log_debug('_on_activate('+appKey+')');
this._systemMenu.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
Main.overview.hide();
appData.appInfo.activate();
}
};
function init() {
return new TweaksSystemMenuExtension();
}

View File

@ -1,73 +0,0 @@
// meson-gse - Library for gnome-shell extensions
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const ExtensionUtils = imports.misc.extensionUtils;
const GLib = imports.gi.GLib;
const Me = ExtensionUtils.getCurrentExtension();
var Logger = class MesonGseLogger {
constructor(title) {
this._first_log = true;
this._title = title;
this._debug = false;
}
get_version() {
return Me.metadata['version']+' / git '+Me.metadata['vcs_revision'];
}
log(text) {
if (this._first_log) {
this._first_log = false;
let msg = 'version ' + this.get_version();
let gnomeShellVersion = imports.misc.config.PACKAGE_VERSION;
if (gnomeShellVersion != undefined) {
msg += ' on Gnome-Shell ' + gnomeShellVersion;
}
let gjsVersion = imports.system.version;
if (gjsVersion != undefined) {
let gjsVersionMajor = Math.floor(gjsVersion / 10000);
let gjsVersionMinor = Math.floor((gjsVersion % 10000) / 100);
let gjsVersionPatch = gjsVersion % 100;
msg +=( ' / gjs ' + gjsVersionMajor
+ '.' +gjsVersionMinor
+ '.' +gjsVersionPatch
+ ' ('+gjsVersion+')');
}
let sessionType = GLib.getenv('XDG_SESSION_TYPE');
if (sessionType != undefined) {
msg += ' / ' + sessionType;
}
this.log(msg);
}
log(''+this._title+': '+text);
}
log_debug(text) {
if (this._debug) {
this.log(text);
}
}
set_debug(debug) {
this._debug = debug;
}
get_debug() {
return this._debug;
}
};

View File

@ -1,17 +0,0 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Put Gnome Tweaks and Extensions (on Shell 40 and later) in the System menu.",
"gettext-domain": "tweaks-system-menu",
"name": "Tweaks & Extensions in System Menu",
"settings-schema": "org.gnome.shell.extensions.tweaks-system-menu",
"shell-version": [
"3.36",
"3.35.92",
"3.38",
"40.0"
],
"url": "https://github.com/F-i-f/tweaks-system-menu",
"uuid": "tweaks-system-menu@extensions.gnome-shell.fifi.org",
"vcs_revision": "v15-0-ge3b04c7",
"version": 15
}

View File

@ -1,181 +0,0 @@
// Tweaks-system-menu - Put Gnome Tweaks in the system menu.
// Copyright (C) 2019-2021 Philippe Troin (F-i-f on Github)
//
// 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 3 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 <https://www.gnu.org/licenses/>.
const Lang = imports.lang;
const Gio = imports.gi.Gio;
const GObject = imports.gi.GObject;
const Gtk = imports.gi.Gtk;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']);
const _ = Gettext.gettext;
const Logger = Me.imports.logger;
const TweaksSystemMenuSettings = GObject.registerClass(class TweaksSystemMenuSettings extends Gtk.Grid {
_addEntry(ypos, setting_prefix, enable_label_val, position_label_val) {
let enable_setting = setting_prefix + '-enable';
let enable_sschema = this._settings.settings_schema.get_key(enable_setting);
let descr = _(enable_sschema.get_description());
let enable_label = new Gtk.Label({
label: enable_label_val,
halign: Gtk.Align.START
});
enable_label.set_tooltip_text(descr);
let enable_control = new Gtk.Switch({halign: Gtk.Align.END});
enable_control.set_tooltip_text(descr);
this.attach(enable_label, 1, ypos, 1, 1);
this.attach(enable_control, 2, ypos, 1, 1);
this._settings.bind(enable_setting, enable_control,
'active', Gio.SettingsBindFlags.DEFAULT);
ypos += 1
let position_setting = setting_prefix + '-position';
let position_sschema = this._settings.settings_schema.get_key(position_setting);
descr = _(position_sschema.get_description());
let position_label = new Gtk.Label({
label: position_label_val,
halign: Gtk.Align.START,
margin_start: 25
});
position_label.set_tooltip_text(descr);
let position_range = position_sschema.get_range().deep_unpack()[1].deep_unpack()
let position_control = new Gtk.SpinButton({
adjustment: new Gtk.Adjustment({
lower: position_range[0],
upper: position_range[1],
step_increment: 1
}),
halign: Gtk.Align.END
});
position_control.set_tooltip_text(descr);
this.attach(position_label, 1, ypos, 1, 1);
this.attach(position_control, 2, ypos, 1, 1);
this._settings.bind(position_setting, position_control,
'value', Gio.SettingsBindFlags.DEFAULT);
ypos += 1
this._settings.connect('changed::'+enable_setting, Lang.bind(this, function(settings, name) {
let val = settings.get_boolean(name);
position_label.set_sensitive(val);
position_control.set_sensitive(val);
}));
return ypos;
}
setup() {
let gnome_shell_version = imports.misc.config.PACKAGE_VERSION;
let gnome_shell_major = /^([0-9]+)\.([0-9]+)(\.([0-9]+)(\..*)?)?$/.exec(gnome_shell_version)[1];
this.margin_top = 12;
this.margin_bottom = this.margin_top;
this.margin_start = 48;
this.margin_end = this.margin_start;
this.row_spacing = 6;
this.column_spacing = this.row_spacing;
this.orientation = Gtk.Orientation.VERTICAL;
this._settings = Convenience.getSettings();
this._logger = new Logger.Logger('Tweaks-System-Menu/prefs');
this._logger.set_debug(this._settings.get_boolean('debug'));
let ypos = 1;
let descr;
this.title_label = new Gtk.Label({
use_markup: true,
label: '<span size="large" weight="heavy">'
+_('Tweaks &amp; Extensions in System Menu')+'</span>',
hexpand: true,
halign: Gtk.Align.CENTER
});
this.attach(this.title_label, 1, ypos, 2, 1);
ypos += 1;
this.version_label = new Gtk.Label({
use_markup: true,
label: '<span size="small">'+_('Version')
+ ' ' + this._logger.get_version() + '</span>',
hexpand: true,
halign: Gtk.Align.CENTER,
});
this.attach(this.version_label, 1, ypos, 2, 1);
ypos += 1;
this.link_label = new Gtk.Label({
use_markup: true,
label: '<span size="small"><a href="'+Me.metadata.url+'">'
+ Me.metadata.url + '</a></span>',
hexpand: true,
halign: Gtk.Align.CENTER,
margin_bottom: this.margin_bottom
});
this.attach(this.link_label, 1, ypos, 2, 1);
ypos += 1;
ypos = this._addEntry(ypos, 'tweaks', _("Show Tweaks:"), _("Tweaks position:"));
if (gnome_shell_major >= 40) {
ypos = this._addEntry(ypos, 'extensions', _("Show Extensions:"), _("Extensions position:"));
}
descr = _(this._settings.settings_schema.get_key('debug').get_description());
this.debug_label = new Gtk.Label({label: _("Debug:"), halign: Gtk.Align.START});
this.debug_label.set_tooltip_text(descr);
this.debug_control = new Gtk.Switch({halign: Gtk.Align.END});
this.debug_control.set_tooltip_text(descr);
this.attach(this.debug_label, 1, ypos, 1, 1);
this.attach(this.debug_control, 2, ypos, 1, 1);
this._settings.bind('debug', this.debug_control, 'active', Gio.SettingsBindFlags.DEFAULT);
ypos += 1;
this.copyright_label = new Gtk.Label({
use_markup: true,
label: '<span size="small">'
+ _('Copyright © 2019-2021 Philippe Troin (<a href="https://github.com/F-i-f">F-i-f</a> on GitHub)')
+ '</span>',
hexpand: true,
halign: Gtk.Align.CENTER,
margin_top: this.margin_bottom
});
this.attach(this.copyright_label, 1, ypos, 2, 1);
ypos += 1;
}
});
function init() {
Convenience.initTranslations();
}
function buildPrefsWidget() {
let widget = new TweaksSystemMenuSettings();
widget.setup();
// show_all() is only available/necessary on GTK < 4.0.
if (widget.show_all !== undefined) {
widget.show_all();
}
return widget;
}

View File

@ -1,38 +0,0 @@
<schemalist gettext-domain="tweaks-system-menu">
<schema id="org.gnome.shell.extensions.tweaks-system-menu" path="/org/gnome/shell/extensions/tweaks-system-menu/">
<key name="tweaks-enable" type="b">
<default>true</default>
<summary>Tweaks should be shown.</summary>
<description>If set, the Gnome Tweaks button is
shown.</description>
</key>
<key name="tweaks-position" type="i">
<default>-1</default>
<range min="-1" max="99"/>
<summary>Position of the Tweaks button.</summary>
<description>If set to -1, the position is automatic: Tweaks
will show up after Settings. If set to zero or more, the actual
launcher position on the system menu.</description>
</key>
<key name="extensions-enable" type="b">
<default>true</default>
<summary>Extensions should be shown.</summary>
<description>If set, the Shell Extensions button is
shown.</description>
</key>
<key name="extensions-position" type="i">
<default>-1</default>
<range min="-1" max="99"/>
<summary>Position of the Extensions button.</summary>
<description>If set to -1, the position is automatic: Extensions
will show up after Tweaks (if shown), or Settings. If set to
zero or more, the actual launcher position on the system
menu.</description>
</key>
<key name="debug" type="b">
<default>false</default>
<summary>Debugging.</summary>
<description>Enable debugging for the extension.</description>
</key>
</schema>
</schemalist>

View File

@ -17,6 +17,7 @@ var DesktopLabel = GObject.registerClass(
this.label_actor = this._label
this.setText(text || 'Desktop')
this.add_style_class_name('desktop-name-label')
}
setText(text) {
@ -41,6 +42,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' })
this.add_child(this._indicators)
this.add_style_class_name('system-tray-icons')
this._sync()
}
@ -62,7 +64,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators.add_child(ibtn)
icon.connect('destroy', () => { ibtn.destroy() })
ibtn.connect('button-release-event', (actor, event) => { icon.click(event) })
ibtn.connect('button-release-event', (actor, event) => icon.click(event))
icon.set_reactive(true)
icon.set_height(this.size)
@ -83,7 +85,7 @@ var TrayIndicator = GObject.registerClass(
}
forEach(callback) {
this._icons.forEach(icon => { callback.call(null, icon) })
this._icons.forEach(icon => callback.call(null, icon))
}
}
)
@ -97,6 +99,7 @@ var WindowControls = GObject.registerClass(
this.add_child(this._controls)
this.add_style_class_name('window-controls')
this.remove_style_class_name('panel-button')
}
_addButton(action) {

View File

@ -1 +0,0 @@
var VERSION = parseInt(imports.misc.config.PACKAGE_VERSION.replace(/^3\./, '').split('.')[0])

View File

@ -2,7 +2,7 @@ const Gettext = imports.gettext
const GObject = imports.gi.GObject
const Gio = imports.gi.Gio
const Config = imports.misc.config
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
var SettingsManager = GObject.registerClass(
class UniteSettings extends Gio.Settings {
@ -89,22 +89,23 @@ var PreferencesManager = GObject.registerClass(
)
function initTranslations(domain) {
let textDomain = domain || Unite.metadata['gettext-domain']
let localeDir = Unite.dir.get_child('locale')
let textDomain = domain || Me.metadata['gettext-domain']
let localeDir = Me.dir.get_child('locale')
if (localeDir.query_exists(null))
if (localeDir.query_exists(null)) {
localeDir = localeDir.get_path()
else
} else {
localeDir = Config.LOCALEDIR
}
Gettext.bindtextdomain(textDomain, localeDir)
}
function getSettings(schema) {
schema = schema || Unite.metadata['settings-schema']
schema = schema || Me.metadata['settings-schema']
let gioSSS = Gio.SettingsSchemaSource
let schemaDir = Unite.dir.get_child('schemas')
let schemaDir = Me.dir.get_child('schemas')
let schemaSource = gioSSS.get_default()
if (schemaDir.query_exists(null)) {
@ -115,7 +116,7 @@ function getSettings(schema) {
let schemaObj = schemaSource.lookup(schema, true)
if (!schemaObj) {
let metaId = Unite.metadata.uuid
let metaId = Me.metadata.uuid
let message = `Schema ${schema} could not be found for extension ${metaId}.`
throw new Error(`${message} Please check your installation.`)

View File

@ -1,9 +1,9 @@
const GObject = imports.gi.GObject
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const PanelManager = Unite.imports.panel.PanelManager
const LayoutManager = Unite.imports.layout.LayoutManager
const WindowManager = Unite.imports.window.WindowManager
const Me = imports.misc.extensionUtils.getCurrentExtension()
const PanelManager = Me.imports.panel.PanelManager
const LayoutManager = Me.imports.layout.LayoutManager
const WindowManager = Me.imports.window.WindowManager
var UniteExtension = GObject.registerClass(
class UniteExtension extends GObject.Object {

View File

@ -2,22 +2,33 @@ const Bytes = imports.byteArray
const Gio = imports.gi.Gio
const GLib = imports.gi.GLib
const St = imports.gi.St
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Unite.imports.convenience
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const SETTINGS = Convenience.getSettings()
const WM_PREFS = Convenience.getPreferences()
const USER_CONFIG = GLib.get_user_config_dir()
const USER_STYLES_GTK3 = `${USER_CONFIG}/gtk-3.0/gtk.css`
const USER_STYLES_GTK4 = `${USER_CONFIG}/gtk-4.0/gtk.css`
const GTK_VERSIONS = [3, 4]
const USER_CONFIGS = GLib.get_user_config_dir()
function filePath(parts) {
const parse = part => part ? part.replace(/^@/, '') : ''
const paths = [Me.path].concat(parts).map(parse)
return GLib.build_filenamev(paths)
}
function userStylesPath(version) {
return GLib.build_filenamev([USER_CONFIGS, `gtk-${version}.0`, 'gtk.css'])
}
function fileExists(path) {
return GLib.file_test(path, GLib.FileTest.EXISTS)
}
function getGioFile(path) {
const absPath = GLib.build_filenamev([Unite.path, path])
const absPath = filePath(path)
if (fileExists(absPath)) {
return Gio.file_new_for_path(absPath)
@ -42,13 +53,16 @@ function setFileContents(path, contents) {
GLib.file_set_contents(path, contents)
}
function resetGtkStyles(filepath) {
function resetGtkStyles() {
GTK_VERSIONS.forEach(version => {
const filepath = userStylesPath(version)
let style = getFileContents(filepath)
style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '')
style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '')
setFileContents(filepath, style)
})
}
var Signals = class Signals {
@ -116,7 +130,70 @@ var Settings = class Settings extends Signals {
}
}
var ShellStyle = class ShellStyle {
var Feature = class Feature {
constructor(setting, callback) {
this._settingsKey = setting
this._checkActive = callback
}
}
var Features = class Features {
constructor() {
this.features = []
this.settings = new Settings()
}
add(klass) {
const feature = new klass()
this.features.push(feature)
const setting = feature._settingsKey
const checkCb = feature._checkActive
feature.activated = false
const isActive = () => {
return checkCb.call(null, this.settings.get(setting))
}
const onChange = () => {
const active = isActive()
if (active && !feature.activated) {
feature.activated = true
return feature.activate()
}
if (!active && feature.activated) {
feature.activated = false
return feature.destroy()
}
}
feature._doActivate = () => {
this.settings.connect(setting, onChange.bind(feature))
onChange()
}
feature._doDestroy = () => {
if (feature.activated) {
feature.destroy()
feature.activated = false
}
}
}
activate() {
this.features.forEach(feature => feature._doActivate())
}
destroy() {
this.features.forEach(feature => feature._doDestroy())
this.settings.disconnectAll()
}
}
class ShellStyle {
constructor(path) {
this.file = getGioFile(path)
}
@ -138,7 +215,7 @@ var ShellStyle = class ShellStyle {
}
}
var WidgetStyle = class WidgetStyle {
class WidgetStyle {
constructor(widget, style) {
this.widget = widget
this.style = style
@ -159,16 +236,27 @@ var WidgetStyle = class WidgetStyle {
}
}
var GtkStyle = class GtkStyle {
constructor(filepath, name, contents) {
this.filepath = filepath
this.contents = `/* UNITE ${name} */\n${contents}\n/* ${name} UNITE */\n`
class GtkStyle {
constructor(version, name, data) {
const content = this.parse(data, version)
this.filepath = userStylesPath(version)
this.contents = `/* UNITE ${name} */\n${content}\n/* ${name} UNITE */\n`
}
get existing() {
return getFileContents(this.filepath)
}
parse(data, ver) {
if (data.startsWith('@/')) {
const path = filePath(['styles', `gtk${ver}`, data])
return `@import url('${path}');`
} else {
return data
}
}
load() {
const style = this.contents + this.existing
setFileContents(this.filepath, style)
@ -180,6 +268,21 @@ var GtkStyle = class GtkStyle {
}
}
class GtkStyles {
constructor(name, data, versions) {
const items = [].concat(versions).filter(ver => GTK_VERSIONS.includes(ver))
this.styles = items.map(ver => new GtkStyle(ver, name, data))
}
load() {
this.styles.forEach(style => style.load())
}
unload() {
this.styles.forEach(style => style.unload())
}
}
var Styles = class Styles {
constructor() {
this.styles = new Map()
@ -211,9 +314,13 @@ var Styles = class Styles {
}
}
addShellStyle(name, path) {
addShellStyle(name, data) {
if (data.startsWith('@/')) {
this.deleteStyle(name)
this.setStyle(name, ShellStyle, path)
this.setStyle(name, ShellStyle, data)
} else {
this.addWidgetStyle(name, Main.uiGroup, data)
}
}
addWidgetStyle(name, widget, styles) {
@ -221,14 +328,9 @@ var Styles = class Styles {
this.setStyle(name, WidgetStyle, widget, styles)
}
addGtk3Style(name, contents) {
addGtkStyle(name, contents, versions = GTK_VERSIONS) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK3, name, contents)
}
addGtk4Style(name, contents) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK4, name, contents)
this.setStyle(name, GtkStyles, name, contents, versions)
}
removeAll() {
@ -238,5 +340,4 @@ var Styles = class Styles {
}
}
resetGtkStyles(USER_STYLES_GTK3)
resetGtkStyles(USER_STYLES_GTK4)
resetGtkStyles()

View File

@ -1,276 +1,220 @@
const GObject = imports.gi.GObject
const St = imports.gi.St
const Clutter = imports.gi.Clutter
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
function actorHasClass(actor, name) {
return actor.has_style_class_name && actor.has_style_class_name(name)
var WidgetArrow = class WidgetArrow {
constructor(widget) {
this.widget = widget || {}
if (!this.widget.hasOwnProperty('_arrow')) {
this._findActor(this.widget)
}
}
get arrow() {
return this.widget._arrow || {}
}
_findActor(widget) {
if (widget.hasOwnProperty('_arrow')) {
return this.widget._arrow = widget._arrow
}
const actor = widget.last_child
const klass = actor && actor.has_style_class_name
const cname = name => klass && actor.has_style_class_name(name)
if (cname('popup-menu-arrow')) {
return this.widget._arrow = actor
}
actor && this._findActor(actor)
}
hide() {
if (!this.widget._arrowRemoved) {
this.arrow.visible = false
this.widget._arrowRemoved = true
}
}
show() {
if (this.widget._arrowRemoved) {
this.arrow.visible = true
delete this.widget._arrowRemoved
}
}
}
function getWidgetArrow(widget) {
let arrow = widget._arrow
var Messages = class Messages extends Handlers.Feature {
constructor() {
super('notifications-position', setting => setting != 'center')
}
if (!arrow) {
const last = widget.get_n_children() - 1
const actor = widget.get_children()[last]
activate() {
this.settings = new Handlers.Settings()
if (actor) {
if (actorHasClass(actor, 'popup-menu-arrow')) {
arrow = actor
this.settings.connect(
'notifications-position', this._onPositionChange.bind(this)
)
this._onPositionChange()
}
get position() {
const mapping = { left: 'START', right: 'END' }
const setting = this.settings.get('notifications-position')
return mapping[setting]
}
_onPositionChange() {
const banner = Main.messageTray._bannerBin
const context = St.ThemeContext.get_for_stage(global.stage)
const position = Clutter.ActorAlign[this.position]
banner.set_x_align(position)
banner.set_width(390 * context.scale_factor)
}
destroy() {
const banner = Main.messageTray._bannerBin
const position = Clutter.ActorAlign.CENTER
banner.set_x_align(position)
banner.set_width(-1)
this.settings.disconnectAll()
}
}
var AppMenuIcon = class AppMenuIcon extends Handlers.Feature {
constructor() {
super('hide-app-menu-icon', setting => setting == true)
Override.inject(this, 'layout', 'AppMenuIconClassic')
}
activate() {
AppMenu._iconBox.hide()
}
destroy() {
AppMenu._iconBox.show()
}
}
var DropdownArrows = class DropdownArrows extends Handlers.Feature {
constructor() {
super('hide-dropdown-arrows', setting => setting == true)
Override.inject(this, 'layout', 'DropdownArrows')
}
activate() {
this.signals = new Handlers.Signals()
for (const box of Main.panel.get_children()) {
this.signals.connect(box, 'actor_added', this._onActorAdded.bind(this))
}
this._onActorAdded()
}
get arrows() {
const items = Main.panel.statusArea
const names = Object.keys(items).filter(this._handleWidget.bind(this))
return names.map(name => new WidgetArrow(items[name]))
}
_handleWidget(name) {
return !name.startsWith('unite')
}
_onActorAdded() {
this.arrows.forEach(arrow => arrow.hide())
}
destroy() {
this.arrows.forEach(arrow => arrow.show())
this.signals.disconnectAll()
}
}
var PanelSpacing = class PanelSpacing extends Handlers.Feature {
constructor() {
super('reduce-panel-spacing', setting => setting == true)
Override.inject(this, 'layout', 'PanelSpacing')
Override.inject(this, 'layout', 'PanelSpacingClassic')
}
activate() {
this.styles = new Handlers.Styles()
this._injectStyles()
Main.panel._addStyleClassName('reduce-spacing')
this._syncLayout()
}
_injectStyles() {
this.styles.addShellStyle('spacing', '@/styles/shell/spacing.css')
}
_syncLayout() {
// Fix dateMenu paddings when reduce spacing enabled
// when returning from lock screen
const dateMenu = Main.panel.statusArea.dateMenu
const paddings = this._dateMenuPadding
if (!paddings) {
this._dateMenuPadding = [dateMenu._minHPadding, dateMenu._natHPadding]
dateMenu._minHPadding = 0
dateMenu._natHPadding = 0
} else {
arrow = getWidgetArrow(actor)
}
}
dateMenu._minHPadding = paddings[0]
dateMenu._natHPadding = paddings[1]
this._dateMenuPadding = null
}
if (arrow && !widget.hasOwnProperty('_arrow')) {
widget._arrow = arrow
dateMenu.queue_relayout()
}
return arrow
}
destroy() {
Main.panel._removeStyleClassName('reduce-spacing')
this.styles.removeAll()
function toggleWidgetArrow(widget, hide) {
const arrow = widget && getWidgetArrow(widget)
if (arrow) {
if (hide && !widget._arrowHandled) {
arrow.visible = false
widget._arrowHandled = true
}
if (!hide && widget._arrowHandled) {
arrow.visible = true
delete widget._arrowHandled
}
this._syncLayout()
}
}
var LayoutManager = GObject.registerClass(
class UniteLayoutManager extends GObject.Object {
_init() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.styles = new Handlers.Styles()
this.features = new Handlers.Features()
this.signals.connect(
Main.panel._leftBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.features.add(Messages)
this.features.add(AppMenuIcon)
this.features.add(DropdownArrows)
this.features.add(PanelSpacing)
this.signals.connect(
Main.panel._centerBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.signals.connect(
Main.panel._rightBox, 'actor_added', this._onHideDropdownArrows.bind(this)
)
this.settings.connect(
'notifications-position', this._onNotificationsChange.bind(this)
)
this.settings.connect(
'hide-app-menu-icon', this._onHideAppMenuIcon.bind(this)
)
if (VERSION < 40) {
this.settings.connect(
'hide-app-menu-arrow', this._onHideAppMenuArrow.bind(this)
)
this.settings.connect(
'hide-aggregate-menu-arrow', this._onHideAggMenuArrow.bind(this)
)
this.settings.connect(
'hide-dropdown-arrows', this._onHideDropdownArrows.bind(this)
)
}
this.settings.connect(
'reduce-panel-spacing', this._onChangeStyles.bind(this)
)
if (VERSION < 36) {
this.settings.connect(
'use-system-fonts', this._onChangeStyles.bind(this)
)
this.signals.connect(
GtkSettings, 'notify::gtk-font-name', this._onChangeStyles.bind(this)
)
}
}
_onNotificationsChange() {
const setting = this.settings.get('notifications-position')
if (setting != 'center') {
const context = St.ThemeContext.get_for_stage(global.stage)
const banner = Main.messageTray._bannerBin
const mappings = { left: 'START', right: 'END' }
const position = mappings[setting]
banner.set_x_align(Clutter.ActorAlign[position])
banner.set_width(390 * context.scale_factor)
} else {
this._resetNotifications()
}
}
_onHideAppMenuIcon() {
const setting = this.settings.get('hide-app-menu-icon')
if (setting) {
AppMenu._iconBox.hide()
} else {
this._resetAppMenuIcon()
}
}
_onHideAppMenuArrow() {
const setting = this.settings.get('hide-app-menu-arrow')
if (setting) {
toggleWidgetArrow(AppMenu, true)
} else {
this._resetAppMenuArrow()
}
}
_onHideAggMenuArrow() {
const setting = this.settings.get('hide-aggregate-menu-arrow')
if (setting) {
toggleWidgetArrow(AggMenu, true)
} else {
this._resetAggMenuArrow()
}
}
_onHideDropdownArrows() {
const setting = this.settings.get('hide-dropdown-arrows')
if (setting) {
for (const [name, widget] of Object.entries(Main.panel.statusArea)) {
if (name != 'aggregateMenu' && name != 'appMenu') {
toggleWidgetArrow(widget, true)
}
}
} else {
this._resetDropdownArrows()
}
}
_onChangeStyles() {
const fonts = this.settings.get('use-system-fonts')
const space = this.settings.get('reduce-panel-spacing')
this._resetStyles()
if (VERSION < 36 && fonts) {
const font = GtkSettings.gtk_font_name.replace(/\s\d+$/, '')
this.styles.addWidgetStyle('uiGroup', Main.uiGroup, `font-family: ${font};`)
this.styles.addWidgetStyle('panel', Main.panel, 'font-size: 11.25pt;')
}
if (space) {
Main.panel._addStyleClassName('small-spacing')
}
if (VERSION < 34) {
Main.panel._addStyleClassName('extra-spacing')
}
this._syncStyles()
}
_resetNotifications() {
const banner = Main.messageTray._bannerBin
banner.set_x_align(Clutter.ActorAlign.CENTER)
banner.set_width(-1)
}
_resetAppMenuIcon() {
AppMenu._iconBox.show()
}
_resetAppMenuArrow() {
toggleWidgetArrow(AppMenu, false)
}
_resetAggMenuArrow() {
toggleWidgetArrow(AggMenu, false)
}
_resetDropdownArrows() {
for (const [name, widget] of Object.entries(Main.panel.statusArea)) {
if (name != 'aggregateMenu' && name != 'appMenu') {
toggleWidgetArrow(widget, false)
}
}
}
_resetStyles() {
Main.panel._removeStyleClassName('small-spacing')
Main.panel._removeStyleClassName('extra-spacing')
this.styles.deleteStyle('uiGroup')
this.styles.deleteStyle('panel')
}
// Fix for panel spacing not applied until mouse-over
// Issue: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1708
_syncStyles() {
const space = this.settings.get('reduce-panel-spacing')
if (VERSION >= 34 && space) {
Object.values(Main.panel.statusArea).forEach((item) => {
if (item !== null) {
item.add_style_pseudo_class('hover')
item.remove_style_pseudo_class('hover')
}
})
}
Override.inject(this, 'layout', 'LayoutManager')
}
activate() {
this._onNotificationsChange()
this._onHideAppMenuIcon()
if (VERSION < 40) {
this._onHideAppMenuArrow()
this._onHideAggMenuArrow()
this._onHideDropdownArrows()
}
this._onChangeStyles()
this.features.activate()
}
destroy() {
this._resetNotifications()
this._resetAppMenuIcon()
if (VERSION < 40) {
this._resetAppMenuArrow()
this._resetAggMenuArrow()
this._resetDropdownArrows()
}
this._resetStyles()
this._syncStyles()
this.signals.disconnectAll()
this.settings.disconnectAll()
this.styles.removeAll()
this.features.destroy()
}
}
)

View File

@ -9,9 +9,9 @@
"3.32",
"3.36",
"3.38",
"40.0"
"40"
],
"url": "https://github.com/hardpixel/unite-shell",
"uuid": "unite@hardpixel.eu",
"version": 48
"version": 53
}

View File

@ -0,0 +1,49 @@
const Config = imports.misc.config
const Me = imports.misc.extensionUtils.getCurrentExtension()
var VERSION = parseInt(Config.PACKAGE_VERSION.replace(/^3\./, '').split('.')[0])
var Injection = class Injection {
__override__(ctx) {
if (!this.active) return
this._replace = (key, fn) => {
const method = fn || this[key]
ctx[key] = (...args) => method.call(ctx, ...args)
}
this._prepend = (key, fn) => {
const method = fn || this[key]
const target = ctx[key]
ctx[key] = (...args) => {
method.call(ctx, ...args)
return target.call(ctx, ...args)
}
}
this._append = (key, fn) => {
const method = fn || this[key]
const target = ctx[key]
ctx[key] = (...args) => {
target.call(ctx, ...args)
return method.call(ctx, ...args)
}
}
this._init(ctx)
}
}
function inject(ctx, path, name) {
const klass = Me.imports.overrides[path][name]
if (klass) {
const instance = new klass()
instance.__override__(ctx)
} else {
const extension = Me.metadata.name
throw new Error(`${extension} Error: Override ${path}.${name} does not exist!`)
}
}

View File

@ -0,0 +1,197 @@
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu
const Handlers = Me.imports.handlers
const WidgetArrow = Me.imports.layout.WidgetArrow
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
const CLASSIC = global.session_mode == 'classic'
var AppMenuArrow = class AppMenuArrow extends Handlers.Feature {
constructor() {
super('hide-app-menu-arrow', setting => setting == true)
}
activate() {
this.arrow = new WidgetArrow(AppMenu)
this.arrow.hide()
}
destroy() {
this.arrow.show()
}
}
var AggMenuArrow = class AggMenuArrow extends Handlers.Feature {
constructor() {
super('hide-aggregate-menu-arrow', setting => setting == true)
}
activate() {
this.arrow = new WidgetArrow(AggMenu)
this.arrow.hide()
}
destroy() {
this.arrow.show()
}
}
var SystemFonts = class SystemFonts extends Handlers.Feature {
constructor() {
super('use-system-fonts', setting => setting == true)
}
activate() {
this.signals = new Handlers.Signals()
this.styles = new Handlers.Styles()
this.signals.connect(
GtkSettings, 'notify::gtk-font-name', this._onFontsChange.bind(this)
)
this._onFontsChange()
}
get fontName() {
return GtkSettings.gtk_font_name.replace(/\s\d+$/, '')
}
_resetStyles() {
Main.panel._removeStyleClassName('system-fonts')
this.styles.removeAll()
}
_onFontsChange() {
this._resetStyles()
this.styles.addWidgetStyle('uiGroup', Main.uiGroup, `font-family: ${this.fontName};`)
this.styles.addWidgetStyle('panel', Main.panel, 'font-size: 11.25pt;')
Main.panel._addStyleClassName('system-fonts')
}
destroy() {
this.signals.disconnectAll()
this._resetStyles()
}
}
var DropdownArrows = class DropdownArrows extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._replace('_handleWidget')
}
_handleWidget(name) {
const ignored = ['aggregateMenu', 'appMenu']
return !name.startsWith('unite') && !ignored.includes(name)
}
}
var PanelSpacing = class PanelSpacing extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._prepend('activate', this._onActivate)
this._prepend('destroy', this._onDestroy)
this._replace('_injectStyles')
this._replace('_syncLayout')
}
_injectStyles() {
this.styles.addShellStyle('spacingLegacy', '@/overrides/styles/spacing-legacy.css')
}
_syncLayout() {
// Fix for panel spacing not applied until mouse-over
// Issue: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/1708
if (VERSION >= 34) {
Object.values(Main.panel.statusArea).forEach(item => {
if (item !== null) {
item.add_style_pseudo_class('hover')
item.remove_style_pseudo_class('hover')
}
})
}
}
_onActivate() {
if (CLASSIC == true) {
Main.panel._addStyleClassName('classic-spacing')
}
if (VERSION < 34) {
Main.panel._addStyleClassName('extra-spacing')
}
}
_onDestroy() {
Main.panel._removeStyleClassName('classic-spacing')
Main.panel._removeStyleClassName('extra-spacing')
}
}
var PanelSpacingClassic = class PanelSpacingClassic extends Override.Injection {
get active() {
return CLASSIC == true
}
_init() {
this._prepend('activate', this._onActivate)
this._prepend('destroy', this._onDestroy)
this._prepend('_injectStyles')
}
_injectStyles() {
this.styles.addShellStyle('spacingClassic', '@/overrides/styles/spacing-classic.css')
}
_onActivate() {
AppMenu.add_style_class_name('app-menu-button')
AppMenu._iconBox.hide()
}
_onDestroy() {
AppMenu.remove_style_class_name('app-menu-button')
}
}
var AppMenuIconClassic = class AppMenuIconClassic extends Override.Injection {
get active() {
return CLASSIC == true
}
_init() {
this._prepend('activate', this._resizeAppIcon)
}
_resizeAppIcon() {
AppMenu._iconBox.set_size(16, 16)
}
}
var LayoutManager = class LayoutManager extends Override.Injection {
get active() {
return true
}
_init(ctx) {
if (VERSION < 40) {
ctx.features.add(AppMenuArrow)
ctx.features.add(AggMenuArrow)
}
if (VERSION < 36) {
ctx.features.add(SystemFonts)
}
}
}

View File

@ -0,0 +1,27 @@
const Gi = imports._gi
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var ExtendLeftBox = class ExtendLeftBox extends Override.Injection {
get active() {
return VERSION < 38
}
_init() {
this._replace('_injectAllocate')
this._replace('_boxAllocate')
}
_injectAllocate() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box, flags) => {
Main.panel.vfunc_allocate.call(Main.panel, box, flags)
this._allocate(Main.panel, box, flags)
})
}
_boxAllocate(box, childBox, flags) {
box.allocate(childBox, flags)
}
}

View File

@ -0,0 +1,31 @@
const GLib = imports.gi.GLib
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var PrefsWidget = class PrefsWidget extends Override.Injection {
get active() {
return VERSION < 40
}
_init() {
this._replace('_loadTemplate')
}
_loadTemplate() {
const template = GLib.build_filenamev([Me.path, 'overrides', 'settings.ui'])
this._buildable.add_from_file(template)
this._container = this._getWidget('prefs_widget')
this.add(this._container)
if (VERSION >= 36) {
const fonts = this._getWidget('use-system-fonts-section')
fonts.set_no_show_all(true)
fonts.set_visible(false)
}
this.show_all()
}
}

View File

@ -0,0 +1,20 @@
#panelLeft .panel-button {
-natural-hpadding: 10px;
-minimum-hpadding: 8px;
padding-left: 10px;
padding-right: 10px;
}
#panel .app-menu-button {
-natural-hpadding: 4px;
-minimum-hpadding: 4px;
padding-left: 4px;
padding-right: 4px;
}
#panel #panelLeft #appMenu {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
padding-left: 0px;
padding-right: 0px;
}

View File

@ -0,0 +1,36 @@
#panel .panel-button {
-natural-hpadding: 8px;
-minimum-hpadding: 6px;
}
#panel .panel-button .system-status-icon {
padding-left: 0px;
padding-right: 0px;
}
#panel .panel-button .panel-status-indicators-box {
spacing: 12px;
}
#panel .panel-button .panel-status-indicators-box .panel-status-indicators-box {
spacing: 4px;
}
#panelRight .window-controls-container {
margin-left: 8px;
margin-right: 8px;
}
#panelRight .window-controls-container:last-child {
margin-right: 0px;
}
#panel.extra-spacing .panel-button .panel-status-indicators-box {
spacing: 10px;
}
#panel.classic-spacing #appMenu,
#panel.extra-spacing #appMenu, {
margin-left: 8px;
margin-right: 8px;
}

View File

@ -0,0 +1,23 @@
const Main = imports.ui.main
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Override = Me.imports.overrides.helper
const VERSION = Me.imports.overrides.helper.VERSION
var WindowManager = class WindowManager extends Override.Injection {
get active() {
return VERSION < 36
}
_init(ctx) {
ctx.signals.connect(
AppMenu._label, 'notify::text', this._onAppmenuChanged.bind(ctx)
)
}
_onAppmenuChanged() {
if (this.focusWindow) {
this.focusWindow.syncAppmenu()
}
}
}

View File

@ -10,56 +10,19 @@ const Shell = imports.gi.Shell
const AppSystem = imports.gi.Shell.AppSystem.get_default()
const WinTracker = imports.gi.Shell.WindowTracker.get_default()
const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Activities = Main.panel.statusArea.activities
const Buttons = Unite.imports.buttons
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Buttons = Me.imports.buttons
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
var PanelExtension = class PanelExtension {
constructor(settings, key, callback) {
this.activated = false
const isActive = () => {
return callback.call(null, settings.get(key))
var WindowButtons = class WindowButtons extends Handlers.Feature {
constructor() {
super('show-window-buttons', setting => setting != 'never')
}
const onChange = () => {
const active = isActive()
if (active && !this.activated) {
this.activated = true
return this._init()
}
if (!active && this.activated) {
this.activated = false
return this._destroy()
}
}
this.activate = () => {
settings.connect(key, onChange.bind(this))
onChange()
}
this.destroy = () => {
if (this.activated) {
this._destroy()
this.activated = false
}
}
}
}
var WindowButtons = class WindowButtons extends PanelExtension {
constructor({ settings }) {
const active = val => val != 'never'
super(settings, 'show-window-buttons', active)
}
_init() {
activate() {
this.theme = 'default-dark'
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -148,17 +111,14 @@ var WindowButtons = class WindowButtons extends PanelExtension {
_onPositionChange() {
const controls = this.controls.container
const container = controls.get_parent()
if (controls.reparent) {
controls.reparent(this.container)
} else {
const currentParent = controls.get_parent()
controls.add_style_class_name('window-controls-container')
if (currentParent) {
currentParent.remove_child(controls)
if (container) {
container.remove_child(controls)
this.container.add_child(controls)
}
}
if (this.index != null) {
this.container.set_child_at_index(controls, this.index)
@ -173,7 +133,7 @@ var WindowButtons = class WindowButtons extends PanelExtension {
this.controls.remove_style_class_name(this.theme)
this.theme = this.settings.get('window-buttons-theme')
const path = `themes/${this.theme}/stylesheet.css`
const path = `@/themes/${this.theme}/stylesheet.css`
this.styles.addShellStyle('windowButtons', path)
this.controls.add_style_class_name(this.theme)
@ -191,7 +151,7 @@ var WindowButtons = class WindowButtons extends PanelExtension {
}
}
_destroy() {
destroy() {
this.controls.destroy()
this.signals.disconnectAll()
@ -200,37 +160,30 @@ var WindowButtons = class WindowButtons extends PanelExtension {
}
}
var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'extend-left-box', active)
var ExtendLeftBox = class ExtendLeftBox extends Handlers.Feature {
constructor() {
super('extend-left-box', setting => setting == true)
Override.inject(this, 'panel', 'ExtendLeftBox')
}
_init() {
activate() {
this._default = Main.panel.__proto__.vfunc_allocate
this._injectAllocate()
if (VERSION < 37) {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box, flags) => {
Main.panel.vfunc_allocate.call(Main.panel, box, flags)
this._allocate(Main.panel, box, flags)
})
} else {
Main.panel.queue_relayout()
}
_injectAllocate() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', (box) => {
Main.panel.vfunc_allocate.call(Main.panel, box)
this._allocate(Main.panel, box)
})
}
Main.panel.queue_relayout()
}
_boxAllocate(box, childBox, flags) {
if (VERSION < 37) {
box.allocate(childBox, flags)
} else {
box.allocate(childBox)
}
}
_allocate(actor, box, flags) {
let leftBox = Main.panel._leftBox
@ -287,7 +240,7 @@ var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
this._boxAllocate(rightBox, childBox, flags)
}
_destroy() {
destroy() {
Main.panel.__proto__[Gi.hook_up_vfunc_symbol]('allocate', this._default)
this._default = null
@ -295,13 +248,12 @@ var ExtendLeftBox = class ExtendLeftBox extends PanelExtension {
}
}
var ActivitiesButton = class ActivitiesButton extends PanelExtension {
constructor({ settings }) {
const active = val => val != 'never'
super(settings, 'hide-activities-button', active)
var ActivitiesButton = class ActivitiesButton extends Handlers.Feature {
constructor() {
super('hide-activities-button', setting => Activities && setting != 'never')
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -352,7 +304,7 @@ var ActivitiesButton = class ActivitiesButton extends PanelExtension {
}
}
_destroy() {
destroy() {
if (!Main.overview.isDummy) {
Activities.container.show()
}
@ -362,13 +314,12 @@ var ActivitiesButton = class ActivitiesButton extends PanelExtension {
}
}
var DesktopName = class DesktopName extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'show-desktop-name', active)
var DesktopName = class DesktopName extends Handlers.Feature {
constructor() {
super('show-desktop-name', setting => setting == true)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.label = new Buttons.DesktopLabel()
@ -413,7 +364,7 @@ var DesktopName = class DesktopName extends PanelExtension {
this.label.setText(text)
}
_destroy() {
destroy() {
this.label.destroy()
this.signals.disconnectAll()
@ -421,13 +372,12 @@ var DesktopName = class DesktopName extends PanelExtension {
}
}
var TrayIcons = class TrayIcons extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'show-legacy-tray', active)
var TrayIcons = class TrayIcons extends Handlers.Feature {
constructor() {
super('show-legacy-tray', setting => setting == true)
}
_init() {
activate() {
this.tray = new Shell.TrayManager()
this.settings = new Handlers.Settings()
this.indicators = new Buttons.TrayIndicator()
@ -480,7 +430,7 @@ var TrayIcons = class TrayIcons extends PanelExtension {
this.indicators.forEach(this._desaturateIcon.bind(this))
}
_destroy() {
destroy() {
this.tray = null
System.gc()
@ -489,13 +439,12 @@ var TrayIcons = class TrayIcons extends PanelExtension {
}
}
var TitlebarActions = class TitlebarActions extends PanelExtension {
constructor({ settings }) {
const active = val => val == true
super(settings, 'enable-titlebar-actions', active)
var TitlebarActions = class TitlebarActions extends Handlers.Feature {
constructor() {
super('enable-titlebar-actions', setting => setting == true)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
@ -505,25 +454,19 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
}
_onButtonPressEvent(actor, event) {
if (Main.modalCount > 0 || actor != event.get_source()) {
return Clutter.EVENT_PROPAGATE
}
const focusWindow = global.unite.focusWindow
if (!focusWindow || !focusWindow.hideTitlebars) {
return Clutter.EVENT_PROPAGATE
}
const [mouseX, mouseY] = event.get_coords()
const ccount = event.get_click_count()
const button = event.get_button()
const clickOnChildren = Main.panel.get_children().some(({ x, y, width, height }) => {
return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height
})
if (clickOnChildren) {
return Clutter.EVENT_PROPAGATE
}
let action = null
if (button == 1 && ccount == 2) {
@ -539,8 +482,7 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
}
if (action == 'menu') {
this._openWindowMenu(focusWindow.win, mouseX)
return Clutter.EVENT_STOP
return this._openWindowMenu(focusWindow.win, event.get_coords()[0])
}
if (action && action != 'none') {
@ -560,37 +502,37 @@ var TitlebarActions = class TitlebarActions extends PanelExtension {
'lower': 'lower'
}
const method = mapping[action]
const method = win[mapping[action]]
if (method) {
win[method].call(win)
return Clutter.EVENT_STOP
if (typeof method !== 'function') {
return Clutter.EVENT_PROPAGATE
}
return Clutter.EVENT_PROPAGATE
method.call(win)
return Clutter.EVENT_STOP
}
_openWindowMenu(win, x) {
const size = Main.panel.height + 4
const rect = { x, y: 0, width: size, height: size }
const rect = { x: x - size, y: 0, width: size * 2, height: size }
const type = Meta.WindowMenuType.WM
Main.wm._windowMenuManager.showWindowMenuForWindow(win, type, rect)
return Clutter.EVENT_STOP
}
_destroy() {
destroy() {
this.signals.disconnectAll()
this.settings.disconnectAll()
}
}
var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
constructor({ settings }) {
const active = val => val > 0
super(settings, 'app-menu-max-width', active)
var AppMenuCustomizer = class AppMenuCustomizer extends Handlers.Feature {
constructor() {
super('app-menu-max-width', setting => setting > 0)
}
_init() {
activate() {
this.signals = new Handlers.Signals()
this.settings = new Handlers.Settings()
this.tooltip = new St.Label({ visible: false, style_class: 'dash-label' })
@ -672,7 +614,7 @@ var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
this.setTextEllipsizeMode(this.ellipsizeMode)
}
_destroy() {
destroy() {
this.tooltip.destroy()
this.setLabelMaxWidth(null)
@ -686,36 +628,23 @@ var AppMenuCustomizer = class AppMenuCustomizer extends PanelExtension {
var PanelManager = GObject.registerClass(
class UnitePanelManager extends GObject.Object {
_init() {
this.settings = new Handlers.Settings()
this.buttons = new WindowButtons(this)
this.extender = new ExtendLeftBox(this)
this.activities = new ActivitiesButton(this)
this.desktop = new DesktopName(this)
this.tray = new TrayIcons(this)
this.titlebar = new TitlebarActions(this)
this.appmenu = new AppMenuCustomizer(this)
this.features = new Handlers.Features()
this.features.add(WindowButtons)
this.features.add(ExtendLeftBox)
this.features.add(ActivitiesButton)
this.features.add(DesktopName)
this.features.add(TrayIcons)
this.features.add(TitlebarActions)
this.features.add(AppMenuCustomizer)
}
activate() {
this.buttons.activate()
this.extender.activate()
this.activities.activate()
this.desktop.activate()
this.tray.activate()
this.titlebar.activate()
this.appmenu.activate()
this.features.activate()
}
destroy() {
this.buttons.destroy()
this.extender.destroy()
this.activities.destroy()
this.desktop.destroy()
this.tray.destroy()
this.titlebar.destroy()
this.appmenu.destroy()
this.settings.disconnectAll()
this.features.destroy()
}
}
)

View File

@ -1,27 +1,21 @@
const GLib = imports.gi.GLib
const GObject = imports.gi.GObject
const Gtk = imports.gi.Gtk
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Unite.imports.convenience
const VERSION = Unite.imports.constants.VERSION
const TEMPLATE = VERSION < 40 ? 'settings-gtk3.ui' : 'settings-gtk4.ui'
const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const Override = Me.imports.overrides.helper
var PrefsWidget = GObject.registerClass(
class UnitePrefsWidget extends Gtk.Box {
_init(params) {
this._settings = Convenience.getSettings()
super._init(params)
this._settings = Convenience.getSettings()
this._buildable = new Gtk.Builder()
this._buildable.add_from_file(`${Unite.path}/${TEMPLATE}`)
this._container = this._getWidget('prefs_widget')
if (VERSION < 40) {
this.add(this._container)
} else {
this.append(this._container)
}
Override.inject(this, 'prefs', 'PrefsWidget')
this._loadTemplate()
this._bindStrings()
this._bindSelects()
this._bindBooleans()
@ -29,20 +23,12 @@ var PrefsWidget = GObject.registerClass(
this._bindIntegers()
}
startup() {
if (VERSION < 40) {
this.show_all()
}
_loadTemplate() {
const template = GLib.build_filenamev([Me.path, 'settings.ui'])
this._buildable.add_from_file(template)
if (VERSION >= 36) {
this._hideSetting('use-system-fonts')
}
if (VERSION >= 40) {
this._disableSetting('hide-dropdown-arrows')
this._disableSetting('hide-aggregate-menu-arrow')
this._disableSetting('hide-app-menu-arrow')
}
this._container = this._getWidget('prefs_widget')
this.append(this._container)
}
_getWidget(name) {
@ -50,16 +36,6 @@ var PrefsWidget = GObject.registerClass(
return this._buildable.get_object(widgetName)
}
_hideSetting(name) {
const widget = this._getWidget(`${name}_section`)
widget.set_visible(false)
}
_disableSetting(name) {
const widget = this._getWidget(`${name}_section`)
widget.set_sensitive(false)
}
_bindInput(setting, prop) {
let widget = this._getWidget(setting)
this._settings.bind(setting, widget, prop, this._settings.DEFAULT_BINDING)
@ -69,34 +45,34 @@ var PrefsWidget = GObject.registerClass(
let widget = this._getWidget(setting)
widget.set_active(this._settings.get_enum(setting))
widget.connect('changed', (combobox) => {
widget.connect('changed', combobox => {
this._settings.set_enum(setting, combobox.get_active())
})
}
_bindStrings() {
let settings = this._settings.getTypeSettings('string')
settings.forEach(setting => { this._bindInput(setting, 'text') })
settings.forEach(setting => this._bindInput(setting, 'text'))
}
_bindSelects() {
let settings = this._settings.getTypeSettings('select')
settings.forEach(setting => { this._bindInput(setting, 'active-id') })
settings.forEach(setting => this._bindInput(setting, 'active-id'))
}
_bindBooleans() {
let settings = this._settings.getTypeSettings('boolean')
settings.forEach(setting => { this._bindInput(setting, 'active') })
settings.forEach(setting => this._bindInput(setting, 'active'))
}
_bindEnumerations() {
let settings = this._settings.getTypeSettings('enum')
settings.forEach(setting => { this._bindEnum(setting) })
settings.forEach(setting => this._bindEnum(setting))
}
_bindIntegers() {
let settings = this._settings.getTypeSettings('int')
settings.forEach(setting => { this._bindInput(setting, 'value') })
settings.forEach(setting => this._bindInput(setting, 'value'))
}
}
)
@ -106,8 +82,5 @@ function init() {
}
function buildPrefsWidget() {
let widget = new PrefsWidget()
widget.startup()
return widget
return new PrefsWidget()
}

View File

@ -14,7 +14,6 @@
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox" id="general_prefs">
<property name="can-focus">0</property>
<property name="valign">start</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
@ -25,7 +24,6 @@
<property name="homogeneous">1</property>
<child>
<object class="GtkBox" id="extend_left_box_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -46,7 +44,6 @@
</child>
<child>
<object class="GtkBox" id="autofocus_windows_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -67,7 +64,6 @@
</child>
<child>
<object class="GtkBox" id="show_legacy_tray_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -88,7 +84,6 @@
</child>
<child>
<object class="GtkBox" id="show_desktop_name_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -109,7 +104,6 @@
</child>
<child>
<object class="GtkBox" id="enable_titlebar_actions_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -130,7 +124,6 @@
</child>
<child>
<object class="GtkBox" id="restrict_to_primary_screen_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -151,7 +144,6 @@
</child>
<child>
<object class="GtkBox" id="hide_activities_button_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -164,7 +156,6 @@
<object class="GtkComboBoxText" id="hide_activities_button">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">1</property>
<items>
@ -178,7 +169,6 @@
</child>
<child>
<object class="GtkBox" id="hide_window_titlebars_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -191,7 +181,6 @@
<object class="GtkComboBoxText" id="hide_window_titlebars">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -207,7 +196,6 @@
</child>
<child>
<object class="GtkBox" id="show_window_title_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -220,7 +208,6 @@
<object class="GtkComboBoxText" id="show_window_title">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -236,7 +223,6 @@
</child>
<child>
<object class="GtkBox" id="show_window_buttons_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -249,7 +235,6 @@
<object class="GtkComboBoxText" id="show_window_buttons">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -265,7 +250,6 @@
</child>
<child>
<object class="GtkBox" id="notifications_position_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -278,7 +262,6 @@
<object class="GtkComboBoxText" id="notifications_position">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -305,7 +288,6 @@
<object class="GtkNotebookPage">
<property name="child">
<object class="GtkBox" id="appearance_prefs">
<property name="can-focus">0</property>
<property name="valign">start</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
@ -316,8 +298,8 @@
<property name="homogeneous">1</property>
<child>
<object class="GtkBox" id="use_system_fonts_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<property name="visible">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -337,7 +319,6 @@
</child>
<child>
<object class="GtkBox" id="greyscale_tray_icons_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -357,7 +338,6 @@
</child>
<child>
<object class="GtkBox" id="hide_dropdown_arrows_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -378,7 +358,7 @@
</child>
<child>
<object class="GtkBox" id="hide_aggregate_menu_arrow_section">
<property name="can-focus">0</property>
<property name="sensitive">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -398,7 +378,7 @@
</child>
<child>
<object class="GtkBox" id="hide_app_menu_arrow_section">
<property name="can-focus">0</property>
<property name="sensitive">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -419,7 +399,6 @@
</child>
<child>
<object class="GtkBox" id="hide_app_menu_icon_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -440,7 +419,6 @@
</child>
<child>
<object class="GtkBox" id="reduce_panel_spacing_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -461,7 +439,6 @@
</child>
<child>
<object class="GtkBox" id="desktop_name_text_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -482,7 +459,6 @@
</child>
<child>
<object class="GtkBox" id="app_menu_max_width_section">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -503,7 +479,6 @@
</child>
<child>
<object class="GtkBox" id="app_menu_ellipsize_mode_section">
<property name="can-focus">0</property>
<child>
<object class="GtkLabel">
<property name="can-focus">0</property>
@ -515,7 +490,6 @@
<object class="GtkComboBoxText" id="app_menu_ellipsize_mode">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">2</property>
<items>
@ -529,7 +503,6 @@
</child>
<child>
<object class="GtkBox" id="window_buttons_placement_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -542,7 +515,6 @@
<object class="GtkComboBoxText" id="window_buttons_placement">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">auto</property>
<items>
@ -558,7 +530,6 @@
</child>
<child>
<object class="GtkBox" id="window_buttons_theme_section">
<property name="can-focus">0</property>
<property name="spacing">50</property>
<child>
<object class="GtkLabel">
@ -571,7 +542,6 @@
<object class="GtkComboBoxText" id="window_buttons_theme">
<property name="hexpand">1</property>
<property name="width-request">170</property>
<property name="can-focus">0</property>
<property name="halign">end</property>
<property name="active-id">0</property>
<items>

View File

@ -0,0 +1,61 @@
#panelLeft,
#panelCenter,
#panelRight {
spacing: 0px;
}
#panel .panel-button {
-natural-hpadding: 6px;
-minimum-hpadding: 4px;
padding-left: 6px;
padding-right: 6px;
}
#panel .panel-button > .system-status-icon {
padding-left: 0px;
padding-right: 0px;
}
#panel .panel-button .panel-status-indicators-box {
spacing: 4px;
}
#panel #panelActivities,
#panel .system-tray-icons,
#panel .desktop-name-label {
-natural-hpadding: 10px;
-minimum-hpadding: 8px;
}
#panel .system-tray-icons .panel-status-indicators-box {
spacing: 10px;
}
#panel .panel-button.clock-display {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
padding-left: 0px;
padding-right: 0px;
}
#panel .clock-display-box .clock {
padding-left: 8px;
padding-right: 8px;
}
#panel .clock-display-box StIcon:last-child {
margin-right: 3px;
}
#panel .window-controls-container {
margin-left: 4px;
margin-right: 4px;
}
#panelLeft .window-controls-container:first-child {
margin-left: 0px;
}
#panelRight .window-controls-container:last-child {
margin-right: 0px;
}

View File

@ -1,28 +1,3 @@
#panel.small-spacing .panel-button {
-natural-hpadding: 8px;
-minimum-hpadding: 6px;
}
#panel.small-spacing .panel-button .system-status-icon {
padding: 0;
}
#panel.small-spacing .panel-button .panel-status-indicators-box {
spacing: 12px;
}
#panel.small-spacing .panel-button .panel-status-indicators-box .panel-status-indicators-box {
spacing: 4px;
}
#panel.small-spacing.extra-spacing .panel-button .panel-status-indicators-box {
spacing: 10px;
}
#panel.small-spacing.extra-spacing #appMenu {
margin: 0 8px;
}
#panel .panel-button.window-controls {
-natural-hpadding: 0px;
-minimum-hpadding: 0px;
@ -36,11 +11,11 @@
width: 22px;
}
#panelLeft .window-controls-box:first-child .window-button:first-child {
#panelLeft .window-controls-container:first-child .window-button:first-child {
padding-left: 3px;
}
#panelRight .window-controls-box:last-child .window-button:last-child {
#panelRight .window-controls-container:last-child .window-button:last-child {
padding-right: 3px;
}

View File

@ -5,10 +5,10 @@ const Meta = imports.gi.Meta
const WinTracker = imports.gi.Shell.WindowTracker.get_default()
const Main = imports.ui.main
const Util = imports.misc.util
const Unite = imports.misc.extensionUtils.getCurrentExtension()
const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu
const Handlers = Unite.imports.handlers
const VERSION = Unite.imports.constants.VERSION
const Handlers = Me.imports.handlers
const Override = Me.imports.overrides.helper
const VALID_TYPES = [
Meta.WindowType.NORMAL,
@ -390,11 +390,7 @@ var WindowManager = GObject.registerClass(
'button-layout', this._onStylesChange.bind(this)
)
if (VERSION < 36) {
this.signals.connect(
AppMenu._label, 'notify::text', this._onAppmenuChanged.bind(this)
)
}
Override.inject(this, 'window', 'WindowManager')
}
get focusWindow() {
@ -460,12 +456,6 @@ var WindowManager = GObject.registerClass(
}
}
_onAppmenuChanged() {
if (this.focusWindow) {
this.focusWindow.syncAppmenu()
}
}
_onAttention(actor, win) {
const auto = this.settings.get('autofocus-windows')
const time = global.get_current_time()
@ -475,15 +465,12 @@ var WindowManager = GObject.registerClass(
_onStylesChange() {
if (this.hideTitlebars != 'never') {
const variant = this.settings.get('window-buttons-position')
const folder = path => `${Unite.path}/styles/${path}/buttons-${variant}`
const content = path => `@import url('${folder(path)}/${this.hideTitlebars}.css');`
const side = this.settings.get('window-buttons-position')
const path = `@/buttons-${side}/${this.hideTitlebars}.css`
this.styles.addGtk3Style('windowDecorationsGTK3', content('gtk3'))
this.styles.addGtk4Style('windowDecorationsGTK4', content('gtk4'))
this.styles.addGtkStyle('windowDecorations', path)
} else {
this.styles.deleteStyle('windowDecorationsGTK3')
this.styles.deleteStyle('windowDecorationsGTK4')
this.styles.deleteStyle('windowDecorations')
}
}
@ -491,6 +478,8 @@ var WindowManager = GObject.registerClass(
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
const actors = global.get_window_actors()
actors.forEach(actor => this._onMapWindow(null, actor))
return GLib.SOURCE_REMOVE
})
this._onStylesChange()

View File

@ -0,0 +1,138 @@
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Main = imports.ui.main;
const Volume = imports.ui.status.volume;
let volume_scroller = null;
const VolumeScrollerIcons =
[
'audio-volume-muted-symbolic',
'audio-volume-low-symbolic',
'audio-volume-medium-symbolic',
'audio-volume-high-symbolic'
];
class VolumeScroller
{
constructor()
{
this.controller = Volume.getMixerControl();
this.panel = Main.panel;
this.enabled = false;
this.sink = null;
this.volume_max = this.controller.get_vol_max_norm();
this.volume_step = 0.05 * this.volume_max;
this.scroll_binding = null;
this.sink_binding = null;
}
enable()
{
if (this.enabled)
{
this.disable();
}
this.enabled = true;
this.sink = this.controller.get_default_sink();
this.scroll_binding = this.panel.connect(
'scroll-event',
(actor, event) => this._handle_scroll(actor, event));
this.sink_binding = this.controller.connect(
'default-sink-changed',
(controller, id) => this._handle_sink_change(controller, id));
}
disable()
{
if (this.enabled)
{
this.enabled = false;
this.sink = null;
this.panel.disconnect(this.scroll_binding);
this.scroll_binding = null;
this.controller.disconnect(this.sink_binding);
this.sink_binding = null;
}
}
_handle_scroll(actor, event)
{
let volume = this.sink.volume;
switch (event.get_scroll_direction())
{
case Clutter.ScrollDirection.UP:
volume += this.volume_step;
break;
case Clutter.ScrollDirection.DOWN:
volume -= this.volume_step;
break;
default:
return Clutter.EVENT_PROPAGATE;
}
volume = Math.min(volume, this.volume_max);
volume = Math.max(volume, 0);
this.sink.volume = volume;
this.sink.push_volume();
this._show_volume(volume);
return Clutter.EVENT_STOP;
}
_handle_sink_change(controller, id)
{
this.sink = controller.lookup_stream_id(id);
}
_show_volume(volume)
{
const percentage = volume / this.volume_max;
let n;
if (volume === 0)
{
n = 0;
}
else
{
n = parseInt(3 * percentage + 1);
n = Math.max(1, n);
n = Math.min(3, n);
}
const monitor = -1; // Display volume window on all monitors.
const icon = Gio.Icon.new_for_string(VolumeScrollerIcons[n]);
const label = this.sink.get_port().human_port;
Main.osdWindowManager.show(monitor, icon, label, percentage);
}
};
function enable()
{
volume_scroller = new VolumeScroller();
volume_scroller.enable();
}
function disable()
{
if (volume_scroller !== null)
{
volume_scroller.disable();
volume_scroller = null;
}
}

View File

@ -0,0 +1,13 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Scroll up or down in the Top Bar to adjust volume.",
"name": "Volume Scroller",
"original-author": "trflynn89@pm.me",
"shell-version": [
"3.36",
"3.38"
],
"url": "https://github.com/trflynn89/gnome-shell-volume-scroller",
"uuid": "volume_scroller@trflynn89.pm.me",
"version": 2
}

View File

@ -0,0 +1,2 @@
export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_STYLE_OVERRIDE="kvantum-dark"