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 #sonar sonar-release
>i686 archlinux32-keyring >i686 archlinux32-keyring
>multilib gcc-libs-multilib >multilib gcc-libs-multilib
haveged
acpi acpi
acpid acpid
amd-ucode amd-ucode

View File

@ -1,17 +1,17 @@
#AUR #AUR
vdhcoapp vdhcoapp
webtorrent-desktop-bin webtorrent-desktop-bin
zafiro-icon-theme zafiro-icon-theme-git
vimix-kde-git vimix-kde-git
vimix-gtk-themes-git vimix-gtk-themes-git
kvantum-theme-vimix-git kvantum-theme-vimix-git
imageburner
bitmask bitmask
gnome-fuzzy-app-search-git gnome-fuzzy-app-search-git
openrgb openrgb
#FILES #FILES
parole parole
libreoffice-fresh libreoffice-fresh
@ -32,6 +32,7 @@ deja-dup
flameshot flameshot
keepassxc keepassxc
gnome-weather gnome-weather
mintstick
@ -57,7 +58,7 @@ rebuild-detector
#COMMUNICATE and SHARE #COMMUNICATE and SHARE
syncthing-gtk syncthing
qtox qtox
firefox 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.label_actor = this._label
this.setText(text || 'Desktop') this.setText(text || 'Desktop')
this.add_style_class_name('desktop-name-label')
} }
setText(text) { setText(text) {
@ -41,6 +42,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' }) this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' })
this.add_child(this._indicators) this.add_child(this._indicators)
this.add_style_class_name('system-tray-icons')
this._sync() this._sync()
} }
@ -62,7 +64,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators.add_child(ibtn) this._indicators.add_child(ibtn)
icon.connect('destroy', () => { ibtn.destroy() }) 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_reactive(true)
icon.set_height(this.size) icon.set_height(this.size)
@ -83,7 +85,7 @@ var TrayIndicator = GObject.registerClass(
} }
forEach(callback) { 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_child(this._controls)
this.add_style_class_name('window-controls') this.add_style_class_name('window-controls')
this.remove_style_class_name('panel-button')
} }
_addButton(action) { _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 GObject = imports.gi.GObject
const Gio = imports.gi.Gio const Gio = imports.gi.Gio
const Config = imports.misc.config const Config = imports.misc.config
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Me = imports.misc.extensionUtils.getCurrentExtension()
var SettingsManager = GObject.registerClass( var SettingsManager = GObject.registerClass(
class UniteSettings extends Gio.Settings { class UniteSettings extends Gio.Settings {
@ -89,22 +89,23 @@ var PreferencesManager = GObject.registerClass(
) )
function initTranslations(domain) { function initTranslations(domain) {
let textDomain = domain || Unite.metadata['gettext-domain'] let textDomain = domain || Me.metadata['gettext-domain']
let localeDir = Unite.dir.get_child('locale') let localeDir = Me.dir.get_child('locale')
if (localeDir.query_exists(null)) if (localeDir.query_exists(null)) {
localeDir = localeDir.get_path() localeDir = localeDir.get_path()
else } else {
localeDir = Config.LOCALEDIR localeDir = Config.LOCALEDIR
}
Gettext.bindtextdomain(textDomain, localeDir) Gettext.bindtextdomain(textDomain, localeDir)
} }
function getSettings(schema) { function getSettings(schema) {
schema = schema || Unite.metadata['settings-schema'] schema = schema || Me.metadata['settings-schema']
let gioSSS = Gio.SettingsSchemaSource let gioSSS = Gio.SettingsSchemaSource
let schemaDir = Unite.dir.get_child('schemas') let schemaDir = Me.dir.get_child('schemas')
let schemaSource = gioSSS.get_default() let schemaSource = gioSSS.get_default()
if (schemaDir.query_exists(null)) { if (schemaDir.query_exists(null)) {
@ -115,7 +116,7 @@ function getSettings(schema) {
let schemaObj = schemaSource.lookup(schema, true) let schemaObj = schemaSource.lookup(schema, true)
if (!schemaObj) { if (!schemaObj) {
let metaId = Unite.metadata.uuid let metaId = Me.metadata.uuid
let message = `Schema ${schema} could not be found for extension ${metaId}.` let message = `Schema ${schema} could not be found for extension ${metaId}.`
throw new Error(`${message} Please check your installation.`) throw new Error(`${message} Please check your installation.`)

View File

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

View File

@ -2,22 +2,33 @@ const Bytes = imports.byteArray
const Gio = imports.gi.Gio const Gio = imports.gi.Gio
const GLib = imports.gi.GLib const GLib = imports.gi.GLib
const St = imports.gi.St const St = imports.gi.St
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Main = imports.ui.main
const Convenience = Unite.imports.convenience const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const SETTINGS = Convenience.getSettings() const SETTINGS = Convenience.getSettings()
const WM_PREFS = Convenience.getPreferences() const WM_PREFS = Convenience.getPreferences()
const USER_CONFIG = GLib.get_user_config_dir() const GTK_VERSIONS = [3, 4]
const USER_STYLES_GTK3 = `${USER_CONFIG}/gtk-3.0/gtk.css` const USER_CONFIGS = GLib.get_user_config_dir()
const USER_STYLES_GTK4 = `${USER_CONFIG}/gtk-4.0/gtk.css`
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) { function fileExists(path) {
return GLib.file_test(path, GLib.FileTest.EXISTS) return GLib.file_test(path, GLib.FileTest.EXISTS)
} }
function getGioFile(path) { function getGioFile(path) {
const absPath = GLib.build_filenamev([Unite.path, path]) const absPath = filePath(path)
if (fileExists(absPath)) { if (fileExists(absPath)) {
return Gio.file_new_for_path(absPath) return Gio.file_new_for_path(absPath)
@ -42,13 +53,16 @@ function setFileContents(path, contents) {
GLib.file_set_contents(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) let style = getFileContents(filepath)
style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '') style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '')
style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '') style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '')
setFileContents(filepath, style) setFileContents(filepath, style)
})
} }
var Signals = class Signals { 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) { constructor(path) {
this.file = getGioFile(path) this.file = getGioFile(path)
} }
@ -138,7 +215,7 @@ var ShellStyle = class ShellStyle {
} }
} }
var WidgetStyle = class WidgetStyle { class WidgetStyle {
constructor(widget, style) { constructor(widget, style) {
this.widget = widget this.widget = widget
this.style = style this.style = style
@ -159,16 +236,27 @@ var WidgetStyle = class WidgetStyle {
} }
} }
var GtkStyle = class GtkStyle { class GtkStyle {
constructor(filepath, name, contents) { constructor(version, name, data) {
this.filepath = filepath const content = this.parse(data, version)
this.contents = `/* UNITE ${name} */\n${contents}\n/* ${name} UNITE */\n`
this.filepath = userStylesPath(version)
this.contents = `/* UNITE ${name} */\n${content}\n/* ${name} UNITE */\n`
} }
get existing() { get existing() {
return getFileContents(this.filepath) 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() { load() {
const style = this.contents + this.existing const style = this.contents + this.existing
setFileContents(this.filepath, style) 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 { var Styles = class Styles {
constructor() { constructor() {
this.styles = new Map() 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.deleteStyle(name)
this.setStyle(name, ShellStyle, path) this.setStyle(name, ShellStyle, data)
} else {
this.addWidgetStyle(name, Main.uiGroup, data)
}
} }
addWidgetStyle(name, widget, styles) { addWidgetStyle(name, widget, styles) {
@ -221,14 +328,9 @@ var Styles = class Styles {
this.setStyle(name, WidgetStyle, widget, styles) this.setStyle(name, WidgetStyle, widget, styles)
} }
addGtk3Style(name, contents) { addGtkStyle(name, contents, versions = GTK_VERSIONS) {
this.deleteStyle(name) this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK3, name, contents) this.setStyle(name, GtkStyles, name, contents, versions)
}
addGtk4Style(name, contents) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK4, name, contents)
} }
removeAll() { removeAll() {
@ -238,5 +340,4 @@ var Styles = class Styles {
} }
} }
resetGtkStyles(USER_STYLES_GTK3) resetGtkStyles()
resetGtkStyles(USER_STYLES_GTK4)

View File

@ -1,276 +1,220 @@
const GObject = imports.gi.GObject const GObject = imports.gi.GObject
const St = imports.gi.St const St = imports.gi.St
const Clutter = imports.gi.Clutter const Clutter = imports.gi.Clutter
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu const Handlers = Me.imports.handlers
const Handlers = Unite.imports.handlers const Override = Me.imports.overrides.helper
const VERSION = Unite.imports.constants.VERSION
function actorHasClass(actor, name) { var WidgetArrow = class WidgetArrow {
return actor.has_style_class_name && actor.has_style_class_name(name) 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) { var Messages = class Messages extends Handlers.Feature {
let arrow = widget._arrow constructor() {
super('notifications-position', setting => setting != 'center')
}
if (!arrow) { activate() {
const last = widget.get_n_children() - 1 this.settings = new Handlers.Settings()
const actor = widget.get_children()[last]
if (actor) { this.settings.connect(
if (actorHasClass(actor, 'popup-menu-arrow')) { 'notifications-position', this._onPositionChange.bind(this)
arrow = actor )
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 { } else {
arrow = getWidgetArrow(actor) dateMenu._minHPadding = paddings[0]
} dateMenu._natHPadding = paddings[1]
}
this._dateMenuPadding = null
} }
if (arrow && !widget.hasOwnProperty('_arrow')) { dateMenu.queue_relayout()
widget._arrow = arrow
} }
return arrow destroy() {
} Main.panel._removeStyleClassName('reduce-spacing')
this.styles.removeAll()
function toggleWidgetArrow(widget, hide) { this._syncLayout()
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
}
} }
} }
var LayoutManager = GObject.registerClass( var LayoutManager = GObject.registerClass(
class UniteLayoutManager extends GObject.Object { class UniteLayoutManager extends GObject.Object {
_init() { _init() {
this.signals = new Handlers.Signals() this.features = new Handlers.Features()
this.settings = new Handlers.Settings()
this.styles = new Handlers.Styles()
this.signals.connect( this.features.add(Messages)
Main.panel._leftBox, 'actor_added', this._onHideDropdownArrows.bind(this) this.features.add(AppMenuIcon)
) this.features.add(DropdownArrows)
this.features.add(PanelSpacing)
this.signals.connect( Override.inject(this, 'layout', 'LayoutManager')
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')
}
})
}
} }
activate() { activate() {
this._onNotificationsChange() this.features.activate()
this._onHideAppMenuIcon()
if (VERSION < 40) {
this._onHideAppMenuArrow()
this._onHideAggMenuArrow()
this._onHideDropdownArrows()
}
this._onChangeStyles()
} }
destroy() { destroy() {
this._resetNotifications() this.features.destroy()
this._resetAppMenuIcon()
if (VERSION < 40) {
this._resetAppMenuArrow()
this._resetAggMenuArrow()
this._resetDropdownArrows()
}
this._resetStyles()
this._syncStyles()
this.signals.disconnectAll()
this.settings.disconnectAll()
this.styles.removeAll()
} }
} }
) )

View File

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

View File

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

View File

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

View File

@ -5,10 +5,10 @@ const Meta = imports.gi.Meta
const WinTracker = imports.gi.Shell.WindowTracker.get_default() const WinTracker = imports.gi.Shell.WindowTracker.get_default()
const Main = imports.ui.main const Main = imports.ui.main
const Util = imports.misc.util const Util = imports.misc.util
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu const AppMenu = Main.panel.statusArea.appMenu
const Handlers = Unite.imports.handlers const Handlers = Me.imports.handlers
const VERSION = Unite.imports.constants.VERSION const Override = Me.imports.overrides.helper
const VALID_TYPES = [ const VALID_TYPES = [
Meta.WindowType.NORMAL, Meta.WindowType.NORMAL,
@ -390,11 +390,7 @@ var WindowManager = GObject.registerClass(
'button-layout', this._onStylesChange.bind(this) 'button-layout', this._onStylesChange.bind(this)
) )
if (VERSION < 36) { Override.inject(this, 'window', 'WindowManager')
this.signals.connect(
AppMenu._label, 'notify::text', this._onAppmenuChanged.bind(this)
)
}
} }
get focusWindow() { get focusWindow() {
@ -460,12 +456,6 @@ var WindowManager = GObject.registerClass(
} }
} }
_onAppmenuChanged() {
if (this.focusWindow) {
this.focusWindow.syncAppmenu()
}
}
_onAttention(actor, win) { _onAttention(actor, win) {
const auto = this.settings.get('autofocus-windows') const auto = this.settings.get('autofocus-windows')
const time = global.get_current_time() const time = global.get_current_time()
@ -475,15 +465,12 @@ var WindowManager = GObject.registerClass(
_onStylesChange() { _onStylesChange() {
if (this.hideTitlebars != 'never') { if (this.hideTitlebars != 'never') {
const variant = this.settings.get('window-buttons-position') const side = this.settings.get('window-buttons-position')
const folder = path => `${Unite.path}/styles/${path}/buttons-${variant}` const path = `@/buttons-${side}/${this.hideTitlebars}.css`
const content = path => `@import url('${folder(path)}/${this.hideTitlebars}.css');`
this.styles.addGtk3Style('windowDecorationsGTK3', content('gtk3')) this.styles.addGtkStyle('windowDecorations', path)
this.styles.addGtk4Style('windowDecorationsGTK4', content('gtk4'))
} else { } else {
this.styles.deleteStyle('windowDecorationsGTK3') this.styles.deleteStyle('windowDecorations')
this.styles.deleteStyle('windowDecorationsGTK4')
} }
} }
@ -491,6 +478,8 @@ var WindowManager = GObject.registerClass(
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
const actors = global.get_window_actors() const actors = global.get_window_actors()
actors.forEach(actor => this._onMapWindow(null, actor)) actors.forEach(actor => this._onMapWindow(null, actor))
return GLib.SOURCE_REMOVE
}) })
this._onStylesChange() 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.label_actor = this._label
this.setText(text || 'Desktop') this.setText(text || 'Desktop')
this.add_style_class_name('desktop-name-label')
} }
setText(text) { setText(text) {
@ -41,6 +42,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' }) this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' })
this.add_child(this._indicators) this.add_child(this._indicators)
this.add_style_class_name('system-tray-icons')
this._sync() this._sync()
} }
@ -62,7 +64,7 @@ var TrayIndicator = GObject.registerClass(
this._indicators.add_child(ibtn) this._indicators.add_child(ibtn)
icon.connect('destroy', () => { ibtn.destroy() }) 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_reactive(true)
icon.set_height(this.size) icon.set_height(this.size)
@ -83,7 +85,7 @@ var TrayIndicator = GObject.registerClass(
} }
forEach(callback) { 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_child(this._controls)
this.add_style_class_name('window-controls') this.add_style_class_name('window-controls')
this.remove_style_class_name('panel-button')
} }
_addButton(action) { _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 GObject = imports.gi.GObject
const Gio = imports.gi.Gio const Gio = imports.gi.Gio
const Config = imports.misc.config const Config = imports.misc.config
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Me = imports.misc.extensionUtils.getCurrentExtension()
var SettingsManager = GObject.registerClass( var SettingsManager = GObject.registerClass(
class UniteSettings extends Gio.Settings { class UniteSettings extends Gio.Settings {
@ -89,22 +89,23 @@ var PreferencesManager = GObject.registerClass(
) )
function initTranslations(domain) { function initTranslations(domain) {
let textDomain = domain || Unite.metadata['gettext-domain'] let textDomain = domain || Me.metadata['gettext-domain']
let localeDir = Unite.dir.get_child('locale') let localeDir = Me.dir.get_child('locale')
if (localeDir.query_exists(null)) if (localeDir.query_exists(null)) {
localeDir = localeDir.get_path() localeDir = localeDir.get_path()
else } else {
localeDir = Config.LOCALEDIR localeDir = Config.LOCALEDIR
}
Gettext.bindtextdomain(textDomain, localeDir) Gettext.bindtextdomain(textDomain, localeDir)
} }
function getSettings(schema) { function getSettings(schema) {
schema = schema || Unite.metadata['settings-schema'] schema = schema || Me.metadata['settings-schema']
let gioSSS = Gio.SettingsSchemaSource let gioSSS = Gio.SettingsSchemaSource
let schemaDir = Unite.dir.get_child('schemas') let schemaDir = Me.dir.get_child('schemas')
let schemaSource = gioSSS.get_default() let schemaSource = gioSSS.get_default()
if (schemaDir.query_exists(null)) { if (schemaDir.query_exists(null)) {
@ -115,7 +116,7 @@ function getSettings(schema) {
let schemaObj = schemaSource.lookup(schema, true) let schemaObj = schemaSource.lookup(schema, true)
if (!schemaObj) { if (!schemaObj) {
let metaId = Unite.metadata.uuid let metaId = Me.metadata.uuid
let message = `Schema ${schema} could not be found for extension ${metaId}.` let message = `Schema ${schema} could not be found for extension ${metaId}.`
throw new Error(`${message} Please check your installation.`) throw new Error(`${message} Please check your installation.`)

View File

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

View File

@ -2,22 +2,33 @@ const Bytes = imports.byteArray
const Gio = imports.gi.Gio const Gio = imports.gi.Gio
const GLib = imports.gi.GLib const GLib = imports.gi.GLib
const St = imports.gi.St const St = imports.gi.St
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Main = imports.ui.main
const Convenience = Unite.imports.convenience const Me = imports.misc.extensionUtils.getCurrentExtension()
const Convenience = Me.imports.convenience
const SETTINGS = Convenience.getSettings() const SETTINGS = Convenience.getSettings()
const WM_PREFS = Convenience.getPreferences() const WM_PREFS = Convenience.getPreferences()
const USER_CONFIG = GLib.get_user_config_dir() const GTK_VERSIONS = [3, 4]
const USER_STYLES_GTK3 = `${USER_CONFIG}/gtk-3.0/gtk.css` const USER_CONFIGS = GLib.get_user_config_dir()
const USER_STYLES_GTK4 = `${USER_CONFIG}/gtk-4.0/gtk.css`
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) { function fileExists(path) {
return GLib.file_test(path, GLib.FileTest.EXISTS) return GLib.file_test(path, GLib.FileTest.EXISTS)
} }
function getGioFile(path) { function getGioFile(path) {
const absPath = GLib.build_filenamev([Unite.path, path]) const absPath = filePath(path)
if (fileExists(absPath)) { if (fileExists(absPath)) {
return Gio.file_new_for_path(absPath) return Gio.file_new_for_path(absPath)
@ -42,13 +53,16 @@ function setFileContents(path, contents) {
GLib.file_set_contents(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) let style = getFileContents(filepath)
style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '') style = style.replace(/\/\* UNITE ([\s\S]*?) UNITE \*\/\n/g, '')
style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '') style = style.replace(/@import.*unite@hardpixel\.eu.*css['"]\);\n/g, '')
setFileContents(filepath, style) setFileContents(filepath, style)
})
} }
var Signals = class Signals { 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) { constructor(path) {
this.file = getGioFile(path) this.file = getGioFile(path)
} }
@ -138,7 +215,7 @@ var ShellStyle = class ShellStyle {
} }
} }
var WidgetStyle = class WidgetStyle { class WidgetStyle {
constructor(widget, style) { constructor(widget, style) {
this.widget = widget this.widget = widget
this.style = style this.style = style
@ -159,16 +236,27 @@ var WidgetStyle = class WidgetStyle {
} }
} }
var GtkStyle = class GtkStyle { class GtkStyle {
constructor(filepath, name, contents) { constructor(version, name, data) {
this.filepath = filepath const content = this.parse(data, version)
this.contents = `/* UNITE ${name} */\n${contents}\n/* ${name} UNITE */\n`
this.filepath = userStylesPath(version)
this.contents = `/* UNITE ${name} */\n${content}\n/* ${name} UNITE */\n`
} }
get existing() { get existing() {
return getFileContents(this.filepath) 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() { load() {
const style = this.contents + this.existing const style = this.contents + this.existing
setFileContents(this.filepath, style) 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 { var Styles = class Styles {
constructor() { constructor() {
this.styles = new Map() 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.deleteStyle(name)
this.setStyle(name, ShellStyle, path) this.setStyle(name, ShellStyle, data)
} else {
this.addWidgetStyle(name, Main.uiGroup, data)
}
} }
addWidgetStyle(name, widget, styles) { addWidgetStyle(name, widget, styles) {
@ -221,14 +328,9 @@ var Styles = class Styles {
this.setStyle(name, WidgetStyle, widget, styles) this.setStyle(name, WidgetStyle, widget, styles)
} }
addGtk3Style(name, contents) { addGtkStyle(name, contents, versions = GTK_VERSIONS) {
this.deleteStyle(name) this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK3, name, contents) this.setStyle(name, GtkStyles, name, contents, versions)
}
addGtk4Style(name, contents) {
this.deleteStyle(name)
this.setStyle(name, GtkStyle, USER_STYLES_GTK4, name, contents)
} }
removeAll() { removeAll() {
@ -238,5 +340,4 @@ var Styles = class Styles {
} }
} }
resetGtkStyles(USER_STYLES_GTK3) resetGtkStyles()
resetGtkStyles(USER_STYLES_GTK4)

View File

@ -1,276 +1,220 @@
const GObject = imports.gi.GObject const GObject = imports.gi.GObject
const St = imports.gi.St const St = imports.gi.St
const Clutter = imports.gi.Clutter const Clutter = imports.gi.Clutter
const GtkSettings = imports.gi.Gtk.Settings.get_default()
const Main = imports.ui.main const Main = imports.ui.main
const Unite = imports.misc.extensionUtils.getCurrentExtension() const Me = imports.misc.extensionUtils.getCurrentExtension()
const AppMenu = Main.panel.statusArea.appMenu const AppMenu = Main.panel.statusArea.appMenu
const AggMenu = Main.panel.statusArea.aggregateMenu const Handlers = Me.imports.handlers
const Handlers = Unite.imports.handlers const Override = Me.imports.overrides.helper
const VERSION = Unite.imports.constants.VERSION
function actorHasClass(actor, name) { var WidgetArrow = class WidgetArrow {
return actor.has_style_class_name && actor.has_style_class_name(name) 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) { var Messages = class Messages extends Handlers.Feature {
let arrow = widget._arrow constructor() {
super('notifications-position', setting => setting != 'center')
}
if (!arrow) { activate() {
const last = widget.get_n_children() - 1 this.settings = new Handlers.Settings()
const actor = widget.get_children()[last]
if (actor) { this.settings.connect(
if (actorHasClass(actor, 'popup-menu-arrow')) { 'notifications-position', this._onPositionChange.bind(this)
arrow = actor )
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 { } else {
arrow = getWidgetArrow(actor) dateMenu._minHPadding = paddings[0]
} dateMenu._natHPadding = paddings[1]
}
this._dateMenuPadding = null
} }
if (arrow && !widget.hasOwnProperty('_arrow')) { dateMenu.queue_relayout()
widget._arrow = arrow
} }
return arrow destroy() {
} Main.panel._removeStyleClassName('reduce-spacing')
this.styles.removeAll()
function toggleWidgetArrow(widget, hide) { this._syncLayout()
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
}
} }
} }
var LayoutManager = GObject.registerClass( var LayoutManager = GObject.registerClass(
class UniteLayoutManager extends GObject.Object { class UniteLayoutManager extends GObject.Object {
_init() { _init() {
this.signals = new Handlers.Signals() this.features = new Handlers.Features()
this.settings = new Handlers.Settings()
this.styles = new Handlers.Styles()
this.signals.connect( this.features.add(Messages)
Main.panel._leftBox, 'actor_added', this._onHideDropdownArrows.bind(this) this.features.add(AppMenuIcon)
) this.features.add(DropdownArrows)
this.features.add(PanelSpacing)
this.signals.connect( Override.inject(this, 'layout', 'LayoutManager')
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')
}
})
}
} }
activate() { activate() {
this._onNotificationsChange() this.features.activate()
this._onHideAppMenuIcon()
if (VERSION < 40) {
this._onHideAppMenuArrow()
this._onHideAggMenuArrow()
this._onHideDropdownArrows()
}
this._onChangeStyles()
} }
destroy() { destroy() {
this._resetNotifications() this.features.destroy()
this._resetAppMenuIcon()
if (VERSION < 40) {
this._resetAppMenuArrow()
this._resetAggMenuArrow()
this._resetDropdownArrows()
}
this._resetStyles()
this._syncStyles()
this.signals.disconnectAll()
this.settings.disconnectAll()
this.styles.removeAll()
} }
} }
) )

View File

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

View File

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

View File

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

View File

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