Attempt to add cursor rendering
This commit is contained in:
parent
a109b5e897
commit
fe828db999
|
|
@ -0,0 +1,68 @@
|
|||
// Taken from https://github.com/jkitching/soft-brightness-plus
|
||||
//
|
||||
// Copyright (C) 2023 Joel Kitching (jkitching on Github)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
|
||||
// Copied almost verbatim from ui/magnifier.js.
|
||||
export const MouseSpriteContent = GObject.registerClass({
|
||||
Implements: [Clutter.Content],
|
||||
}, class MouseSpriteContent extends GObject.Object {
|
||||
_init() {
|
||||
super._init();
|
||||
this._texture = null;
|
||||
}
|
||||
|
||||
vfunc_get_preferred_size() {
|
||||
if (!this._texture)
|
||||
return [false, 0, 0];
|
||||
|
||||
return [true, this._texture.get_width(), this._texture.get_height()];
|
||||
}
|
||||
|
||||
vfunc_paint_content(actor, node, _paintContext) {
|
||||
if (!this._texture)
|
||||
return;
|
||||
|
||||
let color = Clutter.Color.from_string('#ffffff'); // white
|
||||
let [minFilter, magFilter] = actor.get_content_scaling_filters();
|
||||
let textureNode = new Clutter.TextureNode(this._texture,
|
||||
color, minFilter, magFilter);
|
||||
textureNode.set_name('SoftBrightnessPlusMouseSpriteContent');
|
||||
node.add_child(textureNode);
|
||||
|
||||
textureNode.add_rectangle(actor.get_content_box());
|
||||
}
|
||||
|
||||
get texture() {
|
||||
return this._texture;
|
||||
}
|
||||
|
||||
set texture(coglTexture) {
|
||||
if (this._texture === coglTexture)
|
||||
return;
|
||||
|
||||
let oldTexture = this._texture;
|
||||
this._texture = coglTexture;
|
||||
this.invalidate();
|
||||
|
||||
if (!oldTexture || !coglTexture ||
|
||||
oldTexture.get_width() !== coglTexture.get_width() ||
|
||||
oldTexture.get_height() !== coglTexture.get_height())
|
||||
this.invalidate_size();
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
|
||||
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import Meta from 'gi://Meta';
|
||||
import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js';
|
||||
import { MouseSpriteContent } from './cursor.js';
|
||||
|
||||
// Taken from https://github.com/jkitching/soft-brightness-plus
|
||||
export class CursorManager {
|
||||
constructor(logger, settings, mainActor) {
|
||||
this._logger = logger;
|
||||
this._settings = settings;
|
||||
this._mainActor = mainActor;
|
||||
|
||||
this._enableTimeoutId = null;
|
||||
this._changeHookFn = null;
|
||||
|
||||
this._cloneMouseSetting = null;
|
||||
this._cloneMouseSettingChangedConnection = null;
|
||||
|
||||
// Set/destroyed by _enableCloningMouse/_disableCloningMouse
|
||||
this._cursorWantedVisible = null;
|
||||
this._cursorTracker = null;
|
||||
this._cursorTrackerSetPointerVisible = null;
|
||||
this._cursorTrackerSetPointerVisibleBound = null;
|
||||
this._cursorSprite = null;
|
||||
this._cursorActor = null;
|
||||
this._cursorWatcher = null;
|
||||
this._cursorSeat = null;
|
||||
// Set/destroyed by _startCloningMouse / _stopCloningMouse
|
||||
this._cursorWatch = null;
|
||||
this._cursorChangedConnection = null;
|
||||
this._cursorVisibilityChangedConnection = null;
|
||||
// Set/destroyed by _delayedSetPointerInvisible/_clearDelayedSetPointerInvibleCallbacks
|
||||
this._delayedSetPointerInvisibleIdleSource = null;
|
||||
}
|
||||
|
||||
setChangeHook(fn) {
|
||||
this._changeHookFn = fn;
|
||||
}
|
||||
|
||||
enable() {
|
||||
// First 500ms: For some reason, starting the mouse cloning at this
|
||||
// stage fails when gnome-shell is restarting on x11 and the mouse
|
||||
// listener doesn't receive any events. Adding a small delay before
|
||||
// starting the whole mouse cloning business helps.
|
||||
this._enableTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 500, () => {
|
||||
// Wait 500ms before starting to check for the _brightness object.
|
||||
this._enableTimeoutId = null;
|
||||
this._enable();
|
||||
// Ensure proper stacking order for cursor and overlay.
|
||||
if (this._changeHookFn !== null) {
|
||||
this._changeHookFn();
|
||||
}
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
_enable() {
|
||||
this._cloneMouseSetting = true; // this._settings.get_boolean('clone-mouse');
|
||||
this._enableCloningMouse();
|
||||
// this._cloneMouseSettingChangedConnection = this._settings.connect('changed::clone-mouse', this._on_clone_mouse_change.bind(this));
|
||||
}
|
||||
|
||||
disable() {
|
||||
// If _enableTimeoutId is non-null, _enable() has not run yet, and will
|
||||
// not run. Do not run _disable() in this case.
|
||||
GLib.source_remove(this._enableTimeoutId);
|
||||
if (this._enableTimeoutId !== null) {
|
||||
return;
|
||||
}
|
||||
this._enableTimeoutId = null;
|
||||
this._changeHookFn = null;
|
||||
|
||||
// this._settings.disconnect(this._cloneMouseSettingChangedConnection);
|
||||
// this._cloneMouseSettingChangedConnection = null;
|
||||
this._disableCloningMouse();
|
||||
this._cloneMouseSetting = null;
|
||||
|
||||
// Set/destroyed by _enableCloningMouse/_disableCloningMouse
|
||||
this._cursorWantedVisible = null;
|
||||
this._cursorTracker = null;
|
||||
this._cursorTrackerSetPointerVisible = null;
|
||||
this._cursorTrackerSetPointerVisibleBound = null;
|
||||
this._cursorSprite = null;
|
||||
this._cursorActor = null;
|
||||
this._cursorWatcher = null;
|
||||
this._cursorSeat = null;
|
||||
// Set/destroyed by _startCloningMouse / _stopCloningMouse
|
||||
this._cursorWatch = null;
|
||||
this._cursorChangedConnection = null;
|
||||
this._cursorVisibilityChangedConnection = null;
|
||||
// Set/destroyed by _delayedSetPointerInvisible/_clearDelayedSetPointerInvibleCallbacks
|
||||
this._delayedSetPointerInvisibleIdleSource = null;
|
||||
}
|
||||
|
||||
startCloning() {
|
||||
if (this._cursorWantedVisible) {
|
||||
this._startCloningMouse();
|
||||
}
|
||||
}
|
||||
|
||||
stopCloning() {
|
||||
this._stopCloningShowMouse();
|
||||
}
|
||||
|
||||
hidePointer() {
|
||||
this._setPointerVisible(false);
|
||||
}
|
||||
|
||||
_isMouseClonable() {
|
||||
return this._cloneMouseSetting;
|
||||
}
|
||||
|
||||
_on_clone_mouse_change() {
|
||||
const cloneMouse = true; // this._settings.get_boolean('clone-mouse');
|
||||
if (cloneMouse == this._cloneMouseSetting) {
|
||||
this._logger.log_debug('_on_clone_mouse_change(): no setting change, no change');
|
||||
return;
|
||||
}
|
||||
if (cloneMouse) {
|
||||
// Starting to clone mouse
|
||||
this._logger.log_debug('_on_clone_mouse_change(): starting mouse cloning');
|
||||
this._cloneMouseSetting = true;
|
||||
this._enableCloningMouse();
|
||||
if (this._changeHookFn !== null) {
|
||||
this._changeHookFn();
|
||||
}
|
||||
} else {
|
||||
this._logger.log_debug('_on_clone_mouse_change(): stopping mouse cloning');
|
||||
this._disableCloningMouse();
|
||||
this._cloneMouseSetting = false;
|
||||
}
|
||||
}
|
||||
|
||||
_enableCloningMouse() {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
this._logger.log_debug('_enableCloningMouse()');
|
||||
|
||||
this._cursorWantedVisible = true;
|
||||
this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
|
||||
this._cursorTrackerSetPointerVisible = Meta.CursorTracker.prototype.set_pointer_visible;
|
||||
this._cursorTrackerSetPointerVisibleBound = this._cursorTrackerSetPointerVisible.bind(this._cursorTracker);
|
||||
Meta.CursorTracker.prototype.set_pointer_visible = this._cursorTrackerSetPointerVisibleReplacement.bind(this);
|
||||
|
||||
this._cursorSprite = new Clutter.Actor({ request_mode: Clutter.RequestMode.CONTENT_SIZE });
|
||||
this._cursorSprite.content = new MouseSpriteContent();
|
||||
|
||||
this._cursorActor = new Clutter.Actor();
|
||||
this._cursorActor.add_actor(this._cursorSprite);
|
||||
this._cursorWatcher = PointerWatcher.getPointerWatcher();
|
||||
this._cursorSeat = Clutter.get_default_backend().get_default_seat();
|
||||
}
|
||||
|
||||
_disableCloningMouse() {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
this._stopCloningShowMouse();
|
||||
this._logger.log_debug('_disableCloningMouse()');
|
||||
|
||||
Meta.CursorTracker.prototype.set_pointer_visible = this._cursorTrackerSetPointerVisible;
|
||||
|
||||
this._cursorWantedVisible = null;
|
||||
this._cursorTracker = null;
|
||||
this._cursorTrackerSetPointerVisible = null;
|
||||
this._cursorTrackerSetPointerVisibleBound = null;
|
||||
this._cursorSprite = null;
|
||||
this._cursorActor = null;
|
||||
this._cursorWatcher = null;
|
||||
this._cursorSeat = null;
|
||||
}
|
||||
|
||||
_setPointerVisible(visible) {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
this._cursorTrackerSetPointerVisibleBound(visible);
|
||||
}
|
||||
|
||||
_cursorTrackerSetPointerVisibleReplacement(visible) {
|
||||
if (visible) {
|
||||
this._startCloningMouse();
|
||||
// For some reason, exiting the magnifier causes the
|
||||
// stacking order for the cursor and overlay actors to be
|
||||
// swapped around. Reassert stacking order whenever the
|
||||
// pointer should become visible again.
|
||||
if (this._changeHookFn !== null) {
|
||||
this._changeHookFn();
|
||||
}
|
||||
} else {
|
||||
this._stopCloningMouse();
|
||||
this._setPointerVisible(false);
|
||||
}
|
||||
this._cursorWantedVisible = visible;
|
||||
}
|
||||
|
||||
_startCloningMouse() {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
this._logger.log_debug('_startCloningMouse()');
|
||||
if (this._cursorWatch == null) {
|
||||
this._mainActor.add_actor(this._cursorActor);
|
||||
this._cursorChangedConnection = this._cursorTracker.connect('cursor-changed', this._updateMouseSprite.bind(this));
|
||||
this._cursorVisibilityChangedConnection = this._cursorTracker.connect('visibility-changed', this._updateMouseSprite.bind(this));
|
||||
const interval = 1000 / 60;
|
||||
this._logger.log_debug('_startCloningMouse(): watch interval = ' + interval + ' ms');
|
||||
this._cursorWatch = this._cursorWatcher.addWatch(interval, this._updateMousePosition.bind(this));
|
||||
|
||||
this._updateMouseSprite();
|
||||
this._updateMousePosition();
|
||||
}
|
||||
this._setPointerVisible(false);
|
||||
|
||||
if (this._cursorTracker.set_keep_focus_while_hidden) {
|
||||
this._cursorTracker.set_keep_focus_while_hidden(true);
|
||||
}
|
||||
|
||||
if (!this._cursorSeat.is_unfocus_inhibited()) {
|
||||
this._cursorSeat.inhibit_unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
_stopCloningShowMouse() {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
this._logger.log_debug('_stopCloningShowMouse(), restoring cursor visibility to ' + this._cursorWantedVisible);
|
||||
this._stopCloningMouse();
|
||||
this._setPointerVisible(this._cursorWantedVisible);
|
||||
|
||||
if (this._cursorTracker.set_keep_focus_while_hidden) {
|
||||
this._cursorTracker.set_keep_focus_while_hidden(false);
|
||||
}
|
||||
|
||||
if (this._cursorSeat.is_unfocus_inhibited()) {
|
||||
this._cursorSeat.uninhibit_unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
_stopCloningMouse() {
|
||||
if (!this._isMouseClonable()) {
|
||||
return;
|
||||
}
|
||||
if (this._cursorWatch != null) {
|
||||
this._logger.log_debug('_stopCloningMouse()');
|
||||
|
||||
this._cursorWatch.remove();
|
||||
this._cursorWatch = null;
|
||||
|
||||
this._cursorTracker.disconnect(this._cursorChangedConnection);
|
||||
this._cursorChangedConnection = null;
|
||||
|
||||
this._cursorTracker.disconnect(this._cursorVisibilityChangedConnection);
|
||||
this._cursorVisibilityChangedConnection = null;
|
||||
|
||||
this._mainActor.remove_actor(this._cursorActor);
|
||||
}
|
||||
|
||||
this._clearDelayedSetPointerInvibleCallbacks();
|
||||
}
|
||||
|
||||
_updateMousePosition(actor, event) {
|
||||
const [x, y, mask] = global.get_pointer();
|
||||
this._cursorActor.set_position(x, y);
|
||||
this._delayedSetPointerInvisible();
|
||||
}
|
||||
|
||||
_updateMouseSprite() {
|
||||
const sprite = this._cursorTracker.get_sprite();
|
||||
if (sprite) {
|
||||
this._cursorSprite.content.texture = sprite;
|
||||
this._cursorSprite.show();
|
||||
} else {
|
||||
this._cursorSprite.hide();
|
||||
}
|
||||
|
||||
const [xHot, yHot] = this._cursorTracker.get_hot();
|
||||
this._cursorSprite.set({
|
||||
translation_x: -xHot,
|
||||
translation_y: -yHot,
|
||||
});
|
||||
this._delayedSetPointerInvisible();
|
||||
}
|
||||
|
||||
_delayedSetPointerInvisible() {
|
||||
this._setPointerVisible(false);
|
||||
|
||||
// Clear the pointer upon entering idle loop
|
||||
if (this._delayedSetPointerInvisibleIdleSource == null) {
|
||||
this._delayedSetPointerInvisibleIdleSource = GLib.idle_add(
|
||||
GLib.PRIORITY_DEFAULT,
|
||||
() => {
|
||||
this._setPointerVisible(false);
|
||||
this._delayedSetPointerInvisibleIdleSource = null;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_clearDelayedSetPointerInvibleCallbacks() {
|
||||
if (this._delayedSetPointerInvisibleIdleSource != null) {
|
||||
GLib.source_remove(this._delayedSetPointerInvisibleIdleSource);
|
||||
this._delayedSetPointerInvisibleIdleSource = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,12 @@ import GObject from 'gi://GObject';
|
|||
import Shell from 'gi://Shell';
|
||||
import Meta from 'gi://Meta';
|
||||
|
||||
import ExtensionUtils from 'gi://ExtensionUtils';
|
||||
import Main from 'gi://Main';
|
||||
import PanelMenu from 'gi://PanelMenu';
|
||||
import * as Config from 'resource:///org/gnome/shell/misc/config.js';
|
||||
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
|
||||
import * as Logger from './logger.js';
|
||||
import { CursorManager } from './cursormanager.js';
|
||||
|
||||
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||
|
||||
const UINT8_SIZE = 1;
|
||||
const BOOL_SIZE = UINT8_SIZE;
|
||||
|
|
@ -195,12 +198,32 @@ function setIntermittentUniformVariables() {
|
|||
}
|
||||
|
||||
|
||||
export default class ExampleExtension extends Extension {
|
||||
export default class BreezyDesktopExtension extends Extension {
|
||||
constructor(metadata, uuid) {
|
||||
super(metadata, uuid);
|
||||
this._extensionPath = metadata.path;
|
||||
|
||||
// Set/destroyed by enable/disable
|
||||
this._settings = null;
|
||||
this._logger = null;
|
||||
this._cursorManager = null;
|
||||
this._removeSettingsCallbacks = [];
|
||||
}
|
||||
|
||||
enable() {
|
||||
// this._settings = this.getSettings();
|
||||
this._logger = new Logger.Logger('soft-brightness-plus', this.metadata, Config.PACKAGE_VERSION);
|
||||
// this._logger.set_debug(this._settings.get_boolean('debug'));
|
||||
this._logger.log_debug('enable(), session mode = ' + Main.sessionMode.currentMode);
|
||||
this._logger.logVersion();
|
||||
|
||||
this._cursorManager = new CursorManager(this._logger, this._settings, global.stage);
|
||||
this._cursorManager.enable();
|
||||
|
||||
const extensionPath = this._extensionPath;
|
||||
var XREffect = GObject.registerClass({}, class XREffect extends Shell.GLSLEffect {
|
||||
vfunc_build_pipeline() {
|
||||
const shaderPath = GLib.getenv('BREEZY_GNOME_SHADER_PATH');
|
||||
const code = getShaderSource(shaderPath);
|
||||
const code = getShaderSource(`${extensionPath}/IMUAdjust.frag`);
|
||||
const main = 'PS_IMU_Transform(vec4(0, 0, 0, 0), cogl_tex_coord_in[0].xy, cogl_color_out);';
|
||||
this.add_glsl_snippet(Shell.SnippetHook.FRAGMENT, code, main, false);
|
||||
|
||||
|
|
@ -216,7 +239,6 @@ export default class ExampleExtension extends Extension {
|
|||
if (data[0]) {
|
||||
const buffer = new Uint8Array(data[1]).buffer;
|
||||
this._dataView = new DataView(buffer);
|
||||
var repaintNeeded = false;
|
||||
if (!this._initialized) {
|
||||
this.set_uniform_float(this.get_uniform_location('uDesktopTexture'), 1, [0]);
|
||||
|
||||
|
|
@ -227,8 +249,9 @@ export default class ExampleExtension extends Extension {
|
|||
this.setIntermittentUniformVariables = setIntermittentUniformVariables.bind(this);
|
||||
this.setIntermittentUniformVariables();
|
||||
|
||||
this._repaint_needed = false;
|
||||
GLib.timeout_add(GLib.PRIORITY_DEFAULT, this._frametime, () => {
|
||||
repaintNeeded = true;
|
||||
this._repaint_needed = true;
|
||||
this.queue_repaint();
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
});
|
||||
|
|
@ -243,9 +266,10 @@ export default class ExampleExtension extends Extension {
|
|||
|
||||
setUniformMatrix(this, 'imu_quat_data', 4, this._dataView, IMU_QUAT_DATA);
|
||||
|
||||
// if (repaintNeeded) {
|
||||
if (this._repaint_needed) {
|
||||
super.vfunc_paint_target(node, paintContext);
|
||||
// }
|
||||
this._repaint_needed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -254,6 +278,9 @@ export default class ExampleExtension extends Extension {
|
|||
}
|
||||
|
||||
disable() {
|
||||
this._logger.log_debug('disable(), session mode = ' + Main.sessionMode.currentMode);
|
||||
this._cursorManager.disable();
|
||||
this._cursorManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
// Taken from https://github.com/jkitching/soft-brightness-plus
|
||||
//
|
||||
// Copyright (C) 2023 Joel Kitching (jkitching on Github)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import * as Config from 'resource:///org/gnome/shell/misc/config.js';
|
||||
import GLib from 'gi://GLib';
|
||||
import System from 'system';
|
||||
|
||||
export class Logger {
|
||||
constructor(title, metadata, packageVersion) {
|
||||
this._title = title;
|
||||
this._metadata = metadata;
|
||||
this._packageVersion = packageVersion;
|
||||
|
||||
this._first_log = true;
|
||||
this._debug = false;
|
||||
}
|
||||
|
||||
get_version() {
|
||||
return this._metadata['version'] + ' / git ' + this._metadata['vcs_revision'];
|
||||
}
|
||||
|
||||
logVersion() {
|
||||
const gnomeShellVersion = Config.PACKAGE_VERSION;
|
||||
if (gnomeShellVersion != undefined) {
|
||||
const splitVersion = gnomeShellVersion.split('.').map((x) => {
|
||||
x = Number(x);
|
||||
if (Number.isNaN(x)) {
|
||||
return 0;
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
});
|
||||
const major = splitVersion[0];
|
||||
const minor = splitVersion.length >= 2 ? splitVersion[1] : 0;
|
||||
const patch = splitVersion.length >= 3 ? splitVersion[2] : 0;
|
||||
const xdgSessionType = GLib.getenv('XDG_SESSION_TYPE');
|
||||
const onWayland = xdgSessionType == 'wayland';
|
||||
this.log_debug('_logVersion(): gnome-shell version major=' + major + ', minor=' + minor + ', patch=' + patch + ', system_version=' + System.version + ', XDG_SESSION_TYPE=' + xdgSessionType);
|
||||
this.log_debug('_logVersion(): onWayland=' + onWayland);
|
||||
}
|
||||
}
|
||||
|
||||
log(text) {
|
||||
if (this._first_log) {
|
||||
this._first_log = false;
|
||||
let msg = 'version ' + this.get_version();
|
||||
const gnomeShellVersion = this._packageVersion;
|
||||
if (gnomeShellVersion != undefined) {
|
||||
msg += ' on Gnome-Shell ' + gnomeShellVersion;
|
||||
}
|
||||
const gjsVersion = System.version;
|
||||
if (gjsVersion != undefined) {
|
||||
const gjsVersionMajor = Math.floor(gjsVersion / 10000);
|
||||
const gjsVersionMinor = Math.floor((gjsVersion % 10000) / 100);
|
||||
const gjsVersionPatch = gjsVersion % 100;
|
||||
msg += (' / gjs ' + gjsVersionMajor +
|
||||
'.' + gjsVersionMinor +
|
||||
'.' + gjsVersionPatch +
|
||||
' (' + gjsVersion + ')'
|
||||
);
|
||||
}
|
||||
const sessionType = GLib.getenv('XDG_SESSION_TYPE');
|
||||
if (sessionType != undefined) {
|
||||
msg += ' / ' + sessionType;
|
||||
}
|
||||
this.log(msg);
|
||||
}
|
||||
console.log('' + this._title + ': ' + text);
|
||||
}
|
||||
|
||||
log_debug(text) {
|
||||
if (this._debug) {
|
||||
this.log(text);
|
||||
}
|
||||
}
|
||||
|
||||
set_debug(debug) {
|
||||
this._debug = debug;
|
||||
}
|
||||
|
||||
get_debug() {
|
||||
return this._debug;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"uuid": "breezydesktop@org.xronlinux",
|
||||
"name": "Breezy GNOME",
|
||||
"description": "XR virtual desktop for Linux.",
|
||||
"name": "Breezy GNOME XR Desktop",
|
||||
"description": "XR virtual desktop for GNOME.",
|
||||
"shell-version": [
|
||||
"45", "46"
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue