Compare commits

...

32 Commits

Author SHA1 Message Date
Florian Müllner
ffcbf03c9c Bump version to 46.alpha
Update NEWS.
2024-01-06 22:16:52 +01:00
Florian Müllner
1d7f37f420 system-monitor: Add new extension
A long time ago, we used to include a system monitor extension,
that added CPU/memory graphs to the (long gone) message tray.

However demand for this type of extensions hasn't died down, to the
point where RHEL includes a revived version of the old extension.

Account for that demand by adding a newly written system-monitor
extension that has been properly designed, and hopefully does not
bring back the CPU/memory issues of the previous one (unlikely
without the graphs) …

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/277>
2023-12-04 13:20:13 +01:00
Florian Müllner
30a15387b5 workspace-indicator: Update visibility on window-type changes
The visibility depends on the type, so we should listen for
changes (even if the property is unlikely to change).

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:14:26 +01:00
Florian Müllner
b5b841dd38 workspace-indicator: Don't hide previews on other monitors
Workspace thumbnails are clipped, so there's no major benefit
of hiding the actors explicitly.

On the other hand, the check is useful on size/position changes
to avoid unnecessary relayouts.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:13:42 +01:00
Florian Müllner
5f2b199627 Revert "workspace-indicator: Only initialize preview visibility on map"
It is not possible to unmap an actor from within the map vfunc,
so the fix broke the initial visibility again.

This reverts commit 25a75e1b0e.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:11:42 +01:00
Florian Müllner
071584621e window-list: Update visibility on window-type changes
The visibility depends on the type, so we should listen for
changes (even if the property is unlikely to change).

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:10:08 +01:00
Florian Müllner
5c57f44838 window-list: Don't hide previews on other monitors
Workspace thumbnails are clipped, so there's no major benefit
of hiding the actors explicitly.

On the other hand, the check is useful on size/position changes
to avoid unnecessary relayouts.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:09:30 +01:00
Florian Müllner
93741e9e1c Revert "window-list: Only initialize preview visibility on map"
It is not possible to unmap an actor from within the map vfunc,
so the fix broke the initial visibility again.

This reverts commit 8b7cfff558.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/292>
2023-12-01 19:09:30 +01:00
Florian Müllner
836f81f2e2 window-list: Move additional padding into buttons
Commit ca1c4b0f9e added additional padding, which means that the
interactive area of buttons no longer extends to the bottom of
the screen.

Address this by moving the new padding into the buttons themselves.
That restores the Fittsability of the bottom bar, without affecting
the cleaner visual appearance.

Close https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/453

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/291>
2023-12-01 12:34:20 +00:00
Florian Müllner
574638328e window-list: Clean up stylesheet indent
Replaces tabs with spaces.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/291>
2023-12-01 12:34:20 +00:00
Jonas Ådahl
e0750db1bd Mark session file as X-GDM-CanRunHeadless=true
This will make it possible to launch the session headlessly for
remote-only access.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/289>
2023-11-30 20:41:58 +00:00
Florian Müllner
5652182fb3 apps-menu: Use customized layout manager to limit height
To avoid continuous height changes while browsing through categories,
we let the list of categories determine the overall height, and rely
on scrolling for the list of apps within a category.

We currently achieve this by assigning a fixed height via the
`style` property. This has been found to trigger a crash when
running headless, as we end up querying an actor's height request
before a valid resource scale is available.

Instead, use a custom layout manager, which seems more elegant anyway.

Close: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/472
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
2023-11-23 21:20:56 +01:00
Florian Müllner
c3cbef19ac apps-menu: Remove vertical separator
Ever since gnome-shell stopped using a stippled separator in the
calendar menu, the styling required by the separator has been
missing.

There haven't been any complaints about the invisible separator,
so we can just as well drop it altogether.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
2023-11-23 21:15:51 +01:00
Florian Müllner
8c8f990a28 apps-menu: Use stylesheet to set width
The `style` property is useful for computed CSS declarations,
but for regular styling the stylesheet is preferable.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
2023-11-23 21:13:30 +01:00
Florian Müllner
f6a6bdda99 apps-menu: Adjust to events API changes
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/290>
2023-11-23 14:25:57 +01:00
Florian Müllner
0d5d06fdd7 apps-menu: Adjust to ClutterContainer removal
The `actor-added` signal got renamed to `child-added` when
moving it to ClutterActor.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/288>
2023-11-14 16:26:06 +00:00
Florian Müllner
d10b98c4fc extensions: Stop using ClutterContainer API
The methods have long been deprecated in favor of the equivalent
ClutterActor methods, so use the latter instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/288>
2023-11-14 16:26:06 +00:00
Florian Müllner
8b7cfff558 window-list: Only initialize preview visibility on map
The check whether the window overlaps with the monitor the actor
is on requires the actor to be added to the stage first, so delay
the initial visibility update that was added in commit f576f1b1b6.

Fixes: f576f1b1 ("window-list: Initialize preview visibility")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/286>
2023-11-08 16:36:59 +00:00
Florian Müllner
25a75e1b0e workspace-indicator: Only initialize preview visibility on map
The check whether the window overlaps with the monitor the actor
is on requires the actor to be added to the stage first, so delay
the initial visibility update that was added in commit b9d2a445b2.

Fixes: b9d2a445 ("workspace-indicator: Initialize preview visibility")
Closes:
https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/469

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/286>
2023-11-08 16:36:59 +00:00
Florian Müllner
91a1b8245b window-list: Remove window picker
Now that the overview is available again in the classic session,
the window picker that used to replace it is unused.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/287>
2023-11-07 17:43:18 +01:00
Florian Müllner
4abde90e82 classic: Reenable overview
Since we disabled the overview in the classic session, gnome-shell
switched to a horizontal workspace layout and replaced the activities
button with an indicator.

Those are big enough changes to reevaluate the decision, so remove
the delta with the regular session and turn it back on.

This reverts commit 82d2011061.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/287>
2023-11-07 16:38:37 +01:00
Florian Müllner
dd8ee2931a screenshot-window-sizer: Handle wrapping around backwards
The mod takes care of wrapping at the top, but not when
decrementing 0. Fix this by using Array.prototype.at(),
which handles negative indexes.

Close https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/467

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/284>
2023-10-24 21:15:06 +02:00
Florian Müllner
f530acbf9e screenshot-window-sizer: Use built-in support for reversed bindings
Mutter has had explicit support for reversed bindings for a while now.
Use that, as it's more reliably than examining the modifiers manually.

Close https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/467

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/284>
2023-10-24 21:15:06 +02:00
Brage Fuglseth
7d296d2fd2 Update Norwegian Bokmål translation 2023-10-12 20:28:03 +00:00
Florian Müllner
fb858ed0e4 window-list: Complete move to connectObject()
Commit 3bfaf6f88a removed the explicit disconnect, but forgot
to use connectObject() to connect the handler.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/459
Fixes: 3bfaf6f8 ("js: Use connectObject()")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/281>
2023-10-09 15:36:39 +02:00
Florian Müllner
f576f1b1b6 window-list: Initialize preview visibility
Otherwise we can end up showing window previews in the workspace
thumbnail that shouldn't be visible, if none of the properties we
track for updates changes.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/280>
2023-09-29 21:35:33 +02:00
Florian Müllner
b9d2a445b2 workspace-indicator: Initialize preview visibility
Otherwise we can end up showing windows that shouldn't be visible
if none of the properties we track for updates changes.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/280>
2023-09-29 21:33:04 +02:00
Florian Müllner
092b268823 drive-menu: Remove left-over signal connection
The handler itself was removed in commit 3bfaf6f88a, so the
code now fails.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/455
Fixes: 3bfaf6f8 ("js: Use connectObject()")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/278>
2023-09-29 12:33:13 +00:00
Kristjan SCHMIDT
b64cb0f195 Update Esperanto translation 2023-09-27 20:47:58 +00:00
Florian Müllner
2510bb3625 extensions: Stop using run_dispose()
It is considered bad practice, and mainly a lazy way of disconnecting
signal handlers without tracking individual handler IDs.

We can do better by using connectObject(), which provides the same
level of convenience without the dodginess of getting behind the
garbage collector's back.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/275>
2023-09-26 15:21:41 +00:00
Florian Müllner
4fbd878208 lint: Sync with gnome-shell
gnome-shell itself no longer requires parameter descriptions in
doc comments (just type annotations). The requirement makes even
less sense for extensions, so sync up the configuration.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/276>
2023-09-26 14:30:27 +02:00
Florian Müllner
e8840da00c doap: Actually remove defunct mailing list
Fixes: e405d09c ("DOAP: Remove defunct mailing list; add Discourse")
2023-09-20 13:30:42 +02:00
42 changed files with 1094 additions and 800 deletions

18
NEWS
View File

@@ -1,3 +1,21 @@
46.alpha
========
* workspace-indicator: Fix initial preview visibility [Florian; !280, !292]
* screenshot-window-sizer: Fix cycling between sizes backwards [Florian; !284]
* Add back overview in Classic session [Florian; !287]
* Allow running Classic session headless [Jonas; !289]
* window-list: Fix buttons not being clickable at the screen edge
[Florian; !291]
* Add system-monitor extension [Florian; !277]
* Fixed crash [Florian; !290]
* Misc. bug fixes and cleanups [Florian; !276, !275, !278, !281, !286, !288]
Contributors:
Jonas Ådahl, Florian Müllner
Translators:
Kristjan SCHMIDT [eo], Brage Fuglseth [nb]
45.0
====

View File

@@ -1,10 +1,9 @@
{
"parentMode": "user",
"colorScheme": "force-light",
"hasOverview": false,
"showWelcomeDialog": false,
"enabledExtensions": [@CLASSIC_EXTENSIONS@],
"panel": { "left": [],
"panel": { "left": ["activities"],
"center": [],
"right": ["a11y", "keyboard", "dateMenu", "quickSettings"]
}

View File

@@ -6,3 +6,4 @@ TryExec=gnome-session
Type=Application
DesktopNames=GNOME-Classic;GNOME;
X-GDM-SessionRegisters=true
X-GDM-CanRunHeadless=true

View File

@@ -6,3 +6,4 @@ TryExec=gnome-session
Type=Application
DesktopNames=GNOME-Classic;GNOME;
X-GDM-SessionRegisters=true
X-GDM-CanRunHeadless=true

View File

@@ -41,6 +41,8 @@ for f in $extensiondir/*; do
cp $srcdir/NEWS $srcdir/COPYING $f
sources=(NEWS COPYING $(cd $f; ls *.js))
[ -d $f/icons ] && sources+=(icons)
[ -f $schema ] || unset schema
gnome-extensions pack ${sources[@]/#/--extra-source=} \

View File

@@ -214,9 +214,9 @@ class CategoryMenuItem extends PopupMenu.PopupBaseMenuItem {
this._grab?.dismiss();
delete this._grab;
let source = event.get_source();
if (source instanceof St.Widget)
source.sync_hover();
const targetActor = global.stage.get_event_actor(event);
if (targetActor instanceof St.Widget)
targetActor.sync_hover();
return false;
}
@@ -255,7 +255,7 @@ class DesktopTarget extends EventEmitter {
this._desktopDestroyedId = 0;
this._windowAddedId =
global.window_group.connect('actor-added',
global.window_group.connect('child-added',
this._onWindowAdded.bind(this));
global.get_window_actors().forEach(a => {
@@ -363,6 +363,20 @@ class DesktopTarget extends EventEmitter {
}
}
class MainLayout extends Clutter.BoxLayout {
static {
GObject.registerClass(this);
}
vfunc_get_preferred_height(container, forWidth) {
const [mainChild] = container;
const [minHeight, natHeight] =
mainChild.get_preferred_height(forWidth);
return [minHeight, natHeight + MENU_HEIGHT_OFFSET];
}
}
class ApplicationsButton extends PanelMenu.Button {
static {
GObject.registerClass(this);
@@ -385,7 +399,7 @@ class ApplicationsButton extends PanelMenu.Button {
y_align: Clutter.ActorAlign.CENTER,
});
this.add_actor(this._label);
this.add_child(this._label);
this.name = 'panelApplications';
this.label_actor = this._label;
@@ -432,15 +446,6 @@ class ApplicationsButton extends PanelMenu.Button {
}
}
_createVertSeparator() {
let separator = new St.DrawingArea({
style_class: 'calendar-vertical-separator',
pseudo_class: 'highlighted',
});
separator.connect('repaint', this._onVertSepRepaint.bind(this));
return separator;
}
_onDestroy() {
super._onDestroy();
@@ -462,21 +467,6 @@ class ApplicationsButton extends PanelMenu.Button {
return super._onMenuKeyPress(actor, event);
}
_onVertSepRepaint(area) {
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
let stippleColor = themeNode.get_color('-stipple-color');
let stippleWidth = themeNode.get_length('-stipple-width');
let x = Math.floor(width / 2) + 0.5;
cr.moveTo(x, 0);
cr.lineTo(x, height);
Clutter.cairo_set_source_color(cr, stippleColor);
cr.setDash([1, 3], 1); // Hard-code for now
cr.setLineWidth(stippleWidth);
cr.stroke();
}
_onOpenStateChanged(menu, open) {
if (open) {
if (this.reloadFlag) {
@@ -554,7 +544,7 @@ class ApplicationsButton extends PanelMenu.Button {
_createLayout() {
let section = new PopupMenu.PopupMenuSection();
this.menu.addMenuItem(section);
this.mainBox = new St.BoxLayout({vertical: false});
this.mainBox = new St.BoxLayout({layoutManager: new MainLayout()});
this.leftBox = new St.BoxLayout({vertical: true});
this.applicationsScrollBox = new St.ScrollView({
style_class: 'apps-menu vfade',
@@ -578,19 +568,17 @@ class ApplicationsButton extends PanelMenu.Button {
this.leftBox.add_child(this.categoriesScrollBox);
this.applicationsBox = new St.BoxLayout({vertical: true});
this.applicationsScrollBox.add_actor(this.applicationsBox);
this.applicationsScrollBox.set_child(this.applicationsBox);
this.categoriesBox = new St.BoxLayout({vertical: true});
this.categoriesScrollBox.add_actor(this.categoriesBox);
this.categoriesScrollBox.set_child(this.categoriesBox);
this.mainBox.add(this.leftBox);
this.mainBox.add_child(this._createVertSeparator());
this.mainBox.add_child(this.leftBox);
this.mainBox.add_child(this.applicationsScrollBox);
section.actor.add_actor(this.mainBox);
section.actor.add_child(this.mainBox);
}
_display() {
this._applicationsButtons.clear();
this.mainBox.style = 'width: 35em;';
this.mainBox.hide();
// Load categories
@@ -598,7 +586,7 @@ class ApplicationsButton extends PanelMenu.Button {
this._tree.load_sync();
let root = this._tree.get_root_directory();
let categoryMenuItem = new CategoryMenuItem(this, null);
this.categoriesBox.add_actor(categoryMenuItem);
this.categoriesBox.add_child(categoryMenuItem);
let iter = root.iter();
let nextType;
while ((nextType = iter.next()) !== GMenu.TreeItemType.INVALID) {
@@ -614,18 +602,12 @@ class ApplicationsButton extends PanelMenu.Button {
this._loadCategory(categoryId, dir);
if (this.applicationsByCategory[categoryId].length > 0) {
categoryMenuItem = new CategoryMenuItem(this, dir);
this.categoriesBox.add_actor(categoryMenuItem);
this.categoriesBox.add_child(categoryMenuItem);
}
}
// Load applications
this._displayButtons(this._listApplications(null));
let themeContext = St.ThemeContext.get_for_stage(global.stage);
let scaleFactor = themeContext.scale_factor;
let categoriesHeight = this.categoriesBox.height / scaleFactor;
let height = Math.round(categoriesHeight) + MENU_HEIGHT_OFFSET;
this.mainBox.style += `height: ${height}px`;
}
selectCategory(dir) {
@@ -633,7 +615,7 @@ class ApplicationsButton extends PanelMenu.Button {
if (c._delegate instanceof PopupMenu.PopupSeparatorMenuItem)
c._delegate.destroy();
else
this.applicationsBox.remove_actor(c);
this.applicationsBox.remove_child(c);
});
if (dir)
@@ -656,7 +638,7 @@ class ApplicationsButton extends PanelMenu.Button {
this._applicationsButtons.set(app, item);
}
if (!item.get_parent())
this.applicationsBox.add_actor(item);
this.applicationsBox.add_child(item);
}
}

View File

@@ -4,6 +4,8 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.apps-menu {width: 26em;}
.apps-menu:ltr {
padding-right: 3px;
}

View File

@@ -22,7 +22,8 @@ class WindowMover {
this._appSystem.connectObject('installed-changed',
() => this._updateAppData(), this);
this._settings.connect('changed', this._updateAppConfigs.bind(this));
this._settings.connectObject('changed',
this._updateAppConfigs.bind(this), this);
this._updateAppConfigs();
}
@@ -58,11 +59,8 @@ class WindowMover {
destroy() {
this._appSystem.disconnectObject(this);
if (this._settings) {
this._settings.run_dispose();
this._settings = null;
}
this._settings.disconnectObject(this);
this._settings = null;
this._appConfigs.clear();
this._updateAppData();

View File

@@ -39,8 +39,6 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
this.mount = mount;
this.connect('destroy', this._onDestroy.bind(this));
let ejectIcon = new St.Icon({
icon_name: 'media-eject-symbolic',
style_class: 'popup-menu-icon',
@@ -50,7 +48,7 @@ class MountMenuItem extends PopupMenu.PopupBaseMenuItem {
style_class: 'button',
});
ejectButton.connect('clicked', this._eject.bind(this));
this.add(ejectButton);
this.add_child(ejectButton);
this.hide();

View File

@@ -95,7 +95,7 @@ class PlacesMenu extends PanelMenu.Button {
y_expand: true,
y_align: Clutter.ActorAlign.CENTER,
});
this.add_actor(label);
this.add_child(label);
this.placesManager = new PlacesManager();

View File

@@ -141,8 +141,8 @@ class RootInfo extends PlaceInfo {
return;
this._proxy = obj;
this._proxy.connect('g-properties-changed',
this._propertiesChanged.bind(this));
this._proxy.connectObject('g-properties-changed',
this._propertiesChanged.bind(this), this);
this._propertiesChanged(obj);
});
}
@@ -161,10 +161,8 @@ class RootInfo extends PlaceInfo {
}
destroy() {
if (this._proxy) {
this._proxy.run_dispose();
this._proxy = null;
}
this._proxy?.disconnectObject(this);
this._proxy = null;
super.destroy();
}
}

View File

@@ -33,7 +33,7 @@ export default class ScreenshotWindowSizerExtension extends Extension {
_flashMessage(message) {
if (!this._text) {
this._text = new St.Label({style_class: 'screenshot-sizer-message'});
Main.uiGroup.add_actor(this._text);
Main.uiGroup.add_child(this._text);
}
this._text.remove_all_transitions();
@@ -65,10 +65,7 @@ export default class ScreenshotWindowSizerExtension extends Extension {
* @param {Meta.KeyBinding} binding - the key binding
*/
_cycleScreenshotSizes(display, window, binding) {
// Probably this isn't useful with 5 sizes, but you can decrease instead
// of increase by holding down shift.
let modifiers = binding.get_modifiers();
let backwards = (modifiers & Meta.VirtualModifier.SHIFT_MASK) !== 0;
const backwards = binding.is_reversed();
// Unmaximize first
if (window.get_maximized() !== 0)
@@ -99,7 +96,7 @@ export default class ScreenshotWindowSizerExtension extends Extension {
// get the next size up or down from ideal
let newIndex = (nearestIndex + (backwards ? -1 : 1)) % scaledSizes.length;
let [newWidth, newHeight] = scaledSizes[newIndex];
let [newWidth, newHeight] = scaledSizes.at(newIndex);
// Push the window onscreen if it would be resized offscreen
let newX = outerRect.x;

View File

@@ -0,0 +1,480 @@
/*
* SPDX-FileCopyrightText: 2023 Florian Müllner <fmuellner@gnome.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import GTop from 'gi://GTop';
import Pango from 'gi://Pango';
import Shell from 'gi://Shell';
import St from 'gi://St';
import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/extension.js';
import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
const THRESHOLD_HIGH = 0.80;
// adapted from load-graph.cpp in gnome-system-monitor
/**
* @param {string} str
* @returns {number}
*/
function strHash(str) {
let hash = 0xcbf29ce484222325n;
for (const c of str)
hash = (hash * 0x00000100000001B3n) ^ BigInt(c.codePointAt(0));
return hash;
}
class StatSection extends St.BoxLayout {
static {
GObject.registerClass(this);
}
constructor(iconName, accessibleName) {
super({
style_class: 'system-monitor-stat-section',
accessibleName,
});
const ext = Extension.lookupByURL(import.meta.url);
const file =
ext.dir.resolve_relative_path(`icons/${iconName}.svg`);
this._icon = new St.Icon({
style_class: 'system-monitor-stat-section-icon',
gicon: new Gio.FileIcon({file}),
});
this.add_child(this._icon);
this.label = new St.Label({
style_class: 'system-monitor-stat-section-label',
y_align: Clutter.ActorAlign.CENTER,
});
this.label.clutter_text.set({
ellipsize: Pango.EllipsizeMode.NONE,
x_align: Clutter.ActorAlign.CENTER,
});
this.add_child(this.label);
this.connect('destroy', () => this._clearTimeout());
this.connect('notify::visible', () => this._sync());
this._sync();
}
_ensureTimeout() {
if (this._updateId)
return;
this._updateId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1,
() => {
this._update();
return GLib.SOURCE_CONTINUE;
});
}
_clearTimeout() {
if (this._updateId)
GLib.source_remove(this._updateId);
delete this._updateId;
}
_sync() {
if (this.visible)
this._ensureTimeout();
else
this._clearTimeout();
if (this.visible)
this._update();
}
_update() {
}
}
class LoadStatSection extends StatSection {
static {
GObject.registerClass(this);
}
#formatter = new Intl.NumberFormat(undefined, {
style: 'percent',
});
_getLoadValue() {
}
_update() {
const load = this._getLoadValue();
this.label.text = this.#formatter.format(load);
if (load >= THRESHOLD_HIGH)
this.add_style_class_name('high-usage');
else
this.remove_style_class_name('high-usage');
}
}
class CpuSection extends LoadStatSection {
static {
GObject.registerClass(this);
}
#prevCpu = new GTop.glibtop_cpu();
constructor() {
super('processor-symbolic', _('CPU stats'));
}
_getLoadValue() {
const cpu = new GTop.glibtop_cpu();
GTop.glibtop_get_cpu(cpu);
const total = cpu.total - this.#prevCpu.total;
const user = cpu.user - this.#prevCpu.user;
const sys = cpu.sys - this.#prevCpu.sys;
const nice = cpu.nice - this.#prevCpu.nice;
this.#prevCpu = cpu;
return (user + sys + nice) / Math.max(total, 1.0);
}
}
class MemSection extends LoadStatSection {
static {
GObject.registerClass(this);
}
constructor() {
super('memory-symbolic', _('Memory stats'));
}
_getLoadValue() {
const mem = new GTop.glibtop_mem();
GTop.glibtop_get_mem(mem);
const {user, total} = mem;
return user / Math.max(total, 1.0);
}
}
class SwapSection extends LoadStatSection {
static {
GObject.registerClass(this);
}
constructor() {
super('swap-symbolic', _('Swap stats'));
}
_getLoadValue() {
const swap = new GTop.glibtop_swap();
GTop.glibtop_get_swap(swap);
const {used, total} = swap;
return used / Math.max(total, 1.0);
}
}
class NetStatSection extends StatSection {
static {
GObject.registerClass(this);
}
#formats = [{
factor: 1000,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'kilobyte',
maximumFractionDigits: 1,
minimumFractionDigits: 1,
}),
}, {
factor: 1000 * 10,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'kilobyte',
maximumFractionDigits: 0,
}),
}, {
factor: 1000 * 1000,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'megabyte',
maximumFractionDigits: 1,
minimumFractionDigits: 1,
}),
}, {
factor: 1000 * 1000 * 10,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'megabyte',
maximumFractionDigits: 0,
}),
}, {
factor: 1000 * 1000 * 1000,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'gigabyte',
maximumFractionDigits: 1,
minimumFractionDigits: 1,
}),
}, {
factor: 1000 * 1000 * 1000 * 10,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'gigabyte',
maximumFractionDigits: 0,
}),
}, {
factor: 1000 * 1000 * 1000 * 1000,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'terabyte',
maximumFractionDigits: 1,
minimumFractionDigits: 1,
}),
}, {
factor: 1000 * 1000 * 1000 * 1000 * 10,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'terabyte',
maximumFractionDigits: 0,
}),
}, {
factor: 1000 * 1000 * 1000 * 1000 * 1000,
formatter: new Intl.NumberFormat(undefined, {
style: 'unit',
unit: 'petabyte',
maximumFractionDigits: 1,
minimumFractionDigits: 1,
}),
}];
#lastBytes = 0;
#lastHash = 0;
#lastTime = 0;
_getBytes(_netload) {
}
_getFormat(bytes) {
for (let i = 1; i < this.#formats.length; i++) {
if (bytes < this.#formats.at(i).factor)
return this.#formats.at(i - 1);
}
return this.#formats.at(-1);
}
_update() {
const FLAG_LOOPBACK = 1 << 4; // GTop sucks
const netlist = new GTop.glibtop_netlist();
const ifnames = GTop.glibtop_get_netlist(netlist);
let bytes = 0;
let hash = 1n;
for (const ifname of ifnames) {
const netload = new GTop.glibtop_netload();
GTop.glibtop_get_netload(netload, ifname);
if (netload.if_flags & FLAG_LOOPBACK)
continue;
bytes += this._getBytes(netload);
hash += strHash(ifname);
}
const time = GLib.get_monotonic_time();
let dbytes = 0;
// Skip calculation if new data is less than old (interface
// removed, counters reset, ...) or if it is the first time
if (bytes >= this.#lastBytes &&
hash === this.#lastHash &&
this.#lastTime !== 0) {
const dtime = (time - this.#lastTime) / GLib.USEC_PER_SEC;
dbytes = (bytes - this.#lastBytes) / dtime;
}
this.#lastBytes = bytes;
this.#lastTime = time;
this.#lastHash = hash;
const {factor, formatter} = this._getFormat(dbytes);
this.label.text = formatter.format(dbytes / factor);
}
}
class UploadSection extends NetStatSection {
static {
GObject.registerClass(this);
}
constructor() {
super('upload-symbolic', _('Upload stats'));
}
_getBytes(netload) {
return netload.bytes_out;
}
}
class DownloadSection extends NetStatSection {
static {
GObject.registerClass(this);
}
constructor() {
super('download-symbolic', _('Download stats'));
}
_getBytes(netload) {
return netload.bytes_in;
}
}
class Indicator extends PanelMenu.Button {
static {
GObject.registerClass(this);
}
constructor(settings) {
super(0.5, _('System stats'));
this._settings = settings;
this.connect('destroy',
() => (this._settings = null));
const box = new St.BoxLayout({
styleClass: 'system-monitor-stat-sections',
});
this.add_child(box);
this._placeholder = new St.Icon({
styleClass: 'system-status-icon system-monitor-placeholder',
});
box.add_child(this._placeholder);
this._cpuSection = new CpuSection();
this._settings.bind('show-cpu',
this._cpuSection, 'visible',
Gio.SettingsBindFlags.GET);
box.add_child(this._cpuSection);
this._memSection = new MemSection();
this._settings.bind('show-memory',
this._memSection, 'visible',
Gio.SettingsBindFlags.GET);
box.add_child(this._memSection);
this._swapSection = new SwapSection();
this._settings.bind('show-swap',
this._swapSection, 'visible',
Gio.SettingsBindFlags.GET);
box.add_child(this._swapSection);
this._ulSection = new UploadSection();
this._settings.bind('show-upload',
this._ulSection, 'visible',
Gio.SettingsBindFlags.GET);
box.add_child(this._ulSection);
this._dlSection = new DownloadSection();
this._settings.bind('show-download',
this._dlSection, 'visible',
Gio.SettingsBindFlags.GET);
box.add_child(this._dlSection);
this.menu.addMenuItem(
new PopupMenu.PopupSeparatorMenuItem(_('Show')));
this._cpuItem = this.menu.addAction(_('CPU'),
() => this._toggleSettings('show-cpu'));
this._memItem = this.menu.addAction(_('Memory'),
() => this._toggleSettings('show-memory'));
this._swapItem = this.menu.addAction(_('Swap'),
() => this._toggleSettings('show-swap'));
this._ulItem = this.menu.addAction(_('Upload'),
() => this._toggleSettings('show-upload'));
this._dlItem = this.menu.addAction(_('Download'),
() => this._toggleSettings('show-download'));
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this._appMenuItem = this.menu.addAction(_('Open System Monitor'),
() => this._openSystemMonitor());
const appSystem = Shell.AppSystem.get_default();
appSystem.connectObject('installed-changed',
() => this._updateSystemMonitorApp(), this);
this._updateSystemMonitorApp();
this._settings.connectObject('changed',
() => this._sync(), this);
this._sync();
}
_updateSystemMonitorApp() {
const appSystem = Shell.AppSystem.get_default();
this._systemMonitorApp =
appSystem.lookup_app('gnome-system-monitor.desktop');
this._placeholder.gicon = this._systemMonitorApp?.icon ?? null;
this.visible = this._systemMonitorApp != null;
}
_openSystemMonitor() {
this._systemMonitorApp.activate();
Main.overview.hide();
}
_toggleSettings(key) {
this._settings.set_boolean(key, !this._settings.get_boolean(key));
}
_sync() {
this._cpuItem.setOrnament(this._settings.get_boolean('show-cpu')
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
this._memItem.setOrnament(this._settings.get_boolean('show-memory')
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
this._swapItem.setOrnament(this._settings.get_boolean('show-swap')
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
this._ulItem.setOrnament(this._settings.get_boolean('show-upload')
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
this._dlItem.setOrnament(this._settings.get_boolean('show-download')
? PopupMenu.Ornament.CHECK
: PopupMenu.Ornament.NONE);
this._placeholder.visible =
this._settings.list_keys().every(key => !this._settings.get_boolean(key));
}
}
export default class SystemMonitorExtension extends Extension {
enable() {
this._indicator = new Indicator(this.getSettings());
Main.panel.addToStatusArea(this.uuid, this._indicator);
}
disable() {
this._indicator.destroy();
this._indicator = null;
}
}

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="c">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<mask id="d">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.7"/>
</g>
</mask>
<clipPath id="e">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<mask id="f">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.35"/>
</g>
</mask>
<clipPath id="g">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<g mask="url(#b)">
<g clip-path="url(#c)" transform="matrix(1 0 0 1 -920 -120)">
<path d="m 550 182 c -0.351562 0.003906 -0.695312 0.101562 -1 0.28125 v 3.4375 c 0.304688 0.179688 0.648438 0.277344 1 0.28125 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 c -0.339844 0 -0.679688 0.058594 -1 0.175781 v 6.824219 h 4 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/>
</g>
</g>
<g mask="url(#d)">
<g clip-path="url(#e)" transform="matrix(1 0 0 1 -920 -120)">
<path d="m 569 182 v 4 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 v 7 h 3 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/>
</g>
</g>
<g mask="url(#f)">
<g clip-path="url(#g)" transform="matrix(1 0 0 1 -920 -120)">
<path d="m 573 182.269531 v 3.449219 c 0.613281 -0.355469 0.996094 -1.007812 1 -1.71875 c 0 -0.714844 -0.382812 -1.375 -1 -1.730469 z m 0 4.90625 v 6.824219 h 2 v -4 c 0 -1.269531 -0.800781 -2.402344 -2 -2.824219 z m 0 0"/>
</g>
</g>
<path d="m 7.984375 1 c -0.550781 0 -1 0.449219 -1 1 v 8.585938 l -2.292969 -2.292969 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 s -0.519531 0.105469 -0.707031 0.292969 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 l 4 4 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 l 4 -4 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 s -1.023437 -0.390625 -1.414062 0 l -2.292969 2.292969 v -8.585938 c 0 -0.550781 -0.445313 -1 -1 -1 z m 0 0"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Icon Development Kit
SPDX-License-Identifier: CC0-1.0

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 3 2 c -1.660156 0 -3 1.339844 -3 3 v 4 c 0 1.660156 1.339844 3 3 3 h 10 c 1.660156 0 3 -1.339844 3 -3 v -4 c 0 -1.660156 -1.339844 -3 -3 -3 z m 0 2 h 10 c 0.554688 0 1 0.445312 1 1 v 4 c 0 0.554688 -0.445312 1 -1 1 h -10 c -0.554688 0 -1 -0.445312 -1 -1 v -4 c 0 -0.554688 0.445312 -1 1 -1 z m 0 0"/><path d="m 2 10 h 12 v 4 h -12 z m 0 0"/><g fill-opacity="0.501961"><path d="m 4 5 h 2 v 4 h -2 z m 0 0"/><path d="m 7 5 h 2 v 4 h -2 z m 0 0"/><path d="m 10 5 h 2 v 4 h -2 z m 0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 631 B

View File

@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Icon Development Kit
SPDX-License-Identifier: CC0-1.0

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 5 5 h 6 v 6 h -6 z m 0 0"/><path d="m 13 5 h 3 v 1 h -3 z m 0 0"/><path d="m 13 7 h 3 v 1 h -3 z m 0 0"/><path d="m 13 9 h 3 v 1 h -3 z m 0 0"/><path d="m 0 6 h 3 v 1 h -3 z m 0 0"/><path d="m 0 8 h 3 v 1 h -3 z m 0 0"/><path d="m 0 10 h 3 v 1 h -3 z m 0 0"/><path d="m 5 0 h 1 v 3 h -1 z m 0 0"/><path d="m 7 0 h 1 v 3 h -1 z m 0 0"/><path d="m 9 0 h 1 v 3 h -1 z m 0 0"/><path d="m 10 13 h 1 v 3 h -1 z m 0 0"/><path d="m 8 13 h 1 v 3 h -1 z m 0 0"/><path d="m 6 13 h 1 v 3 h -1 z m 0 0"/><path d="m 5 2 c -1.644531 0 -3 1.355469 -3 3 v 6 c 0 1.644531 1.355469 3 3 3 h 6 c 1.644531 0 3 -1.355469 3 -3 v -6 c 0 -1.644531 -1.355469 -3 -3 -3 z m 0 2 h 6 c 0.570312 0 1 0.429688 1 1 v 6 c 0 0.570312 -0.429688 1 -1 1 h -6 c -0.570312 0 -1 -0.429688 -1 -1 v -6 c 0 -0.570312 0.429688 -1 1 -1 z m 0 0"/></svg>

After

Width:  |  Height:  |  Size: 943 B

View File

@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Icon Development Kit
SPDX-License-Identifier: CC0-1.0

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 5 7 c -0.308594 0 -0.613281 0.089844 -0.8125 0.28125 l -3.59375 3.71875 l 3.65625 3.71875 c 0.199219 0.191406 0.441406 0.28125 0.75 0.28125 h 1 v -1 c 0 -0.257812 -0.128906 -0.527344 -0.3125 -0.71875 l -1.28125 -1.28125 h 4.59375 c 0.527344 0.007812 1 -0.472656 1 -1 s -0.472656 -1.007812 -1 -1 h -4.625 l 1.21875 -1.28125 c 0.183594 -0.191406 0.40625 -0.460938 0.40625 -0.71875 v -1 z m 0 0"/><path d="m 11 9 c 0.308594 0 0.613281 -0.089844 0.8125 -0.28125 l 3.59375 -3.71875 l -3.65625 -3.71875 c -0.199219 -0.191406 -0.441406 -0.28125 -0.75 -0.28125 h -1 v 1 c 0 0.257812 0.128906 0.527344 0.3125 0.71875 l 1.28125 1.28125 h -4.59375 c -0.527344 -0.007812 -1 0.472656 -1 1 s 0.472656 1.007812 1 1 h 4.625 l -1.21875 1.28125 c -0.183594 0.191406 -0.40625 0.460938 -0.40625 0.71875 v 1 z m 0 0"/></svg>

After

Width:  |  Height:  |  Size: 941 B

View File

@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Icon Development Kit
SPDX-License-Identifier: CC0-1.0

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="a" height="100%" width="100%" x="0%" y="0%">
<feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
</filter>
<mask id="b">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.5"/>
</g>
</mask>
<clipPath id="c">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<mask id="d">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.7"/>
</g>
</mask>
<clipPath id="e">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<mask id="f">
<g filter="url(#a)">
<path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.35"/>
</g>
</mask>
<clipPath id="g">
<path d="m 0 0 h 1600 v 1200 h -1600 z"/>
</clipPath>
<g mask="url(#b)">
<g clip-path="url(#c)" transform="matrix(1 0 0 1 -900 -120)">
<path d="m 550 182 c -0.351562 0.003906 -0.695312 0.101562 -1 0.28125 v 3.4375 c 0.304688 0.179688 0.648438 0.277344 1 0.28125 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 c -0.339844 0 -0.679688 0.058594 -1 0.175781 v 6.824219 h 4 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/>
</g>
</g>
<g mask="url(#d)">
<g clip-path="url(#e)" transform="matrix(1 0 0 1 -900 -120)">
<path d="m 569 182 v 4 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 v 7 h 3 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/>
</g>
</g>
<g mask="url(#f)">
<g clip-path="url(#g)" transform="matrix(1 0 0 1 -900 -120)">
<path d="m 573 182.269531 v 3.449219 c 0.613281 -0.355469 0.996094 -1.007812 1 -1.71875 c 0 -0.714844 -0.382812 -1.375 -1 -1.730469 z m 0 4.90625 v 6.824219 h 2 v -4 c 0 -1.269531 -0.800781 -2.402344 -2 -2.824219 z m 0 0"/>
</g>
</g>
<path d="m 8.015625 15 c 0.550781 0 1 -0.449219 1 -1 v -8.585938 l 2.292969 2.292969 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 s 0.519531 -0.105469 0.707031 -0.292969 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 l -4 -4 c -0.390625 -0.390625 -1.023437 -0.390625 -1.414062 0 l -4 4 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 2.292969 -2.292969 v 8.585938 c 0 0.550781 0.445313 1 1 1 z m 0 0"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Icon Development Kit
SPDX-License-Identifier: CC0-1.0

View File

@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: 2017 Florian Müllner <fmuellner@gnome.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later
extension_data += configure_file(
input: metadata_name + '.in',
output: metadata_name,
configuration: metadata_conf
)
extension_data += files('stylesheet.css')
extension_schemas += files('schemas/' + metadata_conf.get('gschemaname') + '.gschema.xml')
install_subdir('icons', install_dir: join_paths(extensiondir, uuid))

View File

@@ -0,0 +1,10 @@
{
"extension-id": "@extension_id@",
"uuid": "@uuid@",
"settings-schema": "@gschemaname@",
"gettext-domain": "@gettext_domain@",
"name": "System Monitor",
"description": "Monitor system from the top bar",
"shell-version": [ "@shell_current@" ],
"url": "@url@"
}

View File

@@ -0,0 +1,31 @@
<!--
SPDX-FileCopyrightText: 2023 Florian Müllner <fmuellner@gnome.org>
SPDX-License-Identifier: GPL-2.0-or-later
-->
<schemalist gettext-domain="gnome-shell-extensions">
<schema id="org.gnome.shell.extensions.system-monitor"
path="/org/gnome/shell/extensions/system-monitor/">
<key name="show-cpu" type="b">
<default>true</default>
<summary>Show CPU usage</summary>
</key>
<key name="show-memory" type="b">
<default>true</default>
<summary>Show memory usage</summary>
</key>
<key name="show-swap" type="b">
<default>true</default>
<summary>Show swap usage</summary>
</key>
<key name="show-upload" type="b">
<default>true</default>
<summary>Show upload</summary>
</key>
<key name="show-download" type="b">
<default>true</default>
<summary>Show download</summary>
</key>
</schema>
</schemalist>

View File

@@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2023 Florian Müllner <fmuellner@gnome.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
.system-monitor-stat-section {
padding: 0 6px;
}
.system-monitor-stat-section-icon {icon-size: 1.08em;}
.system-monitor-stat-section-label {
min-width: 3.0em;
font-size: 0.9em;
}
.system-monitor-placeholder {-st-icon-style: symbolic;}
.panel-button .high-usage {color: #ff7800;}

View File

@@ -21,12 +21,13 @@ const SETTINGS_KEY = 'name';
export default class ThemeManager extends Extension {
enable() {
this._settings = this.getSettings();
this._settings.connect(`changed::${SETTINGS_KEY}`, this._changeTheme.bind(this));
this._settings.connectObject(`changed::${SETTINGS_KEY}`,
this._changeTheme.bind(this), this);
this._changeTheme();
}
disable() {
this._settings?.run_dispose();
this._settings?.disconnectObject();
this._settings = null;
Main.setThemeStylesheet(null);

View File

@@ -36,7 +36,7 @@ class UserThemePrefsWidget extends Adw.PreferencesGroup {
this._actionGroup.add_action(
this._settings.create_action('name'));
this.connect('destroy', () => this._settings.run_dispose());
this.connect('destroy', () => (this._settings = null));
this._rows = new Map();
this._addTheme(''); // default

View File

@@ -17,10 +17,8 @@ import {Extension, gettext as _} from 'resource:///org/gnome/shell/extensions/ex
import * as DND from 'resource:///org/gnome/shell/ui/dnd.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import * as Overview from 'resource:///org/gnome/shell/ui/overview.js';
import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
import {WindowPicker, WindowPickerToggle} from './windowPicker.js';
import {WorkspaceIndicator} from './workspaceIndicator.js';
const ICON_TEXTURE_SIZE = 24;
@@ -123,10 +121,10 @@ class WindowTitle extends St.BoxLayout {
this._metaWindow = metaWindow;
this._icon = new St.Bin({style_class: 'window-button-icon'});
this.add(this._icon);
this.add_child(this._icon);
this.label_actor = new St.Label({y_align: Clutter.ActorAlign.CENTER});
this.label_actor.clutter_text.single_line_mode = true;
this.add(this.label_actor);
this.add_child(this.label_actor);
this._textureCache = St.TextureCache.get_default();
this._textureCache.connectObject('icon-theme-changed',
@@ -412,7 +410,7 @@ class WindowButton extends BaseButton {
this._onMenuStateChanged.bind(this));
this._contextMenu.actor.hide();
this._contextMenuManager.addMenu(this._contextMenu);
Main.uiGroup.add_actor(this._contextMenu.actor);
Main.uiGroup.add_child(this._contextMenu.actor);
global.display.connectObject('notify::focus-window',
() => this._updateStyle(), this);
@@ -538,25 +536,25 @@ class AppButton extends BaseButton {
this._singleWindowTitle = new St.Bin({
x_expand: true,
});
stack.add_actor(this._singleWindowTitle);
stack.add_child(this._singleWindowTitle);
this._multiWindowTitle = new St.BoxLayout({
style_class: 'window-button-box',
x_expand: true,
});
stack.add_actor(this._multiWindowTitle);
stack.add_child(this._multiWindowTitle);
this._icon = new St.Bin({
style_class: 'window-button-icon',
child: app.create_icon_texture(ICON_TEXTURE_SIZE),
});
this._multiWindowTitle.add(this._icon);
this._multiWindowTitle.add_child(this._icon);
let label = new St.Label({
text: app.get_name(),
y_align: Clutter.ActorAlign.CENTER,
});
this._multiWindowTitle.add(label);
this._multiWindowTitle.add_child(label);
this._multiWindowTitle.label_actor = label;
this._menuManager = new PopupMenu.PopupMenuManager(this);
@@ -566,13 +564,13 @@ class AppButton extends BaseButton {
this._menu.actor.hide();
this._menu.connect('activate', this._onMenuActivate.bind(this));
this._menuManager.addMenu(this._menu);
Main.uiGroup.add_actor(this._menu.actor);
Main.uiGroup.add_child(this._menu.actor);
this._appContextMenu = new AppContextMenu(this);
this._appContextMenu.connect('open-state-changed',
this._onMenuStateChanged.bind(this));
this._appContextMenu.actor.hide();
Main.uiGroup.add_actor(this._appContextMenu.actor);
Main.uiGroup.add_child(this._appContextMenu.actor);
this._textureCache = St.TextureCache.get_default();
this._textureCache.connectObject('icon-theme-changed', () => {
@@ -637,7 +635,7 @@ class AppButton extends BaseButton {
this._windowContextMenu = new WindowContextMenu(this, this.metaWindow);
this._windowContextMenu.connect(
'open-state-changed', this._onMenuStateChanged.bind(this));
Main.uiGroup.add_actor(this._windowContextMenu.actor);
Main.uiGroup.add_child(this._windowContextMenu.actor);
this._windowContextMenu.actor.hide();
this._contextMenuManager.addMenu(this._windowContextMenu);
}
@@ -682,7 +680,7 @@ class AppButton extends BaseButton {
for (let i = 0; i < windows.length; i++) {
let windowTitle = new WindowTitle(windows[i]);
let item = new PopupMenu.PopupBaseMenuItem();
item.add_actor(windowTitle);
item.add_child(windowTitle);
item._window = windows[i];
this._menu.addMenuItem(item);
}
@@ -728,13 +726,7 @@ class WindowList extends St.Widget {
this._monitor = monitor;
let box = new St.BoxLayout({x_expand: true, y_expand: true});
this.add_actor(box);
let toggle = new WindowPickerToggle();
box.add_actor(toggle);
toggle.connect('notify::checked',
this._updateWindowListVisibility.bind(this));
this.add_child(box);
let layout = new Clutter.BoxLayout({homogeneous: true});
this._windowList = new St.Widget({
@@ -755,7 +747,7 @@ class WindowList extends St.Widget {
this._windowList.connect('scroll-event', this._onScrollEvent.bind(this));
let indicatorsBox = new St.BoxLayout({x_align: Clutter.ActorAlign.END});
box.add(indicatorsBox);
box.add_child(indicatorsBox);
this._workspaceIndicator = new WorkspaceIndicator();
indicatorsBox.add_child(this._workspaceIndicator.container);
@@ -828,8 +820,8 @@ class WindowList extends St.Widget {
}, this);
this._windowSignals = new Map();
this._windowCreatedId = global.display.connect(
'window-created', (dsp, win) => this._addWindow(win));
global.display.connectObject(
'window-created', (dsp, win) => this._addWindow(win), this);
Main.xdndHandler.connectObject(
'drag-begin', () => this._monitorDrag(),
@@ -844,8 +836,8 @@ class WindowList extends St.Widget {
this._dndWindow = null;
this._settings = settings;
this._settings.connect('changed::grouping-mode',
() => this._groupingModeChanged());
this._settings.connectObject('changed::grouping-mode',
() => this._groupingModeChanged(), this);
this._grouped = undefined;
this._groupingModeChanged();
}
@@ -883,20 +875,6 @@ class WindowList extends St.Widget {
this._workspaceIndicator.visible = hasWorkspaces && workspacesOnMonitor;
}
_updateWindowListVisibility() {
const {windowPicker} = Extension.lookupByURL(import.meta.url);
const visible = !windowPicker.visible;
this._windowList.ease({
opacity: visible ? 255 : 0,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: Overview.ANIMATION_TIME,
});
this._windowList.reactive = visible;
this._windowList.get_children().forEach(c => (c.reactive = visible));
}
_getPreferredUngroupedWindowListWidth() {
if (this._windowList.get_n_children() === 0)
return this._windowList.get_preferred_width(-1)[1];
@@ -1092,7 +1070,8 @@ class WindowList extends St.Widget {
this._stopMonitoringDrag();
this._settings.run_dispose();
this._settings.disconnectObject();
this._settings = null;
let windows = global.get_window_actors();
for (let i = 0; i < windows.length; i++)
@@ -1105,7 +1084,6 @@ export default class WindowListExtension extends Extension {
super(metadata);
this._windowLists = null;
this._hideOverviewOrig = Main.overview.hide;
}
enable() {
@@ -1118,13 +1096,6 @@ export default class WindowListExtension extends Extension {
Main.layoutManager.connectObject('monitors-changed',
() => this._buildWindowLists(), this);
this.windowPicker = new WindowPicker();
Main.overview.hide = () => {
this.windowPicker.close();
this._hideOverviewOrig.call(Main.overview);
};
this._buildWindowLists();
}
@@ -1144,19 +1115,15 @@ export default class WindowListExtension extends Extension {
if (!this._windowLists)
return;
this._settings.disconnectObject(this);
Main.layoutManager.disconnectObject(this);
this._settings.disconnectObject(this);
this._settings = null;
this._windowLists.forEach(windowList => {
windowList.hide();
windowList.destroy();
});
this._windowLists = null;
this.windowPicker.destroy();
delete this.windowPicker;
Main.overview.hide = this._hideOverviewOrig;
}
someWindowListContains(actor) {

View File

@@ -12,5 +12,5 @@ extension_data += files(
'stylesheet-light.css'
)
extension_sources += files('prefs.js', 'windowPicker.js', 'workspaceIndicator.js')
extension_sources += files('prefs.js', 'workspaceIndicator.js')
extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml')

View File

@@ -6,115 +6,111 @@
*/
.window-list {
spacing: 2px;
font-size: 10pt;
spacing: 2px;
font-size: 10pt;
}
.bottom-panel {
background-color: #000000;
border-top-width: 0px;
padding: 2px;
background-color: #000000;
border-top-width: 0px;
height: 2.45em;
}
.window-button {
padding: 2px, 1px;
padding: 4px, 3px;
}
.window-button:first-child:ltr {
padding-left: 2px;
padding-left: 2px;
}
.window-button:last-child:rtl {
padding-right: 2px;
padding-right: 2px;
}
.window-button-box {
spacing: 4px;
}
.window-button > StWidget,
.window-picker-toggle > StWidget {
color: #bbb;
background-color: #1d1d1d;
border-radius: 4px;
padding: 3px 6px 1px;
transition: 100ms ease;
spacing: 4px;
}
.window-button > StWidget {
-st-natural-width: 18.75em;
max-width: 18.75em;
color: #bbb;
background-color: #1d1d1d;
border-radius: 4px;
padding: 3px 6px 1px;
transition: 100ms ease;
}
.window-button:hover > StWidget,
.window-picker-toggle:hover > StWidget {
color: #fff;
background-color: #303030;
.window-button > StWidget {
-st-natural-width: 18.75em;
max-width: 18.75em;
}
.window-button:hover > StWidget {
color: #fff;
background-color: #303030;
}
.window-button:active > StWidget,
.window-button:focus > StWidget {
color: #fff;
background-color: #3f3f3f;
color: #fff;
background-color: #3f3f3f;
}
.window-button.focused > StWidget,
.window-picker-toggle:checked > StWidget {
color: #fff;
background-color: #3f3f3f;
.window-button.focused > StWidget {
color: #fff;
background-color: #3f3f3f;
}
.window-button.focused:active > StWidget,
.window-picker-toggle:checked:active > StWidget {
color: #fff;
background-color: #3f3f3f;
.window-button.focused:active > StWidget {
color: #fff;
background-color: #3f3f3f;
}
.window-button.minimized > StWidget {
color: #666;
background-color: #161616;
color: #666;
background-color: #161616;
}
.window-button.minimized:active > StWidget {
color: #666;
background-color: #161616;
color: #666;
background-color: #161616;
}
.window-button-icon {
width: 24px;
height: 24px;
width: 24px;
height: 24px;
}
.window-list-workspace-indicator .status-label-bin {
background-color: rgba(200, 200, 200, 0.3);
padding: 0 3px;
margin: 3px;
background-color: rgba(200, 200, 200, 0.3);
padding: 5px;
margin: 3px;
}
.window-list-workspace-indicator .workspaces-box {
spacing: 3px;
padding: 3px;
spacing: 3px;
padding: 5px;
}
.window-list-workspace-indicator .workspace {
width: 52px;
border-radius: 4px;
background-color: #1e1e1e;
width: 52px;
border-radius: 4px;
background-color: #1e1e1e;
}
.window-list-workspace-indicator .workspace.active {
background-color: #3f3f3f;
background-color: #3f3f3f;
}
.window-list-window-preview {
background-color: #bebebe;
border-radius: 1px;
background-color: #bebebe;
border-radius: 1px;
}
.window-list-window-preview.active {
background-color: #d4d4d4;
background-color: #d4d4d4;
}
.notification {
font-weight: normal;
font-weight: normal;
}

View File

@@ -10,12 +10,10 @@
#panel.bottom-panel {
border-top-width: 1px;
border-bottom-width: 0px;
height: 2.25em ;
padding: 2px;
height: 2.5em;
}
.bottom-panel .window-button > StWidget,
.bottom-panel .window-picker-toggle > StWidget {
.bottom-panel .window-button > StWidget {
color: #2e3436;
background-color: #eee;
border-radius: 3px;
@@ -30,8 +28,7 @@
max-width: 18.75em;
}
.bottom-panel .window-button:hover > StWidget,
.bottom-panel .window-picker-toggle:hover > StWidget {
.bottom-panel .window-button:hover > StWidget {
background-color: #f9f9f9;
}
@@ -40,8 +37,7 @@
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}
.bottom-panel .window-button.focused > StWidget,
.bottom-panel .window-picker-toggle:checked > StWidget {
.bottom-panel .window-button.focused > StWidget {
background-color: #ccc;
box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}

View File

@@ -1,342 +0,0 @@
// SPDX-FileCopyrightText: 2019 Florian Müllner <fmuellner@gnome.org>
// SPDX-FileCopyrightText: 2019 Marco Trevisan (Treviño) <mail@3v1n0.net>
//
// SPDX-License-Identifier: GPL-2.0-or-later
import Clutter from 'gi://Clutter';
import GObject from 'gi://GObject';
import Shell from 'gi://Shell';
import St from 'gi://St';
import {Extension, InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
import * as Layout from 'resource:///org/gnome/shell/ui/layout.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import {WorkspacesDisplay} from 'resource:///org/gnome/shell/ui/workspacesView.js';
import * as Workspace from 'resource:///org/gnome/shell/ui/workspace.js';
import {VIGNETTE_BRIGHTNESS} from 'resource:///org/gnome/shell/ui/lightbox.js';
import {
SIDE_CONTROLS_ANIMATION_TIME,
OverviewAdjustment,
ControlsState
} from 'resource:///org/gnome/shell/ui/overviewControls.js';
class MyWorkspacesDisplay extends WorkspacesDisplay {
static {
GObject.registerClass(this);
}
constructor(controls, overviewAdjustment) {
let workspaceManager = global.workspace_manager;
const workspaceAdjustment = new St.Adjustment({
value: workspaceManager.get_active_workspace_index(),
lower: 0,
page_increment: 1,
page_size: 1,
step_increment: 0,
upper: workspaceManager.n_workspaces,
});
super(controls, workspaceAdjustment, overviewAdjustment);
this._windowPicker = controls;
this._workspaceAdjustment = workspaceAdjustment;
this._workspaceAdjustment.actor = this;
workspaceManager.connectObject('notify::n-workspaces',
() => this._updateAdjustment(), this);
this.add_constraint(
new Layout.MonitorConstraint({
primary: true,
work_area: true,
}));
}
prepareToEnterOverview(...args) {
if (!this._scrollEventId) {
this._scrollEventId = this._windowPicker.connect('scroll-event',
this._onScrollEvent.bind(this));
}
super.prepareToEnterOverview(...args);
}
vfunc_hide(...args) {
if (this._scrollEventId > 0)
this._windowPicker.disconnect(this._scrollEventId);
this._scrollEventId = 0;
super.vfunc_hide(...args);
}
_updateAdjustment() {
let workspaceManager = global.workspace_manager;
this._workspaceAdjustment.set({
upper: workspaceManager.n_workspaces,
value: workspaceManager.get_active_workspace_index(),
});
}
}
export class WindowPicker extends Clutter.Actor {
static [GObject.signals] = {
'open-state-changed': {param_types: [GObject.TYPE_BOOLEAN]},
};
static {
GObject.registerClass(this);
}
constructor() {
super({reactive: true});
this._visible = false;
this._modal = false;
this._stageKeyPressId = 0;
this._adjustment = new OverviewAdjustment(this);
this._injectionManager = new InjectionManager();
this.connect('destroy', this._onDestroy.bind(this));
global.bind_property('screen-width',
this, 'width',
GObject.BindingFlags.SYNC_CREATE);
global.bind_property('screen-height',
this, 'height',
GObject.BindingFlags.SYNC_CREATE);
this._workspacesDisplay = new MyWorkspacesDisplay(this, this._adjustment);
this.add_child(this._workspacesDisplay);
Main.uiGroup.insert_child_below(this, global.window_group);
if (!Main.sessionMode.hasOverview) {
this._injectBackgroundShade();
global.display.connectObject('overlay-key', () => {
if (!this._visible)
this.open();
else
this.close();
}, this);
}
}
_injectBackgroundShade() {
const backgroundProto = Workspace.WorkspaceBackground.prototype;
this._injectionManager.overrideMethod(backgroundProto, '_updateBorderRadius',
() => {
return function () {};
});
this._injectionManager.overrideMethod(backgroundProto, 'vfunc_allocate',
() => {
/* eslint-disable no-invalid-this */
return function (box) {
this.set_allocation(box);
const themeNode = this.get_theme_node();
const contentBox = themeNode.get_content_box(box);
this._bin.allocate(contentBox);
const [contentWidth, contentHeight] = contentBox.get_size();
const monitor = Main.layoutManager.monitors[this._monitorIndex];
const xRatio = contentWidth / this._workarea.width;
const yRatio = contentHeight / this._workarea.height;
const right = area => area.x + area.width;
const bottom = area => area.y + area.height;
const offsets = {
left: xRatio * (this._workarea.x - monitor.x),
right: xRatio * (right(monitor) - right(this._workarea)),
top: yRatio * (this._workarea.y - monitor.y),
bottom: yRatio * (bottom(monitor) - bottom(this._workarea)),
};
contentBox.set_origin(-offsets.left, -offsets.top);
contentBox.set_size(
offsets.left + contentWidth + offsets.right,
offsets.top + contentHeight + offsets.bottom);
this._backgroundGroup.allocate(contentBox);
};
/* eslint-enable */
});
this._injectionManager.overrideMethod(backgroundProto, 'vfunc_parent_set',
() => {
/* eslint-disable no-invalid-this */
return function () {
setTimeout(() => {
const parent = this.get_parent();
if (!parent)
return;
parent._overviewAdjustment.connectObject('notify::value', () => {
const {value: progress} = parent._overviewAdjustment;
const brightness = 1 - (1 - VIGNETTE_BRIGHTNESS) * progress;
for (const bg of this._backgroundGroup ?? []) {
bg.content.set({
vignette: true,
brightness,
});
}
}, this);
});
};
/* eslint-enable */
});
}
get visible() {
return this._visible;
}
open() {
if (this._visible)
return;
this._visible = true;
if (!this._syncGrab())
return;
this._fakeOverviewVisible(true);
this._workspacesDisplay.prepareToEnterOverview();
Main.overview._animationInProgress = true;
this._adjustment.value = ControlsState.HIDDEN;
this._adjustment.ease(ControlsState.WINDOW_PICKER, {
duration: SIDE_CONTROLS_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => (Main.overview._animationInProgress = false),
});
this._stageKeyPressId = global.stage.connect('key-press-event',
(a, event) => {
let sym = event.get_key_symbol();
if (sym === Clutter.KEY_Escape) {
this.close();
return Clutter.EVENT_STOP;
}
return Clutter.EVENT_PROPAGATE;
});
this.emit('open-state-changed', this._visible);
}
close() {
if (!this._visible)
return;
this._visible = false;
if (!this._syncGrab())
return;
this._workspacesDisplay.prepareToLeaveOverview();
Main.overview._animationInProgress = true;
this._adjustment.ease(ControlsState.HIDDEN, {
duration: SIDE_CONTROLS_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => {
Main.overview._animationInProgress = false;
this._workspacesDisplay.hide();
this._fakeOverviewVisible(false);
},
});
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
this.emit('open-state-changed', this._visible);
}
getWorkspacesBoxForState() {
return this.allocation;
}
_fakeOverviewVisible(visible) {
// Fake overview state for WorkspacesDisplay
Main.overview._visible = visible;
// Hide real windows
Main.layoutManager._inOverview = visible;
Main.layoutManager._updateVisibility();
}
_syncGrab() {
if (this._visible) {
if (this._modal)
return true;
const grab = Main.pushModal(global.stage, {
actionMode: Shell.ActionMode.OVERVIEW,
});
if (grab.get_seat_state() !== Clutter.GrabState.NONE) {
this._grab = grab;
this._modal = true;
} else {
Main.popModal(grab);
this.hide();
return false;
}
} else if (this._modal) {
Main.popModal(this._grab);
this._modal = false;
this._grab = null;
}
return true;
}
_onDestroy() {
this._injectionManager.clear();
if (this._stageKeyPressId)
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
}
}
export class WindowPickerToggle extends St.Button {
static {
GObject.registerClass(this);
}
constructor() {
let iconBin = new St.Widget({
layout_manager: new Clutter.BinLayout(),
});
iconBin.add_child(new St.Icon({
icon_name: 'focus-windows-symbolic',
icon_size: 16,
x_expand: true,
y_expand: true,
x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER,
}));
super({
style_class: 'window-picker-toggle',
child: iconBin,
visible: !Main.sessionMode.hasOverview,
toggle_mode: true,
});
const {windowPicker} = Extension.lookupByURL(import.meta.url);
this.connect('notify::checked', () => {
if (this.checked)
windowPicker.open();
else
windowPicker.close();
});
windowPicker.connect('open-state-changed', () => {
this.checked = windowPicker.visible;
});
}
}

View File

@@ -36,13 +36,12 @@ class WindowPreview extends St.Button {
this._window = window;
this._window.connectObject(
'size-changed', () => this.queue_relayout(),
'position-changed', () => {
this._updateVisible();
this.queue_relayout();
},
'size-changed', () => this._checkRelayout(),
'position-changed', () => this._checkRelayout(),
'notify::minimized', this._updateVisible.bind(this),
'notify::window-type', this._updateVisible.bind(this),
this);
this._updateVisible();
global.display.connectObject('notify::focus-window',
this._onFocusChanged.bind(this), this);
@@ -61,11 +60,15 @@ class WindowPreview extends St.Button {
this.remove_style_class_name('active');
}
_updateVisible() {
_checkRelayout() {
const monitor = Main.layoutManager.findIndexForActor(this);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
this.visible = this._window.get_frame_rect().overlap(workArea) &&
this._window.window_type !== Meta.WindowType.DESKTOP &&
if (this._window.get_frame_rect().overlap(workArea))
this.queue_relayout();
}
_updateVisible() {
this.visible = this._window.window_type !== Meta.WindowType.DESKTOP &&
this._window.showing_on_its_workspace();
}
}
@@ -258,7 +261,7 @@ export class WorkspaceIndicator extends PanelMenu.Button {
x_expand: true,
y_expand: true,
});
this.add_actor(container);
this.add_child(container);
let workspaceManager = global.workspace_manager;
@@ -271,7 +274,7 @@ export class WorkspaceIndicator extends PanelMenu.Button {
y_expand: true,
child: this._statusLabel,
});
container.add_actor(this._statusBin);
container.add_child(this._statusBin);
this._thumbnailsBox = new St.BoxLayout({
style_class: 'workspaces-box',
@@ -280,7 +283,7 @@ export class WorkspaceIndicator extends PanelMenu.Button {
});
this._thumbnailsBox.connect('scroll-event',
this._onScrollEvent.bind(this));
container.add_actor(this._thumbnailsBox);
container.add_child(this._thumbnailsBox);
this._workspacesItems = [];
@@ -394,7 +397,7 @@ export class WorkspaceIndicator extends PanelMenu.Button {
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let thumb = new WorkspaceThumbnail(i);
this._thumbnailsBox.add_actor(thumb);
this._thumbnailsBox.add_child(thumb);
}
this._updateActiveThumbnail();
}

View File

@@ -86,7 +86,7 @@ export default class Extension {
style_class: 'extension-windowsNavigator-window-tooltip',
visible: false,
});
this.add_actor(this._tip);
this.add_child(this._tip);
this.connect('notify::scale-x', () => {
this._tip.set_scale(1 / this.scale_x, 1 / this.scale_x);

View File

@@ -42,13 +42,12 @@ class WindowPreview extends St.Button {
this._window = window;
this._window.connectObject(
'size-changed', () => this.queue_relayout(),
'position-changed', () => {
this._updateVisible();
this.queue_relayout();
},
'size-changed', () => this._checkRelayout(),
'position-changed', () => this._checkRelayout(),
'notify::minimized', this._updateVisible.bind(this),
'notify::window-type', this._updateVisible.bind(this),
this);
this._updateVisible();
global.display.connectObject('notify::focus-window',
this._onFocusChanged.bind(this), this);
@@ -67,11 +66,15 @@ class WindowPreview extends St.Button {
this.remove_style_class_name('active');
}
_updateVisible() {
_checkRelayout() {
const monitor = Main.layoutManager.findIndexForActor(this);
const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
this.visible = this._window.get_frame_rect().overlap(workArea) &&
this._window.window_type !== Meta.WindowType.DESKTOP &&
if (this._window.get_frame_rect().overlap(workArea))
this.queue_relayout();
}
_updateVisible() {
this.visible = this._window.window_type !== Meta.WindowType.DESKTOP &&
this._window.showing_on_its_workspace();
}
}
@@ -260,7 +263,7 @@ class WorkspaceIndicator extends PanelMenu.Button {
x_expand: true,
y_expand: true,
});
this.add_actor(container);
this.add_child(container);
let workspaceManager = global.workspace_manager;
@@ -271,7 +274,7 @@ class WorkspaceIndicator extends PanelMenu.Button {
text: this._labelText(),
});
container.add_actor(this._statusLabel);
container.add_child(this._statusLabel);
this._thumbnailsBox = new St.BoxLayout({
style_class: 'panel-workspace-indicator-box',
@@ -279,7 +282,7 @@ class WorkspaceIndicator extends PanelMenu.Button {
reactive: true,
});
container.add_actor(this._thumbnailsBox);
container.add_child(this._thumbnailsBox);
this._workspacesItems = [];
this._workspaceSection = new PopupMenu.PopupMenuSection();
@@ -402,7 +405,7 @@ class WorkspaceIndicator extends PanelMenu.Button {
for (let i = 0; i < workspaceManager.n_workspaces; i++) {
let thumb = new WorkspaceThumbnail(i);
this._thumbnailsBox.add_actor(thumb);
this._thumbnailsBox.add_child(thumb);
}
this._updateActiveThumbnail();
}

View File

@@ -18,7 +18,6 @@ Most extensions can be installed by configuring --prefix=$HOME/.local,
and will be picked automatically at next login.
</description>
<homepage rdf:resource="https://wiki.gnome.org/Projects/GnomeShell/Extensions" />
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
<support-forum rdf:resource="https://discourse.gnome.org/tag/shell" />
<download-page rdf:resource="https://download.gnome.org/sources/gnome-shell-extensions/" />
<bug-database rdf:resource="https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues" />

View File

@@ -12,6 +12,12 @@ rules:
- error
- smart
prefer-arrow-callback: error
jsdoc/require-param-description: off
jsdoc/require-jsdoc:
- error
- exemptEmptyFunctions: true
publicOnly:
esm: true
globals:
global: readonly
parserOptions:

View File

@@ -3,7 +3,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
project('gnome-shell-extensions',
version: '45.0',
version: '46.alpha',
meson_version: '>= 0.58.0',
license: 'GPL2+'
)
@@ -42,6 +42,7 @@ default_extensions += [
'drive-menu',
'light-style',
'screenshot-window-sizer',
'system-monitor',
'windowsNavigator',
'workspace-indicator'
]

103
po/eo.po
View File

@@ -3,39 +3,48 @@
# This file is distributed under the same license as the gnome-shell-extensions package.
# Ryan LORTIE <desrt@desrt.ca>, 2013.
# Daniel PUENTES <blatberk@openmailbox.org>, 2015.
# Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2011-2019.
# Carmen Bianca BAKKER <carmen@carmenbianca.eu>, 2021.
# Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2011-2023.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell-extensions master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/"
"issues\n"
"POT-Creation-Date: 2021-03-27 20:14+0000\n"
"PO-Revision-Date: 2021-03-29 17:24+0200\n"
"Last-Translator: Carmen Bianca BAKKER <carmen@carmenbianca.eu>\n"
"POT-Creation-Date: 2023-08-05 15:58+0000\n"
"PO-Revision-Date: 2023-09-27 22:47+0200\n"
"Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n"
"Language-Team: Esperanto <gnome-eo-list@gnome.org>\n"
"Language: eo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Generator: Gtranslator 3.38.0\n"
"X-Generator: Gtranslator 42.0\n"
"X-Project-Style: gnome\n"
#: data/gnome-classic.desktop.in:3
msgid "GNOME Classic"
msgstr "GNOME-klasika"
#: data/gnome-classic.desktop.in:4
#: data/gnome-classic.desktop.in:4 data/gnome-classic-wayland.desktop.in:4
#: data/gnome-classic-xorg.desktop.in:4
msgid "This session logs you into GNOME Classic"
msgstr "Ĉi tiu seanco ensalutas vin GNOME-klasiken"
#: extensions/apps-menu/extension.js:113
#: data/gnome-classic-wayland.desktop.in:3
msgid "GNOME Classic on Wayland"
msgstr "GNOME-klasika je Vajlando"
#: data/gnome-classic-xorg.desktop.in:3
msgid "GNOME Classic on Xorg"
msgstr "GNOME-klasika je Xorg"
#: extensions/apps-menu/extension.js:121
msgid "Favorites"
msgstr "Plej ŝatataj"
#: extensions/apps-menu/extension.js:367
#: extensions/apps-menu/extension.js:378
msgid "Applications"
msgstr "Aplikaĵoj"
@@ -51,26 +60,26 @@ msgstr ""
"Listo de ĉenoj, ĉiu enhavas aplikaĵan identigilon ('desktop' dosiernomo), "
"sevkita per dupunkto kaj la laborspaca numero"
#: extensions/auto-move-windows/prefs.js:35
#: extensions/auto-move-windows/prefs.js:155
msgid "Workspace Rules"
msgstr "Laborspacaj reguloj"
#: extensions/auto-move-windows/prefs.js:237
#: extensions/auto-move-windows/prefs.js:309
msgid "Add Rule"
msgstr "Aldoni regulon"
#. TRANSLATORS: %s is the filesystem name
#: extensions/drive-menu/extension.js:112
#: extensions/places-menu/placeDisplay.js:233
#: extensions/drive-menu/extension.js:122
#: extensions/places-menu/placeDisplay.js:213
#, javascript-format
msgid "Ejecting drive “%s” failed:"
msgstr "Elĵeto de volumo “%s” malsukcesis:"
#: extensions/drive-menu/extension.js:128
#: extensions/drive-menu/extension.js:141
msgid "Removable devices"
msgstr "Demeteblaj aparatoj"
#: extensions/drive-menu/extension.js:152
#: extensions/drive-menu/extension.js:163
msgid "Open Files"
msgstr "Malfermi dosierojn"
@@ -102,31 +111,31 @@ msgstr ""
"estas meti ĝin malsupre). Si vi ŝanĝas ĉi agordon tiam vi devas restartigi "
"la ŝelon."
#: extensions/places-menu/extension.js:89
#: extensions/places-menu/extension.js:92
#: extensions/places-menu/extension.js:85
#: extensions/places-menu/extension.js:88
msgid "Places"
msgstr "Lokoj"
#: extensions/places-menu/placeDisplay.js:46
#: extensions/places-menu/placeDisplay.js:53
#, javascript-format
msgid "Failed to launch “%s”"
msgstr "Malsukcesis lanĉi “%s”"
#: extensions/places-menu/placeDisplay.js:61
#: extensions/places-menu/placeDisplay.js:68
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "Ne eblis munti datumportilon por “%s”"
#: extensions/places-menu/placeDisplay.js:148
#: extensions/places-menu/placeDisplay.js:171
#: extensions/places-menu/placeDisplay.js:128
#: extensions/places-menu/placeDisplay.js:151
msgid "Computer"
msgstr "Komputilo"
#: extensions/places-menu/placeDisplay.js:359
#: extensions/places-menu/placeDisplay.js:328
msgid "Home"
msgstr "Domo"
#: extensions/places-menu/placeDisplay.js:404
#: extensions/places-menu/placeDisplay.js:373
msgid "Browse Network"
msgstr "Foliumi reton"
@@ -146,47 +155,47 @@ msgstr "Etosnomo"
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell"
msgstr "La nomo de la etoso, malfermigi de ~/.themes/name/gnome-shell"
#: extensions/window-list/extension.js:98
#: extensions/window-list/extension.js:71
msgid "Close"
msgstr "Fermi"
#: extensions/window-list/extension.js:118
#: extensions/window-list/extension.js:98
msgid "Unminimize"
msgstr "Malminimumigi"
#: extensions/window-list/extension.js:118
#: extensions/window-list/extension.js:98
msgid "Minimize"
msgstr "Minimumigi"
#: extensions/window-list/extension.js:125
#: extensions/window-list/extension.js:105
msgid "Unmaximize"
msgstr "Malmaksimumigi"
#: extensions/window-list/extension.js:125
#: extensions/window-list/extension.js:105
msgid "Maximize"
msgstr "Maksimumigi"
#: extensions/window-list/extension.js:432
#: extensions/window-list/extension.js:468
msgid "Minimize all"
msgstr "Minimumigi ĉiujn"
#: extensions/window-list/extension.js:438
#: extensions/window-list/extension.js:474
msgid "Unminimize all"
msgstr "Malminimumigi ĉiujn"
#: extensions/window-list/extension.js:444
#: extensions/window-list/extension.js:480
msgid "Maximize all"
msgstr "Maksimumigi ĉiujn"
#: extensions/window-list/extension.js:452
#: extensions/window-list/extension.js:488
msgid "Unmaximize all"
msgstr "Malmaksimumigi ĉiujn"
#: extensions/window-list/extension.js:460
#: extensions/window-list/extension.js:496
msgid "Close all"
msgstr "Fermi ĉiujn"
#: extensions/window-list/extension.js:737
#: extensions/window-list/extension.js:776
msgid "Window List"
msgstr "Fenestra listo"
@@ -203,7 +212,7 @@ msgstr ""
"Validaj valoroj estas “neniam”, “aŭtomate” kaj ĉiam”."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
#: extensions/window-list/prefs.js:100
#: extensions/window-list/prefs.js:76
msgid "Show windows from all workspaces"
msgstr "Montri la fenestrojn de ĉiuj laborspacoj"
@@ -222,41 +231,41 @@ msgid ""
msgstr ""
"Ĉu montri la fenestroliston en ĉiuj konektitaj ekranoj aŭ nur en la ĉefa."
#: extensions/window-list/prefs.js:29
#: extensions/window-list/prefs.js:32
msgid "Window Grouping"
msgstr "Fenestra grupigo"
#: extensions/window-list/prefs.js:58
#: extensions/window-list/prefs.js:37
msgid "Never group windows"
msgstr "Neniam grupigi fenestrojn"
#: extensions/window-list/prefs.js:59
#: extensions/window-list/prefs.js:38
msgid "Group windows when space is limited"
msgstr "Grupigi fenestrojn kiam spaco limitas"
#: extensions/window-list/prefs.js:60
#: extensions/window-list/prefs.js:39
msgid "Always group windows"
msgstr "Ĉiam grupigi fenestrojn"
#: extensions/window-list/prefs.js:94
#: extensions/window-list/prefs.js:63
msgid "Show on all monitors"
msgstr "Montri en ĉiuj ekranoj"
#: extensions/window-list/workspaceIndicator.js:249
#: extensions/workspace-indicator/extension.js:255
#: extensions/window-list/workspaceIndicator.js:248
#: extensions/workspace-indicator/extension.js:252
msgid "Workspace Indicator"
msgstr "Laborspaco Indikilo"
#: extensions/workspace-indicator/prefs.js:34
msgid "Workspace Names"
msgstr "Laborspacaj nomoj"
#: extensions/workspace-indicator/prefs.js:67
#: extensions/workspace-indicator/prefs.js:65
#, javascript-format
msgid "Workspace %d"
msgstr "Laborspaco %d"
#: extensions/workspace-indicator/prefs.js:208
#: extensions/workspace-indicator/prefs.js:132
msgid "Workspace Names"
msgstr "Laborspacaj nomoj"
#: extensions/workspace-indicator/prefs.js:258
msgid "Add Workspace"
msgstr "Aldoni laborspacon"

383
po/nb.po
View File

@@ -6,178 +6,81 @@
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell-extensions 3.26.x\n"
"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-shell&keywords=I18N+L10N&component=extensions\n"
"POT-Creation-Date: 2017-10-04 18:03+0000\n"
"PO-Revision-Date: 2017-11-06 13:40+0100\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/"
"issues\n"
"POT-Creation-Date: 2023-08-05 15:58+0000\n"
"PO-Revision-Date: 2023-10-12 22:27+0200\n"
"Last-Translator: Brage <bragefuglseth@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: nb\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.4\n"
"X-Generator: Poedit 3.4\n"
#: data/gnome-classic.desktop.in:3 data/gnome-classic.session.desktop.in:3
#: data/gnome-classic.desktop.in:3
msgid "GNOME Classic"
msgstr "Klassisk GNOME"
#: data/gnome-classic.desktop.in:4
#: data/gnome-classic.desktop.in:4 data/gnome-classic-wayland.desktop.in:4
#: data/gnome-classic-xorg.desktop.in:4
msgid "This session logs you into GNOME Classic"
msgstr "Denne økten logger inn i klassisk GNOME"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:7
msgid "Attach modal dialog to the parent window"
msgstr "Fest modal dialog til opphavsvindu"
#: data/gnome-classic-wayland.desktop.in:3
msgid "GNOME Classic on Wayland"
msgstr "Klassisk GNOME med Wayland"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:8
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:25
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:33
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:41
msgid ""
"This key overrides the key in org.gnome.mutter when running GNOME Shell."
msgstr ""
"Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell kjører."
#: data/gnome-classic-xorg.desktop.in:3
msgid "GNOME Classic on Xorg"
msgstr "Klassisk GNOME med Xorg"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:16
msgid "Arrangement of buttons on the titlebar"
msgstr "Plassering av knapper på tittellinjen"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:17
msgid ""
"This key overrides the key in org.gnome.desktop.wm.preferences when running "
"GNOME Shell."
msgstr ""
"Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når "
"GNOME Shell kjører."
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:24
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
"Del opp skjermkantene i fliser når brukeren drar og slipper vinduer på dem"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:32
msgid "Workspaces only on primary monitor"
msgstr "Arbeidsområder kun på hovedskjerm"
#: data/org.gnome.shell.extensions.classic-overrides.gschema.xml:40
msgid "Delay focus changes in mouse mode until the pointer stops moving"
msgstr "Vent med å endre fokus i mus-modus til pekeren holdes i ro"
#: extensions/alternate-tab/prefs.js:20
msgid "Thumbnail only"
msgstr "Kun miniatyr"
#: extensions/alternate-tab/prefs.js:21
msgid "Application icon only"
msgstr "Kun programikon"
#: extensions/alternate-tab/prefs.js:22
msgid "Thumbnail and application icon"
msgstr "Miniatyr og programikon"
#: extensions/alternate-tab/prefs.js:38
msgid "Present windows as"
msgstr "Vis vinduer som"
#: extensions/alternate-tab/prefs.js:69
msgid "Show only windows in the current workspace"
msgstr "Vis kun vinduer i aktivt arbeidsområde"
#: extensions/apps-menu/extension.js:41
msgid "Activities Overview"
msgstr "Aktivitetsoversikt"
#: extensions/apps-menu/extension.js:141
#: extensions/apps-menu/extension.js:121
msgid "Favorites"
msgstr "Favoritter"
#: extensions/apps-menu/extension.js:436
#: extensions/apps-menu/extension.js:378
msgid "Applications"
msgstr "Programmer"
msgstr "Apper"
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:6
msgid "Application and workspace list"
msgstr "Liste med programmer og arbeidsområder"
msgstr "Liste over apper og områder"
#: extensions/auto-move-windows/org.gnome.shell.extensions.auto-move-windows.gschema.xml:7
msgid ""
"A list of strings, each containing an application id (desktop file name), "
"followed by a colon and the workspace number"
msgstr ""
"En liste med strenger som inneholder en ID for et program (navn på .desktop-"
"fil), fulgt av et kolon og arbeidsområdenummeret"
"En liste hvor hvert element inneholder en app-ID (navn på skrivebordsfil), "
"fulgt av et kolon og et områdenummer"
#: extensions/auto-move-windows/prefs.js:60
msgid "Application"
msgstr "Program"
#: extensions/auto-move-windows/prefs.js:155
msgid "Workspace Rules"
msgstr "Områderegler"
#: extensions/auto-move-windows/prefs.js:69
#: extensions/auto-move-windows/prefs.js:127
msgid "Workspace"
msgstr "Arbeidsområde"
#: extensions/auto-move-windows/prefs.js:85
#: extensions/auto-move-windows/prefs.js:309
msgid "Add Rule"
msgstr "Legg til regel"
#: extensions/auto-move-windows/prefs.js:106
msgid "Create new matching rule"
msgstr "Lag en ny regel for treff"
#: extensions/auto-move-windows/prefs.js:111
msgid "Add"
msgstr "Legg til"
#. TRANSLATORS: %s is the filesystem name
#: extensions/drive-menu/extension.js:107
#: extensions/drive-menu/extension.js:122
#: extensions/places-menu/placeDisplay.js:213
#, javascript-format
msgid "Ejecting drive “%s” failed:"
msgstr "Utløsing av stasjon «%s» feilet:"
msgstr "Løsning av lagringsenheten %s” mislyktes:"
#: extensions/drive-menu/extension.js:125
#: extensions/drive-menu/extension.js:141
msgid "Removable devices"
msgstr "Avtagbare enheter"
msgstr "Flyttbare enheter"
#: extensions/drive-menu/extension.js:150
#: extensions/drive-menu/extension.js:163
msgid "Open Files"
msgstr "Åpne fil"
#: extensions/example/extension.js:17
msgid "Hello, world!"
msgstr "Hallo verden!"
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:5
msgid "Alternative greeting text."
msgstr "Alternativ velkomsttekst."
#: extensions/example/org.gnome.shell.extensions.example.gschema.xml:6
msgid ""
"If not empty, it contains the text that will be shown when clicking on the "
"panel."
msgstr ""
"Hvis denne ikke er tom, inneholder den tekst som vises når brukeren klikker "
"på panelet."
#: extensions/example/prefs.js:30
msgid "Message"
msgstr "Melding"
#. TRANSLATORS: Example is the name of the extension, should not be
#. translated
#: extensions/example/prefs.js:43
msgid ""
"Example aims to show how to build well behaved extensions for the Shell and "
"as such it has little functionality on its own.\n"
"Nevertheless its possible to customize the greeting message."
msgstr ""
"Example har som hensikt å vise hvordan du kan bygge godt fungerende "
"utvidelser til Gnome-skallet, og byr dermed på lite funksjonalitet i seg "
"selv.\n"
"Hvis du likevel har lyst, kan du tilpasse velkomstmeldingen."
msgstr "Åpne filer"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:5
msgid "Use more screen for windows"
msgstr "Bruk mer skjerm til vinduer"
msgstr "Bruk mer av skjermen til vinduer"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:6
msgid ""
@@ -185,14 +88,14 @@ msgid ""
"aspect ratio, and consolidating them further to reduce the bounding box. "
"This setting applies only with the natural placement strategy."
msgstr ""
"Prøv å bruke mer skjermplass for å plassere miniatyrvinduer ved å tilpasse "
"dem til skjermens høyde- og breddeforhold, og slå dem sammen ytterligere for "
"å redusere avgrensingsboksen. Denne innstillinga gjelder bare med naturlig "
"plassering-strategien."
"Prøv å bruke mer av skjermen til miniatyrvinduer ved å tilpasse dem til "
"skjermens høyde- og breddeforhold, og ved å samle dem tettere sammen for å "
"redusere tomrom. Denne innstillingen virker bare når naturlig plassering er "
"i bruk."
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:11
msgid "Place window captions on top"
msgstr "Plasser vindutekster i toppen"
msgstr "Plasser vindustekster i toppen"
#: extensions/native-window-placement/org.gnome.shell.extensions.native-window-placement.gschema.xml:12
msgid ""
@@ -200,103 +103,97 @@ msgid ""
"shell default of placing it at the bottom. Changing this setting requires "
"restarting the shell to have any effect."
msgstr ""
"Hvis verdien av denne er «true» (sann), plasseres vindutekster i toppen av "
"gjeldende miniatyr og overstyrer skallets standard bunnplassering. Hvis du "
"endrer denne innstillinga, må du starte skallet på nytt for at den skal tre "
"i kraft."
"Hvis denne innstillingen er slått på, plasseres vindustekster toppen av "
"sine respektive miniatyrbilder i stedet for på bunnen. For at denne "
"innstillingen skal tre i kraft, må GNOME Shell startes på nytt."
#: extensions/places-menu/extension.js:78
#: extensions/places-menu/extension.js:81
#: extensions/places-menu/extension.js:85
#: extensions/places-menu/extension.js:88
msgid "Places"
msgstr "Steder"
#: extensions/places-menu/placeDisplay.js:65
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "Klarte ikke å montere volum for «%s»"
#: extensions/places-menu/placeDisplay.js:78
#: extensions/places-menu/placeDisplay.js:53
#, javascript-format
msgid "Failed to launch “%s”"
msgstr "Klarte ikke å starte «%s»"
msgstr "Oppstart av “%s” mislyktes"
#: extensions/places-menu/placeDisplay.js:137
#: extensions/places-menu/placeDisplay.js:160
#: extensions/places-menu/placeDisplay.js:68
#, javascript-format
msgid "Failed to mount volume for “%s”"
msgstr "Klarte ikke å montere dataområde for “%s”"
#: extensions/places-menu/placeDisplay.js:128
#: extensions/places-menu/placeDisplay.js:151
msgid "Computer"
msgstr "Datamaskin"
#: extensions/places-menu/placeDisplay.js:303
#: extensions/places-menu/placeDisplay.js:328
msgid "Home"
msgstr "Hjem"
#: extensions/places-menu/placeDisplay.js:347
#: extensions/places-menu/placeDisplay.js:373
msgid "Browse Network"
msgstr "Bla gjennom nettverk"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:7
msgid "Cycle Screenshot Sizes"
msgstr "Bla gjennom størrelser på skjermdump"
msgstr "Bla gjennom skjermbildestørrelser"
#: extensions/screenshot-window-sizer/org.gnome.shell.extensions.screenshot-window-sizer.gschema.xml:11
msgid "Cycle Screenshot Sizes Backward"
msgstr "Bla gjennom størrelser på skjermdump baklengs"
msgstr "Bla gjennom skjermbildestørrelser baklengs"
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:5
msgid "Theme name"
msgstr "Navn på tema"
msgstr "Stilnavn"
#: extensions/user-theme/org.gnome.shell.extensions.user-theme.gschema.xml:6
msgid "The name of the theme, to be loaded from ~/.themes/name/gnome-shell"
msgstr "Navn på tema som skal lastes fra ~/.themes/name/gnome-shell"
msgstr "Navn på stil, som vil bli lastet fra ~/.themes/{navn}/gnome-shell"
#: extensions/window-list/extension.js:110
#: extensions/window-list/extension.js:71
msgid "Close"
msgstr "Lukk"
#: extensions/window-list/extension.js:129
#: extensions/window-list/extension.js:98
msgid "Unminimize"
msgstr "Gjenopprett"
#: extensions/window-list/extension.js:130
#: extensions/window-list/extension.js:98
msgid "Minimize"
msgstr "Minimer"
#: extensions/window-list/extension.js:136
#: extensions/window-list/extension.js:105
msgid "Unmaximize"
msgstr "Gjenopprett"
msgstr "Demaksimer"
#: extensions/window-list/extension.js:137
#: extensions/window-list/extension.js:105
msgid "Maximize"
msgstr "Maksimer"
#: extensions/window-list/extension.js:420
#: extensions/window-list/extension.js:468
msgid "Minimize all"
msgstr "Minimer alle"
#: extensions/window-list/extension.js:428
#: extensions/window-list/extension.js:474
msgid "Unminimize all"
msgstr "Gjenopprett alle"
#: extensions/window-list/extension.js:436
#: extensions/window-list/extension.js:480
msgid "Maximize all"
msgstr "Maksimer alle"
#: extensions/window-list/extension.js:445
#: extensions/window-list/extension.js:488
msgid "Unmaximize all"
msgstr "Gjenopprett alle"
msgstr "Demaksimer alle"
#: extensions/window-list/extension.js:454
#: extensions/window-list/extension.js:496
msgid "Close all"
msgstr "Lukk alle"
#: extensions/window-list/extension.js:678
#: extensions/workspace-indicator/extension.js:30
msgid "Workspace Indicator"
msgstr "Arbeidsområdeindikator"
#: extensions/window-list/extension.js:842
#: extensions/window-list/extension.js:776
msgid "Window List"
msgstr "Vinduliste"
msgstr "Vindusliste"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:12
msgid "When to group windows"
@@ -307,50 +204,146 @@ msgid ""
"Decides when to group windows from the same application on the window list. "
"Possible values are “never”, “auto” and “always”."
msgstr ""
"Avgjør når vinduer fra samme program skal grupperes i vindulista. Mulige "
"verdier er «never» (aldri), «auto» og «always» (alltid)."
"Avgjør når vinduer som tilhører samme app skal grupperes i vindulista. "
"Mulige verdier er never (aldri), auto og always (alltid)."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:20
msgid "Show the window list on all monitors"
msgstr "Vis vindulisten på alle skjermer"
#: extensions/window-list/prefs.js:76
msgid "Show windows from all workspaces"
msgstr "Vis vinduer fra alle områder"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:21
msgid "Whether to show windows from all workspaces or only the current one."
msgstr "Om det skal vises vinduer fra alle områder eller bare det nåværende."
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:27
msgid "Show the window list on all monitors"
msgstr "Vis vinduslisten på alle skjermer"
#: extensions/window-list/org.gnome.shell.extensions.window-list.gschema.xml:28
msgid ""
"Whether to show the window list on all connected monitors or only on the "
"primary one."
msgstr ""
"Hvorvidt vindulisten skal vises på alle tilkoblede skjermer eller bare "
"primærskjerm."
"Om vinduslisten skal vises på alle tilkoblede skjermer eller bare "
"hovedskjermen."
#: extensions/window-list/prefs.js:32
msgid "Window Grouping"
msgstr "Gruppering av vinduer"
msgstr "Vindusgruppering"
#: extensions/window-list/prefs.js:50
#: extensions/window-list/prefs.js:37
msgid "Never group windows"
msgstr "Aldri grupper vinduer"
#: extensions/window-list/prefs.js:51
#: extensions/window-list/prefs.js:38
msgid "Group windows when space is limited"
msgstr "Grupper vinduer når det er begrenset med plass"
#: extensions/window-list/prefs.js:52
#: extensions/window-list/prefs.js:39
msgid "Always group windows"
msgstr "Alltid grupper vinduer"
#: extensions/window-list/prefs.js:75
#: extensions/window-list/prefs.js:63
msgid "Show on all monitors"
msgstr "Vis på alle skjermer"
#: extensions/workspace-indicator/prefs.js:141
msgid "Workspace Names"
msgstr "Navn på arbeidsområder"
#: extensions/window-list/workspaceIndicator.js:248
#: extensions/workspace-indicator/extension.js:252
msgid "Workspace Indicator"
msgstr "Områdeindikator"
#: extensions/workspace-indicator/prefs.js:157
msgid "Name"
msgstr "Navn"
#: extensions/workspace-indicator/prefs.js:198
#: extensions/workspace-indicator/prefs.js:65
#, javascript-format
msgid "Workspace %d"
msgstr "Arbeidsområde %d"
msgstr "Område %d"
#: extensions/workspace-indicator/prefs.js:132
msgid "Workspace Names"
msgstr "Områdenavn"
#: extensions/workspace-indicator/prefs.js:258
msgid "Add Workspace"
msgstr "Legg til område"
#~ msgid "Attach modal dialog to the parent window"
#~ msgstr "Fest modal dialog til opphavsvindu"
#~ msgid ""
#~ "This key overrides the key in org.gnome.mutter when running GNOME Shell."
#~ msgstr ""
#~ "Denne nøkkelen overstyrer nøkkelen i org.gnome.mutter når GNOME Shell "
#~ "kjører."
#~ msgid "Arrangement of buttons on the titlebar"
#~ msgstr "Plassering av knapper på tittellinjen"
#~ msgid ""
#~ "This key overrides the key in org.gnome.desktop.wm.preferences when "
#~ "running GNOME Shell."
#~ msgstr ""
#~ "Denne nøkkelen overstyrer nøkkelen i org.gnome.desktop.wm.preferences når "
#~ "GNOME Shell kjører."
#~ msgid "Enable edge tiling when dropping windows on screen edges"
#~ msgstr ""
#~ "Del opp skjermkantene i fliser når brukeren drar og slipper vinduer på dem"
#~ msgid "Workspaces only on primary monitor"
#~ msgstr "Arbeidsområder kun på hovedskjerm"
#~ msgid "Delay focus changes in mouse mode until the pointer stops moving"
#~ msgstr "Vent med å endre fokus i mus-modus til pekeren holdes i ro"
#~ msgid "Thumbnail only"
#~ msgstr "Kun miniatyr"
#~ msgid "Application icon only"
#~ msgstr "Kun programikon"
#~ msgid "Thumbnail and application icon"
#~ msgstr "Miniatyr og programikon"
#~ msgid "Present windows as"
#~ msgstr "Vis vinduer som"
#~ msgid "Activities Overview"
#~ msgstr "Aktivitetsoversikt"
#~ msgid "Application"
#~ msgstr "Program"
#~ msgid "Create new matching rule"
#~ msgstr "Lag en ny regel for treff"
#~ msgid "Add"
#~ msgstr "Legg til"
#~ msgid "Hello, world!"
#~ msgstr "Hallo verden!"
#~ msgid "Alternative greeting text."
#~ msgstr "Alternativ velkomsttekst."
#~ msgid ""
#~ "If not empty, it contains the text that will be shown when clicking on "
#~ "the panel."
#~ msgstr ""
#~ "Hvis denne ikke er tom, inneholder den tekst som vises når brukeren "
#~ "klikker på panelet."
#~ msgid "Message"
#~ msgstr "Melding"
#~ msgid ""
#~ "Example aims to show how to build well behaved extensions for the Shell "
#~ "and as such it has little functionality on its own.\n"
#~ "Nevertheless its possible to customize the greeting message."
#~ msgstr ""
#~ "Example har som hensikt å vise hvordan du kan bygge godt fungerende "
#~ "utvidelser til Gnome-skallet, og byr dermed på lite funksjonalitet i seg "
#~ "selv.\n"
#~ "Hvis du likevel har lyst, kan du tilpasse velkomstmeldingen."
#~ msgid "Name"
#~ msgstr "Navn"