diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/busUtils.js b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/busUtils.js
new file mode 100644
index 0000000..6839c8c
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/busUtils.js
@@ -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 .
+*/
+
+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);
+ }
+}
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/extension.js b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/extension.js
new file mode 100644
index 0000000..326f527
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/extension.js
@@ -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 .
+*/
+
+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;
+ }
+}
+
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/metadata.json b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/metadata.json
new file mode 100644
index 0000000..8a53079
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/metadata.json
@@ -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
+}
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/prefs.js b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/prefs.js
new file mode 100644
index 0000000..862423e
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/prefs.js
@@ -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 .
+*/
+
+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;
+ }
+}
\ No newline at end of file
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/rotator.js b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/rotator.js
new file mode 100644
index 0000000..5f6ff13
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/rotator.js
@@ -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 .
+*/
+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);
+ })
+}
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/gschemas.compiled b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/gschemas.compiled
new file mode 100644
index 0000000..6833ea0
Binary files /dev/null and b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/gschemas.compiled differ
diff --git a/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/org.gnome.shell.extensions.screen-rotate.gschema.xml b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/org.gnome.shell.extensions.screen-rotate.gschema.xml
new file mode 100644
index 0000000..f391aff
--- /dev/null
+++ b/gnome/.local/share/gnome-shell/extensions/screen-rotate@shyzus.github.io/schemas/org.gnome.shell.extensions.screen-rotate.gschema.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ false
+ Invert horizontal rotation direction of the screen
+
+
+ false
+ Invert vertical rotation direction of the screen
+
+
+ false
+ Alter orientation. (e.g: Landscape to Portrait. Default is Landscape.)
+
+
+ 0
+ Experiment with this offset in case orientation is incorrect.
+
+
+ false
+ Toggle debug logging.
+
+
+
+