Last active
May 5, 2023 17:45
-
-
Save marcinjahn/7acadd90e3d8299ffd2f67470f18b10b to your computer and use it in GitHub Desktop.
prefs.js with failure "JS ERROR: Failed to open preferences: ImportError: No JS module 'ui' found in search path"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const GIRepository = imports.gi.GIRepository; | |
const GLib = imports.gi.GLib; | |
let libdir = GIRepository.Repository.get_search_path().find(path => { | |
return path.endsWith("/gjs/girepository-1.0"); | |
}).replace("/gjs/girepository-1.0", ""); | |
const gsdir = GLib.build_filenamev([libdir, "gnome-shell"]); | |
if (!GLib.file_test(gsdir, GLib.FileTest.IS_DIR)) { | |
const currentDir = `/${GLib.path_get_basename(libdir)}`; | |
libdir = libdir.replace(currentDir, ""); | |
} | |
const typelibDir = GLib.build_filenamev([libdir, "gnome-shell"]); | |
GIRepository.Repository.prepend_search_path(typelibDir); | |
GIRepository.Repository.prepend_library_path(typelibDir); | |
var prefs = (function (gvc1, adw1, gtk4) { | |
'use strict'; | |
function delay(miliseconds) { | |
return new Promise(resolve => { | |
setTimeout(() => resolve(undefined), miliseconds); | |
}); | |
} | |
const VolumeStatus = imports.ui.status.volume; | |
const Main = imports.ui.main; | |
const QuickSettings = Main.panel.statusArea.quickSettings; | |
async function getVisibleDevices() { | |
const mixer = VolumeStatus.getMixerControl(); | |
await waitForReady(mixer); | |
const devices = QuickSettings._volume._output._deviceItems; | |
// value is PopupImageMenuItem, label is St.Label | |
return Array.from(devices, ([id, value]) => ({ | |
id, | |
displayName: value.label.get_text() | |
})); | |
} | |
async function getOutputDevicesInfo(ids) { | |
const mixer = VolumeStatus.getMixerControl(); | |
await waitForReady(mixer); | |
return ids.map(id => ({ | |
id, | |
displayName: mixer.lookup_output_id(id).description | |
})); | |
} | |
async function waitForReady(mixer) { | |
while (mixer.get_state() === gvc1.MixerControlState.CONNECTING) { | |
await delay(200); | |
} | |
const state = mixer.get_state(); | |
if (state === gvc1.MixerControlState.FAILED) { | |
throw new Error('MixerControl is in a failed state'); | |
} | |
else if (state === gvc1.MixerControlState.CLOSED) { | |
throw new Error('MixerControl is in a closed state'); | |
} | |
} | |
const ExtensionUtils = imports.misc.extensionUtils; | |
const SettingsPath = 'com.marcinjahn.exampleextension'; | |
const excludedOutputsSetting = 'excluded-outputs'; | |
function getExcludedOutputDeviceIds() { | |
const settings = ExtensionUtils.getSettings(SettingsPath); | |
const ids = settings.get_strv(excludedOutputsSetting); | |
return ids.map(id => parseInt(id)); | |
} | |
imports.misc.extensionUtils; | |
function init() { | |
} | |
async function fillPreferencesWindow(window) { | |
const visibleDevicesPromise = getVisibleDevices(); | |
const hiddenDevicesPromise = getOutputDevicesInfo(getExcludedOutputDeviceIds()); | |
const page = new adw1.PreferencesPage(); | |
const group = new adw1.PreferencesGroup(); | |
page.add(group); | |
const [visibleDevices, hiddenDevices] = await Promise.all([ | |
visibleDevicesPromise, | |
hiddenDevicesPromise | |
]); | |
visibleDevices.forEach(device => { | |
group.add(createDeviceRow(device, true)); | |
}); | |
hiddenDevices.forEach(device => { | |
group.add(createDeviceRow(device, false)); | |
}); | |
window.add(page); | |
} | |
function createDeviceRow(device, active) { | |
const row = new adw1.ActionRow({ title: device.displayName }); | |
const toggle = new gtk4.Switch({ | |
active, | |
valign: gtk4.Align.CENTER, | |
}); | |
// Add the switch to the row | |
row.add_suffix(toggle); | |
row.activatable_widget = toggle; | |
return row; | |
} | |
var prefs = { init, fillPreferencesWindow }; | |
return prefs; | |
})(imports.gi.Gvc, imports.gi.Adw, imports.gi.Gtk); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment