├── screenshot42.png ├── screenshot43.png ├── unsafe-mode-menu@linushdot.local ├── schemas │ ├── gschemas.compiled │ └── org.gnome.shell.extensions.unsafe-mode-menu.gschema.xml ├── metadata.json ├── prefs.js └── extension.js ├── LICENSE └── README.md /screenshot42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linushdot/unsafe-mode-menu/HEAD/screenshot42.png -------------------------------------------------------------------------------- /screenshot43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linushdot/unsafe-mode-menu/HEAD/screenshot43.png -------------------------------------------------------------------------------- /unsafe-mode-menu@linushdot.local/schemas/gschemas.compiled: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linushdot/unsafe-mode-menu/HEAD/unsafe-mode-menu@linushdot.local/schemas/gschemas.compiled -------------------------------------------------------------------------------- /unsafe-mode-menu@linushdot.local/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Unsafe Mode Menu", 3 | "description": "Change unsafe mode via panel menu", 4 | "uuid": "unsafe-mode-menu@linushdot.local", 5 | "url": "https://github.com/linushdot/unsafe-mode-menu", 6 | "version": 11, 7 | "shell-version": [ 8 | "45", "46", "47", "48", "49" 9 | ], 10 | "settings-schema": "org.gnome.shell.extensions.unsafe-mode-menu" 11 | } 12 | -------------------------------------------------------------------------------- /unsafe-mode-menu@linushdot.local/schemas/org.gnome.shell.extensions.unsafe-mode-menu.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | Enable on Startup 7 | 8 | Enable unsafe mode when extension is enabled 9 | 10 | 11 | 12 | false 13 | Current state 14 | 15 | Enable/disable unsafe mode directly 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 linushdot 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /unsafe-mode-menu@linushdot.local/prefs.js: -------------------------------------------------------------------------------- 1 | import Adw from 'gi://Adw'; 2 | import Gtk from 'gi://Gtk'; 3 | import Gio from 'gi://Gio'; 4 | 5 | import {ExtensionPreferences} from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; 6 | 7 | export default class UnsafeModeMenuExtensionPreferences extends ExtensionPreferences { 8 | 9 | // Preferences Window 10 | fillPreferencesWindow(window) { 11 | const settings = this.getSettings(); 12 | 13 | // Preferences page with single group and row 14 | const page = new Adw.PreferencesPage(); 15 | window.add(page); 16 | const group = new Adw.PreferencesGroup(); 17 | page.add(group); 18 | const row = new Adw.ActionRow({ 19 | title: 'Enable on Startup', 20 | subtitle: 'Enable unsafe mode when extension is enabled' 21 | }); 22 | group.add(row); 23 | 24 | // Switch and binding 25 | const toggle = new Gtk.Switch({ 26 | active: settings.get_boolean('enable-on-startup'), 27 | valign: Gtk.Align.CENTER, 28 | }); 29 | settings.bind('enable-on-startup', toggle, 'active', 30 | Gio.SettingsBindFlags.DEFAULT); 31 | row.add_suffix(toggle); 32 | row.activatable_widget = toggle; 33 | 34 | // Make sure the window does not outlive the settings object 35 | window._settings = settings; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /unsafe-mode-menu@linushdot.local/extension.js: -------------------------------------------------------------------------------- 1 | import GObject from 'gi://GObject'; 2 | import Gio from 'gi://Gio'; 3 | 4 | import * as QuickSettings from 'resource:///org/gnome/shell/ui/quickSettings.js'; 5 | 6 | import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js'; 7 | import * as Main from 'resource:///org/gnome/shell/ui/main.js'; 8 | 9 | const UnsafeModeIndicator = GObject.registerClass( 10 | class UnsafeModeIndicator extends QuickSettings.SystemIndicator { 11 | _init(extensionObject) { 12 | super._init(); 13 | } 14 | }); 15 | 16 | const UnsafeModeToggle = GObject.registerClass( 17 | class UnsafeModeToggle extends QuickSettings.QuickToggle { 18 | _init(extensionObject) { 19 | super._init({ 20 | title: 'Unsafe Mode', 21 | iconName: 'channel-insecure-symbolic', 22 | toggleMode: true, 23 | }); 24 | 25 | // listen for changes to unsafe mode 26 | global.context.bind_property('unsafe-mode', this, 'checked', 27 | GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE); 28 | 29 | // bind to state setting 30 | this._settings = extensionObject.getSettings(); 31 | this._settings.bind('state', global.context, 'unsafe-mode', Gio.SettingsBindFlags.DEFAULT); 32 | } 33 | }); 34 | 35 | export default class UnsafeModeMenuExtension extends Extension { 36 | enable() { 37 | this._indicator = new UnsafeModeIndicator(this); 38 | this._indicator.quickSettingsItems.push(new UnsafeModeToggle(this)); 39 | 40 | Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator); 41 | 42 | // enable unsafe mode if configured 43 | if(this.getSettings().get_boolean('enable-on-startup')) 44 | global.context.unsafe_mode = true; 45 | } 46 | 47 | disable() { 48 | this._indicator.quickSettingsItems.forEach(item => item.destroy()); 49 | this._indicator.destroy(); 50 | this._indicator = null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unsafe Mode Menu 2 | 3 | Simple GNOME extension to change the Gnome Shell unsafe-mode via the quick 4 | settings menu/panel menu. Currently runs on Gnome Shell 42-49 using the following 5 | extension versions: 6 | 7 | | Gnome Shell | Latest Version | Branch | 8 | |-------------|----------------|-------------| 9 | | 45-49 | v11 | main | 10 | | 42-44 | v8 | gnome-42-44 | 11 | 12 | If you want to try it on a newer version you need to add `""` to the 13 | list of supported versions in `unsafe-mode-menu@linushdot.local/metadata.json` 14 | before installing it. If it just works or if there are bugs with the new Gnome 15 | Shell, feel free to open an issue here and I will see if I can update the 16 | extension. 17 | 18 | ## Install/Update 19 | 20 | Clone this repository and copy the extension to your extensions folder. 21 | 22 | ``` 23 | git clone https://github.com/linushdot/unsafe-mode-menu.git 24 | cd unsafe-mode-menu 25 | mkdir -p ~/.local/share/gnome-shell/extensions/ 26 | cp -r unsafe-mode-menu@linushdot.local ~/.local/share/gnome-shell/extensions/ 27 | ``` 28 | 29 | Then restart the shell and enable the extension from https://extensions.gnome.org/local/ 30 | or from `gnome-extensions-app`. 31 | Also on this page or in the extensions app the preferences can be modified. 32 | 33 | If you need an older version than the current one (for example version 8) clone the repository with 34 | the following command instead and follow the rest of the steps. 35 | 36 | ``` 37 | git clone --branch v8 https://github.com/linushdot/unsafe-mode-menu.git 38 | ``` 39 | 40 | ## Preferences 41 | 42 | - Enable on Startup: enable unsafe mode when extension is enabled or when 43 | Gnome Shell is started with the extension enabled 44 | 45 | ## Screenshot Gnome Shell 43 46 | 47 | ![Screenshot Gnome Shell 43](screenshot43.png) 48 | 49 | ## Screenshot Gnome Shell 42 50 | 51 | ![Screenshot Gnome Shell 42](screenshot42.png) 52 | 53 | ## Changing Unsafe Mode via dconf 54 | 55 | With the extension enabled unsafe mode can be read and changed using `dconf`: 56 | ``` 57 | dconf read /org/gnome/shell/extensions/unsafe-mode-menu/state 58 | dconf write /org/gnome/shell/extensions/unsafe-mode-menu/state 59 | ``` 60 | 61 | ## Use Cases 62 | 63 | Since Gnome 41 unsafe mode is necessary to let applications access certain 64 | [private D-Bus APIs](https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1970) 65 | of the Gnome Shell. This mostly concerns: 66 | 67 | - API for Screenshots (also sometimes used for screen sharing): 68 | most applications now use a 69 | [new interface](https://flatpak.github.io/xdg-desktop-portal/) instead, but 70 | legacy applications may need unsafe mode for this 71 | - Calling the `org.gnome.Shell.Eval` method to execute javascript inside 72 | Gnome Shell: This is useful for keybindings or for controlling the Gnome 73 | Shell from a script. 74 | 75 | An example for the latter is changing to the secondary input source using a 76 | command: 77 | 78 | ``` 79 | gdbus call --session --dest org.gnome.Shell \ 80 | --object-path /org/gnome/Shell \ 81 | --method org.gnome.Shell.Eval \ 82 | "imports.ui.status.keyboard.getInputSourceManager().inputSources[1].activate()" 83 | ``` 84 | --------------------------------------------------------------------------------