[gnome] Add auto rotate extensions
This commit is contained in:
@ -0,0 +1,172 @@
|
||||
/* busUtils.js
|
||||
*
|
||||
* Copyright (C) 2022 kosmospredanie, efosmark
|
||||
*
|
||||
* 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 GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
export const Methods = Object.freeze({
|
||||
'verify': 0,
|
||||
'temporary': 1,
|
||||
'persistent': 2
|
||||
});
|
||||
|
||||
export const Monitor = class Monitor {
|
||||
constructor(variant) {
|
||||
let unpacked = variant.unpack();
|
||||
this.connector = unpacked[0].unpack()[0].unpack();
|
||||
|
||||
let modes = unpacked[1].unpack();
|
||||
for (let i = 0; i < modes.length; i++) {
|
||||
let mode = modes[i].unpack();
|
||||
let id = mode[0].unpack();
|
||||
let mode_props = mode[6].unpack();
|
||||
if ('is-current' in mode_props) {
|
||||
let is_current = mode_props['is-current'].unpack().get_boolean();
|
||||
if (is_current) {
|
||||
this.current_mode_id = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let props = unpacked[2].unpack();
|
||||
if ('is-underscanning' in props) {
|
||||
this.is_underscanning = props['is-underscanning'].unpack().get_boolean();
|
||||
} else {
|
||||
this.is_underscanning = false;
|
||||
}
|
||||
if ('is-builtin' in props) {
|
||||
this.is_builtin = props['is-builtin'].unpack().get_boolean();
|
||||
} else {
|
||||
this.is_builtin = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const LogicalMonitor = class LogicalMonitor {
|
||||
constructor(variant) {
|
||||
let unpacked = variant.unpack();
|
||||
this.x = unpacked[0].unpack();
|
||||
this.y = unpacked[1].unpack();
|
||||
this.scale = unpacked[2].unpack();
|
||||
this.transform = unpacked[3].unpack();
|
||||
this.primary = unpacked[4].unpack();
|
||||
// [ [connector, vendor, product, serial]* ]
|
||||
this.monitors = unpacked[5].deep_unpack();
|
||||
this.properties = unpacked[6].unpack();
|
||||
for (let key in this.properties) {
|
||||
this.properties[key] = this.properties[key].unpack().unpack();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const DisplayConfigState = class DisplayConfigState {
|
||||
constructor(result) {
|
||||
let unpacked = result.unpack();
|
||||
|
||||
this.serial = unpacked[0].unpack();
|
||||
|
||||
this.monitors = [];
|
||||
let monitors = unpacked[1].unpack();
|
||||
monitors.forEach(monitor_packed => {
|
||||
let monitor = new Monitor(monitor_packed);
|
||||
this.monitors.push(monitor);
|
||||
});
|
||||
|
||||
this.logical_monitors = [];
|
||||
let logical_monitors = unpacked[2].unpack();
|
||||
logical_monitors.forEach(lmonitor_packed => {
|
||||
let lmonitor = new LogicalMonitor(lmonitor_packed);
|
||||
this.logical_monitors.push(lmonitor);
|
||||
});
|
||||
|
||||
this.properties = unpacked[3].unpack();
|
||||
for (let key in this.properties) {
|
||||
this.properties[key] = this.properties[key].unpack().unpack();
|
||||
}
|
||||
}
|
||||
|
||||
get builtin_monitor() {
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let monitor = this.monitors[i];
|
||||
if (monitor.is_builtin) {
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get_monitor(connector) {
|
||||
for (let i = 0; i < this.monitors.length; i++) {
|
||||
let monitor = this.monitors[i];
|
||||
if (monitor.connector === connector) {
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get_logical_monitor_for(connector) {
|
||||
for (let i = 0; i < this.logical_monitors.length; i++) {
|
||||
let lmonitor = this.logical_monitors[i];
|
||||
for (let j = 0; j < lmonitor.monitors.length; j++) {
|
||||
let lm_connector = lmonitor.monitors[j][0];
|
||||
if (connector === lm_connector) {
|
||||
return lmonitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pack_to_apply(method) {
|
||||
let packing = [this.serial, method, [], {}];
|
||||
let logical_monitors = packing[2];
|
||||
let properties = packing[3];
|
||||
|
||||
this.logical_monitors.forEach(lmonitor => {
|
||||
let lmonitor_pack = [
|
||||
lmonitor.x,
|
||||
lmonitor.y,
|
||||
lmonitor.scale,
|
||||
lmonitor.transform,
|
||||
lmonitor.primary,
|
||||
[]
|
||||
];
|
||||
let monitors = lmonitor_pack[5];
|
||||
for (let i = 0; i < lmonitor.monitors.length; i++) {
|
||||
let connector = lmonitor.monitors[i][0];
|
||||
let monitor = this.get_monitor(connector);
|
||||
monitors.push([
|
||||
connector,
|
||||
monitor.current_mode_id,
|
||||
{
|
||||
'enable_underscanning': new GLib.Variant('b', monitor.is_underscanning)
|
||||
}
|
||||
]);
|
||||
}
|
||||
logical_monitors.push(lmonitor_pack);
|
||||
});
|
||||
|
||||
if ('layout-mode' in this.properties) {
|
||||
properties['layout-mode'] = new GLib.Variant('b', this.properties['layout-mode']);
|
||||
}
|
||||
|
||||
return new GLib.Variant('(uua(iiduba(ssa{sv}))a{sv})', packing);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,225 @@
|
||||
/* extension.js
|
||||
* Copyright (C) 2023 kosmospredanie, shyzus, Shinigaminai
|
||||
*
|
||||
* 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 { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
import * as SystemActions from 'resource:///org/gnome/shell/misc/systemActions.js';
|
||||
|
||||
import * as Rotator from './rotator.js'
|
||||
|
||||
const ORIENTATION_LOCK_SCHEMA = 'org.gnome.settings-daemon.peripherals.touchscreen';
|
||||
const ORIENTATION_LOCK_KEY = 'orientation-lock';
|
||||
|
||||
// Orientation names must match those provided by net.hadess.SensorProxy
|
||||
const Orientation = Object.freeze({
|
||||
'normal': 0,
|
||||
'left-up': 1,
|
||||
'bottom-up': 2,
|
||||
'right-up': 3
|
||||
});
|
||||
|
||||
class SensorProxy {
|
||||
constructor(rotate_cb) {
|
||||
this._rotate_cb = rotate_cb;
|
||||
this._proxy = null;
|
||||
this._enabled = false;
|
||||
this._watcher_id = Gio.bus_watch_name(
|
||||
Gio.BusType.SYSTEM,
|
||||
'net.hadess.SensorProxy',
|
||||
Gio.BusNameWatcherFlags.NONE,
|
||||
this.appeared.bind(this),
|
||||
this.vanished.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
Gio.bus_unwatch_name(this._watcher_id);
|
||||
if (this._enabled) this.disable();
|
||||
this._proxy = null;
|
||||
}
|
||||
|
||||
enable() {
|
||||
this._enabled = true;
|
||||
if (this._proxy === null) return;
|
||||
this._proxy.call_sync('ClaimAccelerometer', null, Gio.DBusCallFlags.NONE, -1, null);
|
||||
}
|
||||
|
||||
disable() {
|
||||
this._enabled = false;
|
||||
if (this._proxy === null) return;
|
||||
this._proxy.call_sync('ReleaseAccelerometer', null, Gio.DBusCallFlags.NONE, -1, null);
|
||||
}
|
||||
|
||||
appeared(connection, name, name_owner) {
|
||||
this._proxy = Gio.DBusProxy.new_for_bus_sync(
|
||||
Gio.BusType.SYSTEM, Gio.DBusProxyFlags.NONE, null,
|
||||
'net.hadess.SensorProxy', '/net/hadess/SensorProxy', 'net.hadess.SensorProxy',
|
||||
null);
|
||||
this._proxy.connect('g-properties-changed', this.properties_changed.bind(this));
|
||||
if (this._enabled) {
|
||||
this._proxy.call_sync('ClaimAccelerometer', null, Gio.DBusCallFlags.NONE, -1, null);
|
||||
}
|
||||
}
|
||||
|
||||
vanished(connection, name) {
|
||||
this._proxy = null;
|
||||
}
|
||||
|
||||
properties_changed(proxy, changed, invalidated) {
|
||||
if (!this._enabled) return;
|
||||
let properties = changed.deep_unpack();
|
||||
for (let [name, value] of Object.entries(properties)) {
|
||||
if (name != 'AccelerometerOrientation') continue;
|
||||
let target = value.unpack();
|
||||
this._rotate_cb(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ScreenAutorotate {
|
||||
constructor(settings) {
|
||||
this._system_actions = SystemActions.getDefault();
|
||||
this._settings = settings;
|
||||
this._system_actions_backup = null;
|
||||
this._override_system_actions();
|
||||
this._orientation_settings = new Gio.Settings({ schema_id: ORIENTATION_LOCK_SCHEMA });
|
||||
this._orientation_settings.connect('changed::' + ORIENTATION_LOCK_KEY, this._orientation_lock_changed.bind(this));
|
||||
|
||||
this._sensor_proxy = new SensorProxy(this.rotate_to.bind(this));
|
||||
|
||||
this._state = false; // enabled or not
|
||||
|
||||
let locked = this._orientation_settings.get_boolean(ORIENTATION_LOCK_KEY);
|
||||
if (!locked) this.enable();
|
||||
}
|
||||
|
||||
_override_system_actions() {
|
||||
this._system_actions_backup = {
|
||||
'_updateOrientationLock': this._system_actions._updateOrientationLock
|
||||
};
|
||||
|
||||
this._system_actions._updateOrientationLock = function() {
|
||||
this._actions.get('lock-orientation').available = true;
|
||||
this.notify('can-lock-orientation');
|
||||
};
|
||||
|
||||
this._system_actions._updateOrientationLock();
|
||||
}
|
||||
|
||||
_restore_system_actions() {
|
||||
if (this._system_actions_backup === null) return;
|
||||
this._system_actions._updateOrientationLock = this._system_actions_backup['_updateOrientationLock'];
|
||||
this._system_actions._updateOrientationLock();
|
||||
this._system_actions_backup = null;
|
||||
}
|
||||
|
||||
_orientation_lock_changed() {
|
||||
let locked = this._orientation_settings.get_boolean(ORIENTATION_LOCK_KEY);
|
||||
if (this._state == locked) {
|
||||
this.toggle();
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._sensor_proxy.destroy();
|
||||
this._orientation_settings = null;
|
||||
this._restore_system_actions();
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if (this._state) {
|
||||
this.disable();
|
||||
} else {
|
||||
this.enable();
|
||||
}
|
||||
}
|
||||
enable() {
|
||||
this._sensor_proxy.enable();
|
||||
this._state = true;
|
||||
}
|
||||
|
||||
disable() {
|
||||
this._sensor_proxy.disable();
|
||||
this._state = false;
|
||||
}
|
||||
|
||||
rotate_to(orientation) {
|
||||
const sensor = Orientation[orientation];
|
||||
const invert_horizontal_direction = this._settings.get_boolean('invert-horizontal-rotation-direction');
|
||||
const invert_vertical_direction = this._settings.get_boolean('invert-vertical-rotation-direction');
|
||||
const offset = this._settings.get_int('orientation-offset');
|
||||
let target = sensor; // Default to sensor output.
|
||||
|
||||
switch (sensor) {
|
||||
case 0:
|
||||
// sensor reports landscape
|
||||
if (invert_horizontal_direction) {
|
||||
target = 2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// sensor reports portrait
|
||||
if (invert_vertical_direction) {
|
||||
target = 3;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// sensor reports landscape-inverted
|
||||
if (invert_horizontal_direction) {
|
||||
target = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// sensor reports portrait-inverted
|
||||
if (invert_vertical_direction) {
|
||||
target = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
target = (target + offset) % 4;
|
||||
if (this._settings.get_boolean('debug-logging')) {
|
||||
console.debug(`sensor=${Orientation[orientation]}`);
|
||||
console.debug(`offset=${offset}`);
|
||||
console.debug(`target=${target}`);
|
||||
}
|
||||
Rotator.rotate_to(target);
|
||||
}
|
||||
}
|
||||
|
||||
export default class ScreenAutoRotateExtension extends Extension {
|
||||
enable() {
|
||||
this._settings = this.getSettings();
|
||||
this._ext = new ScreenAutorotate(this._settings);
|
||||
}
|
||||
|
||||
disable() {
|
||||
/*
|
||||
Comment for unlock-dialog usage:
|
||||
The unlock-dialog sesson-mode is usefull for this extension as it allows
|
||||
the user to rotate their screen or lock rotation after their device may
|
||||
have auto-locked. This provides the ability to log back in regardless of
|
||||
the orientation of the device in tablet mode.
|
||||
*/
|
||||
this._settings = null;
|
||||
this._ext.destroy();
|
||||
this._ext = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"_generated": "Generated by SweetTooth, do not edit",
|
||||
"description": "Enable screen rotation regardless of touch mode. Fork of Screen Autorotate by Kosmospredanie.",
|
||||
"gettext-domain": "gnome-shell-extension-screen-rotate",
|
||||
"name": "Screen Rotate",
|
||||
"session-modes": [
|
||||
"unlock-dialog",
|
||||
"user"
|
||||
],
|
||||
"settings-schema": "org.gnome.shell.extensions.screen-rotate",
|
||||
"shell-version": [
|
||||
"45"
|
||||
],
|
||||
"url": "https://github.com/shyzus/gnome-shell-extension-screen-autorotate",
|
||||
"uuid": "screen-rotate@shyzus.github.io",
|
||||
"version": 15
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
/* prefs.js
|
||||
* Copyright (C) 2023 kosmospredanie, shyzus, Shinigaminai
|
||||
*
|
||||
* 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 Gtk from 'gi://Gtk';
|
||||
import Gio from 'gi://Gio';
|
||||
import Adw from 'gi://Adw';
|
||||
|
||||
import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
|
||||
|
||||
export default class MyExtensionPreferences extends ExtensionPreferences {
|
||||
|
||||
fillPreferencesWindow(window) {
|
||||
window._settings = this.getSettings();
|
||||
|
||||
const page = new Adw.PreferencesPage();
|
||||
window.add(page);
|
||||
|
||||
const orientationGroup = new Adw.PreferencesGroup();
|
||||
orientationGroup.set_title('Orientation Settings')
|
||||
page.add(orientationGroup);
|
||||
|
||||
const debugGroup = new Adw.PreferencesGroup();
|
||||
debugGroup.set_title('Debug Settings');
|
||||
page.add(debugGroup);
|
||||
|
||||
const invertHorizontalRow = new Adw.ActionRow({
|
||||
title: 'Invert horizontal rotation'
|
||||
});
|
||||
orientationGroup.add(invertHorizontalRow);
|
||||
|
||||
const invertVerticalRow = new Adw.ActionRow({
|
||||
title: 'Invert vertical rotation'
|
||||
});
|
||||
orientationGroup.add(invertVerticalRow);
|
||||
|
||||
const flipOrientationRow = new Adw.ActionRow({
|
||||
title: 'Flip orientation',
|
||||
subtitle: 'e.g: Landscape to Portrait. Default is Landscape'
|
||||
});
|
||||
orientationGroup.add(flipOrientationRow);
|
||||
|
||||
const setOffsetRow = new Adw.ActionRow({
|
||||
title: 'Set orientation offset',
|
||||
subtitle: 'Valid offset range: 0 to 3. Default is 0\nExperiment with this in case\
|
||||
orientation is incorrect due to the display being mounted in a non-landscape orientation\
|
||||
e.g PineTab2 or GPD Pocket 3'
|
||||
});
|
||||
|
||||
orientationGroup.add(setOffsetRow);
|
||||
|
||||
const toggleLoggingRow = new Adw.ActionRow({
|
||||
title: 'Enable debug logging',
|
||||
subtitle: 'Use "journalctl /usr/bin/gnome-shell -f" to see log output.'
|
||||
});
|
||||
debugGroup.add(toggleLoggingRow);
|
||||
|
||||
const invertHorizontalRotationSwitch = new Gtk.Switch({
|
||||
active: window._settings.get_boolean('invert-horizontal-rotation-direction'),
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
|
||||
const invertVerticalRotationSwitch = new Gtk.Switch({
|
||||
active: window._settings.get_boolean('invert-vertical-rotation-direction'),
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
|
||||
const flipOrientationSwitch = new Gtk.Switch({
|
||||
active: window._settings.get_boolean('flip-orientation'),
|
||||
valign: Gtk.Align.CENTER,
|
||||
});
|
||||
|
||||
const setOffsetSpinButton = Gtk.SpinButton.new_with_range(0, 3, 1);
|
||||
setOffsetSpinButton.value = window._settings.get_int('orientation-offset');
|
||||
|
||||
const toggleLoggingSwitch = new Gtk.Switch({
|
||||
active: window._settings.get_boolean('debug-logging'),
|
||||
valign: Gtk.Align.CENTER
|
||||
});
|
||||
|
||||
window._settings.bind('invert-horizontal-rotation-direction',
|
||||
invertHorizontalRotationSwitch, 'active', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
window._settings.bind('invert-vertical-rotation-direction',
|
||||
invertVerticalRotationSwitch, 'active', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
window._settings.bind('flip-orientation',
|
||||
flipOrientationSwitch, 'active', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
window._settings.bind('orientation-offset',
|
||||
setOffsetSpinButton, 'value', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
window._settings.bind('debug-logging',
|
||||
toggleLoggingSwitch, 'active', Gio.SettingsBindFlags.DEFAULT);
|
||||
|
||||
invertHorizontalRow.add_suffix(invertHorizontalRotationSwitch);
|
||||
invertHorizontalRow.activatable_widget = invertHorizontalRotationSwitch;
|
||||
|
||||
invertVerticalRow.add_suffix(invertVerticalRotationSwitch);
|
||||
invertVerticalRow.activatable_widget = invertVerticalRotationSwitch;
|
||||
|
||||
flipOrientationRow.add_suffix(flipOrientationSwitch);
|
||||
flipOrientationRow.activatable_widget = flipOrientationSwitch;
|
||||
|
||||
setOffsetRow.add_suffix(setOffsetSpinButton);
|
||||
setOffsetRow.activatable_widget = setOffsetSpinButton;
|
||||
|
||||
toggleLoggingRow.add_suffix(toggleLoggingSwitch);
|
||||
toggleLoggingRow.activatable_widget = toggleLoggingSwitch;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
/* rotator.js
|
||||
*
|
||||
* Copyright (C) 2022 kosmospredanie, shyzus
|
||||
*
|
||||
* 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 Gio from 'gi://Gio';
|
||||
|
||||
import * as BusUtils from './busUtils.js';
|
||||
const connection = Gio.DBus.session;
|
||||
|
||||
export function call_dbus_method(method, params = null, handler) {
|
||||
if (handler != undefined || handler != null) {
|
||||
connection.call(
|
||||
'org.gnome.Mutter.DisplayConfig',
|
||||
'/org/gnome/Mutter/DisplayConfig',
|
||||
'org.gnome.Mutter.DisplayConfig',
|
||||
method,
|
||||
params,
|
||||
null,
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1,
|
||||
null, handler);
|
||||
} else {
|
||||
connection.call(
|
||||
'org.gnome.Mutter.DisplayConfig',
|
||||
'/org/gnome/Mutter/DisplayConfig',
|
||||
'org.gnome.Mutter.DisplayConfig',
|
||||
method,
|
||||
params,
|
||||
null,
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1,
|
||||
null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function get_state() {
|
||||
return new Promise((resolve, reject) => {
|
||||
call_dbus_method('GetCurrentState', null, (connection, res) => {
|
||||
try {
|
||||
let reply = connection.call_finish(res);
|
||||
let configState = new BusUtils.DisplayConfigState(reply)
|
||||
resolve(configState);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
export function rotate_to(transform) {
|
||||
this.get_state().then(state => {
|
||||
let builtin_monitor = state.builtin_monitor;
|
||||
let logical_monitor = state.get_logical_monitor_for(builtin_monitor.connector);
|
||||
logical_monitor.transform = transform;
|
||||
let variant = state.pack_to_apply(BusUtils.Methods['temporary']);
|
||||
call_dbus_method('ApplyMonitorsConfig', variant);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
})
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,46 @@
|
||||
<!--
|
||||
- org.gnome.shell.extensions.screen-rotate.gschema.xml
|
||||
- Copyright (C) 2023 shyzus, Shinigaminai
|
||||
-
|
||||
- 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/>.
|
||||
-
|
||||
-->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist>
|
||||
<schema id="org.gnome.shell.extensions.screen-rotate"
|
||||
path="/org/gnome/shell/extensions/screen-rotate/">
|
||||
|
||||
<key type="b" name="invert-horizontal-rotation-direction">
|
||||
<default>false</default>
|
||||
<description>Invert horizontal rotation direction of the screen</description>
|
||||
</key>
|
||||
<key type="b" name="invert-vertical-rotation-direction">
|
||||
<default>false</default>
|
||||
<description>Invert vertical rotation direction of the screen</description>
|
||||
</key>
|
||||
<key type="b" name="flip-orientation">
|
||||
<default>false</default>
|
||||
<description>Alter orientation. (e.g: Landscape to Portrait. Default is Landscape.)</description>
|
||||
</key>
|
||||
<key type="i" name="orientation-offset">
|
||||
<default>0</default>
|
||||
<description>Experiment with this offset in case orientation is incorrect.</description>
|
||||
</key>
|
||||
<key type="b" name="debug-logging">
|
||||
<default>false</default>
|
||||
<description>Toggle debug logging.</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
Reference in New Issue
Block a user