Review of "Gtk4 Desktop Icons NG (DING)" version 100.21 (134)

Details Page Preview

Adw. Desktop Icons Libadwaita/Gtk4 port of Desktop Icons NG with multiple fixes and new features. Latest update: widgets can now be pinned into floating windows, including the Today calendar and media widgets. This release also adds a new Sticky Note widget, improves pinned widget controls and focus behavior, adds media widget playback and volume controls, and updates the world clock widgets for better timezone and DST handling. Now has a widget layer that can run widgets- like KDE desklets, they are little HTML display apps that run in Webkit. Icons cover this layer, layers can be moved up or down for editing. Widgets can be snapped to a grid to maintain row/column alignment or free positioned. Icons can be positioned anywhere on desktop or are snapped to a grid. Can make links on the Desktop. GSconnect Integration, can send files to connected devices. Drag and Drop support on to Dock, Dash, or from Dock, Dash to the Desktop. Updated and modified code base, uses Gio menus. All functions are asynchronous where possible. It is ported to ESM modules, supports Gnome 45 and higher. Translations available in- [ar, az, be, bg, bn, ca, cs, da, de, el, eo, es, et eu, fa, fi, fr, fur, ga, gl, he, hi, hr, hu, id, it, ja, ka, kk, ko, ky, lv, lt, ms, nb, nb_NO, nl, oc, pl, pt_BR, pt, ro, ru, sk, sl, sq, sv, ta, tl, tr, th, uk, ur, zh-Hans, zh-Hant, zh_CN, zh_TW] Translated using LibreTranslate, machine translation, not every string is verified manually. Although most strings in languages should be correct, errors are possible. Corrections, verification of translated strings, and new translations are welcome, all translations are on Weblate. You can help translate Adw. Desktop Icons NG on [Hosted Weblate](https://hosted.weblate.org/projects/gtk4-desktop-icons-ng/gtk4-ding-pot/). Multiple fixes and new features- * New media player/display widget in horizontal or vertical available for download. Multiple rendering fixes for the old widgets, please re-install. * Media widgets are now pinnable and include on-widget MPRIS controls for Previous, Play/Pause, Next, volume slider, +/- volume buttons, and mouse-wheel volume. * New Sticky Note widget with rich-text editing, checklist support, links, note colors, and floating/pinned window support. * Floating widget handling is improved with better overlay controls, focus retention, and more reliable redraw/reload behavior when moving widgets between desktop and pinned windows. * Add widget grid, improve widget chrome to stay on screen, multiple fixes to widget rendering to redisplay when desktop geometry changes, animates with icons on geometry changes. * Use GSK to draw instead of Cairo, optimizes GPU/CPU use. * Fixes to widget positioning, keyboard modifier selection of icons with arrow keys. * Fixes overview animation. * All widgets have been updaetd. Re-install from widgets folder on GitLab Website. * Widgets can now run backend processes for host side compute work. Added demo new metrics widget and Today(Calendar) view widget. Added helper classes for backend and widget for widget authors. * The program no explicitly asks for your permission prior to installing and running a widget and records this choice so you are not asked again. * Multiple fixes for the new widgets. * Widgets on desktop- little display desklets for Gnome. Demo widgets for weather and world clock available on Gitlab repo in the widgets subfolder. * Users can override CSS with their own CSS. * Uses LibreTranslate to automatically translate into 54 languages. * Right long click- launches shell background menu directly. * Animate margin changes with Adw.Animation. Respects global Gtk4/Gnome allow/disallow animation settings. * Improve search UI, files found containing the text in label are selected, non-selected files lose opacity an are dimmed so that found files are evident to the eye on a desktop with a large bunch of icons.. (Sundeep Mediratta) * Enable Gnome 49, use new API * Fixes, read xdg-terminals.list from correct system conf dirs. * Set localized default desktop name * Resizable open with dialog * Fix custom icons size * Update to more direct error message * Change name to Adw. Desktop Icons, version 100 :) * Feature complete shortcut manager with editable keybindings for app actions. * New About dialog and redesigned preferences. Proper credits and acknowledgements * Right click menu now displays and activates actions for .desktop files. * Added global hotkey accelerator to display or hide desktop icons. * New ShortCutsManager that displays Adw.Window and widgets for shortcuts. * Complete rewrite of the app, major clean up and restructuring. * Add a .desktop icon with actions for app, can be displayed in dock for windows, launcher, menus etc with right click actions, including hiding all windows * Show a shortcuts window for the application to list all available shortcuts. * Improve multi-monitor support, saves monitor positon with icon position, allow to change fractional scaling in app if a second monitor connected at different zoom level. * Fix dd-term focus loss isssue. * App rewritten as Adw.Application GObject subclass, better css handling, use Adw.Stylemanager, better icons and emblems for stackTop items. * Integrate ptyxis, replaces gnome-terminal on some distributions. Open ptyxis properly. * Modern emblems like Gnome Files, allow multiple emblems * Emblem for encrypted pdf, zip, 7z files * Allow setting any user folder as the Desktop folder following xdg-sepecifications and updating the xdg-files and vice versa in the running program. * Proper app icon, image and app name in Notifications. * Proper integration for AppImage files, treat them like .desktop files. Integration with AppImageLauncher. Prefer that to open AppImage files if available. * For Gnome 47, change highlighting and rubber band selection colors with accent-colors in Gnome Settings. * Selection rectangle with rounded corners, similar to Gnome Files aesthetic. * The stock gnome shell background menu can now be shown from the Gtk4 DING desktop right click menu. All shell settings can be accessed from that menu. * Icons can be placed on any arbitrary position. Make a mess! - icons can overlap each other etc. Neat people can keep the default behavior and have the icons always snapped to a grid. Controlled in preferences, tweaks, 'Snap to grid'. Affects the shape of icons and drag and drop behavior as well. Free positioning has trapezoidal icons, drop only works with direct overlap. Grid positioning has rectangular icons, and drag and drop works on overlap with the grid holding the icon. This behavior is consistent with other desktop environments. * Icons on background on overview, improved gesture switching icons appear to be on all work spaces on the background with workspace switching, with no flashing. * Support for dragging icons onto the dock - Drag icons from desktop to and drop over application icon to open them with the app. Works with Dash to Dock and Dash to Panel. * Support for dragging icons from desktop directly to Trash on Dash to Dock, or to mounted volumes on the dock, to copy them directly. * Set the correct cursor with proposed action on drop on dock. * Drag Navigation on Dock - dragging an icon over the Gnome Files icon on the dock or mounted drives, and hovering over it for 1/2 seconds will open a Gnome Files Window. Behavior can be changed in preferences. * Drag Navigation - dragging an icon over a folder icon or a drive icon, and then hovering over it for one and half seconds will open that location in Gnome Files. * Sets correct hovering behavior during drag and drop on the Dock, enables scrolling in the dock to icons when they are hidden. * Drag and drop Favorite apps from Dash to Dock, Dash to Panel directly to Desktop. Pressing shift, ctr or alt while doing this will copy or move the app to Desktop, allowing launching from the desktop. Just dropping an app from the dock to the desktop will remove from Dash/Dock. * Follows xdg-terminal-exec to display the correct terminal in right click menus, and will launch the correct terminal, even if xdg-terminal-exec is not installed. * Shows the correct file manager in the right click menu and give the user the option to change the file manager. * Gio menus, menus display all keyboard shortcuts. * Uses Gtk4 AlertDialog, uses asynchronous promises for dialog's, shows button to launch URL for help and troubleshooting information. * Automatically zip Folders if mailing them. * Tool tips are now positioned correctly to not go under the dash or make it auto hide, or go over/under any gnome shell actors on the edge of the screen. * Right Click Menus will not go under the dock. * Make Links on Desktop with Alt button on Wayland. Shift, Ctr or Alt button control the effect, move, copy, drop or link. (Linking may not work on X11) * Copied/dropped/pasted files retain dropped position. Undo action after trashing or moving files puts icons back in the old position. * Better multi monitor support, preference to place icons on non primary monitor. * GSconnect extension integration, can send files from desktop directly to connected mobile device. * Accessibility support with screen readers * Deals correctly with appimage files on desktop. * Display GIMP thumbnails, even for snap and flatpack installs. Please see Readme for full details of new features. Works best on Wayland. However your mileage may vary on X11. Multiple bugs fixed on X11. Please report all issues on the Gitlab link below, this page is not monitored. All known issues as well as all the features are detailed there.

Extension Homepage
https://gitlab.com/smedius/desktop-icons-ng

No comments.

Diff Against

Files

Note: Binary files aren't shown on the web site. To see all files, please download the extension zipfile.

Shexli (experimental) error 3 warning 22

Shexli found 25 issues that may need reviewer attention.

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 13 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/desktopFolderMonitor.js:45
    console.error(e)
  • app/desktopFolderMonitor.js:57
    console.error(e)
  • app/desktopFolderMonitor.js:130
    console.error(e)
  • app/desktopFolderMonitor.js:134
    console.error(e)
  • app/desktopFolderMonitor.js:198
    console.error(e)
  • app/desktopFolderMonitor.js:281
                            console.error(
                                e,
                                'Exception while updating desktop from' +
                                ` Directory Monitor attribute change: ${e.message}`
                            )
  • app/desktopFolderMonitor.js:296
                console.error(
                    e,
                    'Exception while updating desktop from Directory Monitor: ' +
                    `${e.message}`
                )
  • app/desktopFolderMonitor.js:414
                                console.error(e,
                                    `Failed with ${e.message} while adding` +
                                    ` extra folder ${newFolder.get_uri()}`
                                )
  • app/desktopFolderMonitor.js:508
                                console.error(e,
                                    `Failed with ${e.message} while ` +
                                    `adding volume ${newFolder}`
                                )
  • app/desktopFolderMonitor.js:529
                    console.error(e,
                        'Failed to read contents of' +
                        `${this._desktopDir.get_path()}`
                    )

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 7 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/desktopGrid.js:1795
    console.error(e)
  • app/desktopGrid.js:1809
    console.error(e)
  • app/desktopGrid.js:1883
    console.error(e)
  • app/desktopGrid.js:1897
    console.error(e)
  • app/desktopGrid.js:1958
    console.error(e)
  • app/desktopGrid.js:2196
    console.error(e)
  • app/desktopGrid.js:2274
                            console.error(e, `Error opening ${fileItem.uri}` +
                                ` in GNOME Files: ${e.message}`)
  • app/utils/desktopFolderUtils.js:110
                console.error(
                    `Unable to create Folder ${defaultDesktop}: ${e.message}`
                )
  • app/utils/desktopFolderUtils.js:143
    console.error(e, `XDG Desktop not set, ${e}`)
  • app/utils/desktopFolderUtils.js:164
    console.error('No system xdg user-dirs.default file')
  • app/utils/desktopFolderUtils.js:184
    console.error(e, `XDG Desktop not set in user-dirs.default, ${e}`)
  • app/utils/desktopFolderUtils.js:200
    console.error(e, `Error selecting folder: ${e.message}`)
  • app/utils/desktopFolderUtils.js:278
    console.error(e, `Failed to write XDG Desktop file with ${e}`)
  • app/utils/desktopFolderUtils.js:308
    console.error(e, `Failed to write XDG Desktop file with ${e}`)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 9 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/desktopManager.js:1029
    console.error(e, 'Error loading stackMarker icon')
  • app/desktopManager.js:1694
                        console.error(
                            e, `Failed to set attributes to ${dir.get_path()}`)
  • app/desktopManager.js:1701
    console.error(e, `Failed to create folder ${e.message}`)
  • app/desktopManager.js:1732
                console.error(
                    `Error while redrawing desktop: ${e.message}\n${e.stack}`
                )
  • app/desktopManager.js:1750
    console.error(`Error while refreshing desktop: ${e.message}`)
  • app/desktopManager.js:1763
    console.error(`Error while reframing desktop: ${e.message}`)
  • app/desktopManager.js:822
    console.log('Not enough space to add icons')
  • app/desktopManager.js:1774
                console.log('Exception while updating desktop after the hidden ' +
                    `settings changed: ${e.message}\n${e.stack}`)
  • app/desktopManager.js:1809
                console.log('Exception while reloading desktop after icon ' +
                    `size change: ${e.message}\n${e.stack}`)
  • app/gnomeShellDragDrop.js:60
    console.error(e)
  • app/gnomeShellDragDrop.js:80
    console.error(e)
  • app/gnomeShellDragDrop.js:108
    console.error(e)
  • app/gnomeShellDragDrop.js:148
                    console.error(
                        e, `Error opening ${uri} in GNOME Files: ${e.message}`
                    )
  • app/gnomeShellDragDrop.js:264
                console.error(e,
                    'Error reading desktop file. Cannot set shell Cursor'
                )
  • app/gnomeShellDragDrop.js:320
                    console.error(e,
                        'Error reading desktop file. Cannot launch application.'
                    )
  • app/gnomeShellDragDrop.js:343
    console.error(e)
  • app/gnomeShellDragDrop.js:211
                        console.log(
                            'Could not parse desktopFile as a desktop file,' +
                            ' cannot set shell cursor'
                        )
  • app/gnomeShellDragDrop.js:286
    console.log('Could not parse desktopFile as desktop file')
  • app/thumbnails.js:139
    console.error(`Error saving thumbnail ${e}`)
  • app/thumbnails.js:145
                    console.error(e,
                        'Error creating thumbnail with thumbnailFactory: ' +
                        `${e.message}`
                    )
  • app/thumbnails.js:174
    console.error(`Error saving thumbnail ${e}`)
  • app/thumbnails.js:192
                    console.error(e,
                        `Error while creating failed thumbnail: ${e.message}`
                    )
  • app/thumbnails.js:217
                    console.error(e,
                        `Error while generating icon image: ${e.message}`
                    )
  • app/thumbnails.js:292
                    console.error(e,
                        `Error creating pdf thumbnail pixbuf ${file.uri}`
                    )
  • app/thumbnails.js:336
                console.error(e,
                    `Error creating image thumbnail pixbuf ${file.uri}`
                )
  • app/thumbnails.js:110
                    console.log(
                        `Timeout while generating thumbnail for ${file.displayName}`
                    )
  • app/thumbnails.js:487
                console.log(
                    `Error when asking for a thumbnail for ${file.displayName}:` +
                    ` ${error.message}\n${error.stack}`)
  • app/utils/desktopIconsUtil.js:200
    console.error(e, `${commandLine} failed with ${e}`)
  • app/utils/desktopIconsUtil.js:658
    console.error(`Error determining encryption Zip file ${e}`)
  • app/utils/desktopIconsUtil.js:682
    console.error(`Error determining encryption 7z file ${e}`)
  • app/utils/desktopIconsUtil.js:865
    console.error(e)
  • app/utils/desktopIconsUtil.js:984
    console.error(`readJsonFile(${file.get_path?.() ?? '??'}):`, e)
  • app/utils/desktopIconsUtil.js:1015
    console.error('writeJsonFile: JSON.stringify failed:', e)
  • app/utils/desktopIconsUtil.js:321
    console.log(`Failed to get the list of mounts with ${e}`)
  • app/utils/desktopIconsUtil.js:349
    console.log(`Failed with ${e} while getting volume`)
  • app/utils/desktopIconsUtil.js:854
                                            console.log(
                                                'Failed to make executable ' +
                                                `.desktop File: ${error.message}`
                                            )

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 11 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/desktopMenu.js:52
    console.error(e)
  • app/desktopMenu.js:67
    console.error(e, 'Paste action failed')
  • app/desktopMenu.js:604
                console.error(
                    e, `Error opening desktop in GNOME Files: ${e.message}`
                )
  • app/desktopMenu.js:912
                    console.error(
                        e, `Failed to set template metadata ${e.message}`)
  • app/desktopMenu.js:919
    console.error(e, `Failed to create template ${e.message}`)
  • app/desktopMenu.js:945
    console.error(e, 'Error updating Clipboard')
  • app/desktopMenu.js:1169
    console.error(e, 'Error updating clipboard')
  • app/desktopMenu.js:245
                        console.log(
                            `Exception while updating desktop after pressing "F5":
                            ${e.message}\n${e.stack}`)
  • app/desktopMenu.js:408
                                        console.log(
                                            'Exception while reading clipboard:' +
                                            `${e.message}\n${e.stack}`
                                        )
  • app/desktopMenu.js:418
                            console.log(
                                `Exception while reading clipboard mimetype
                                x-special/gnome-copied-files:
                                ${e.message}\n${e.stack}`
                            )

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 10 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/dragManager.js:100
    console.error(e, 'Error making file-system links')
  • app/dragManager.js:547
    console.error(e)
  • app/dragManager.js:747
    console.error(`Cannot Copy/Move, ${uri} does not exist`)
  • app/dragManager.js:825
    console.error('Error moving files')
  • app/dragManager.js:844
    console.error('Error copying files')
  • app/dragManager.js:864
    console.error('Error making links')
  • app/dragManager.js:873
                            console.error(
                                e,
                                'Error asking choosing what to do with Files ' +
                                `${e.message}`
                            )
  • app/dragManager.js:934
    console.error(e, 'Error setting link FileInfo')
  • app/dragManager.js:938
    console.error('Error making desktop links')
  • app/dragManager.js:612
                    console.log(
                        'Exception while doing move with drag and drop and' +
                        `"Keep arranged…": ${e.message}\n${e.stack}`)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 16 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/fileItemIcon.js:169
    console.error(e, `Error getting file info: ${e.message}`)
  • app/fileItemIcon.js:261
    console.error(`Error updating after setting encryption status ${e}`)
  • app/fileItemIcon.js:300
                    console.error(
                        e, `Error opening file ${this.file.get_uri()}: ${e.message}`
                    )
  • app/fileItemIcon.js:417
    console.error(e)
  • app/fileItemIcon.js:468
                    console.error(
                        e,
                        `Exception while updating ${
                            this._getVisibleName()
                                ? this._getVisibleName()
                                : 'updating icon'
                        }: ${e.message}`)
  • app/fileItemIcon.js:510
                    console.error(
                        e,
                        'Exception while updating icon on Attribute Changed: ' +
                        `${e.message}`
                    )
  • app/fileItemIcon.js:523
                    console.error(
                        e,
                        'Exception while updating icon on Metadata Changed: ' +
                        `${e.message}`
                    )
  • app/fileItemIcon.js:541
    console.error(e)
  • app/fileItemIcon.js:609
    console.error(e)
  • app/fileItemIcon.js:632
                    console.error(
                        'Error while updating icon while setting attributes'
                    )

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 17 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/fileItemMenu.js:627
    console.error(e)
  • app/fileItemMenu.js:633
    console.error(e)
  • app/fileItemMenu.js:639
    console.error(e)
  • app/fileItemMenu.js:796
    console.error(e)
  • app/fileItemMenu.js:850
    console.error(e)
  • app/fileItemMenu.js:957
    console.error(e)
  • app/fileItemMenu.js:1107
    console.error(e)
  • app/fileItemMenu.js:1271
    console.error(e)
  • app/fileItemMenu.js:1295
    console.error(e)
  • app/fileItemMenu.js:867
    console.log('Reverting to old method of selecting')

EGO-X-003 warning

extensions should not call run_dispose in extension code

Extension code should not call `run_dispose()`.

GObject.Object.run_dispose

  • app/htmlWidgetHost.js:116
    this._webView.run_dispose()

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 15 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/htmlWidgetHostWithBackend.js:90
                console.error(
                    'HtmlWidgetHostWithBackend: failed to fetch descriptor:',
                    e
                )
  • app/htmlWidgetHostWithBackend.js:98
                console.error(
                    'HtmlWidgetHostWithBackend: no descriptor for widget',
                    inst?.widgetId ?? '<unknown>'
                )
  • app/htmlWidgetHostWithBackend.js:119
                console.error(
                    'HtmlWidgetHostWithBackend: no backend configured for widget',
                    inst?.widgetId ?? '<unknown>'
                )
  • app/htmlWidgetHostWithBackend.js:171
    console.error('BACKEND stdout loop error:', e?.message ?? e)
  • app/htmlWidgetHostWithBackend.js:189
    console.error('BACKEND stderr loop error:', e?.message ?? e)
  • app/htmlWidgetHostWithBackend.js:204
                console.error(
                    'HtmlWidgetHostWithBackend: failed to start backend:', e
                )
  • app/htmlWidgetHostWithBackend.js:234
                console.error(
                    'HtmlWidgetHostWithBackend: write backend failed:', e
                )
  • app/htmlWidgetHostWithBackend.js:259
    console.error('BACKEND stream read error:', label, e?.message ?? e)
  • app/htmlWidgetHostWithBackend.js:269
    console.error('BACKEND stdout JSON parse error:', e?.message ?? e)
  • app/htmlWidgetHostWithBackend.js:536
                    console.error(
                        'BACKEND STDERR:',
                        inst?.instanceId ?? '<unknown>',
                        line.trim()
                    )
  • dingManager.js:143
    console.error('Gtk4 DING extension requires a Wayland session')
  • dingManager.js:153
    console.error(e)
  • dingManager.js:271
    console.error(e)
  • dingManager.js:592
    console.error(e)
  • dingManager.js:634
                    console.error(
                        e, `Error while trying to launch DING process: ${e.message}`
                    )
  • dingManager.js:772
    console.error(e)
  • dingManager.js:809
    console.error(e, `${this._processID}_Error`)
  • dingManager.js:294
    console.log('Adw-DING enabled.')
  • dingManager.js:361
    console.log('Adw-DING disabled.')
  • dingManager.js:375
    console.log(`${name} DBus Name Acquired`)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 25 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/preferences.js:697
    console.error(`Failed to load CSS override: ${e}`)
  • app/preferences.js:796
    console.error(e)
  • app/preferences.js:804
    console.error(e)
  • app/preferences.js:849
    console.error(e)
  • app/preferences.js:853
    console.error(e)
  • app/preferences.js:46
    console.log('System supports accent colors')
  • app/preferences.js:50
    console.log('System does not support accent colors')
  • app/preferences.js:158
    console.log('schemaObj does not exist!')
  • app/preferences.js:159
    console.log('Current extension path:', this._extensionPath)
  • app/preferences.js:160
    console.log('Current schemaFile:', schemaFile.get_path())

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 8 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/templatesScriptsManager.js:99
    console.error(e)
  • app/templatesScriptsManager.js:118
    console.error(e)
  • app/templatesScriptsManager.js:56
                                console.log(
                                    'Exception while updating entries in ' +
                                    `monitor: ${e.message}\n${e.stack}`
                                )
  • app/templatesScriptsManager.js:67
                    console.log(
                        'Exception while updating entries: ' +
                        `${e.message}\n${e.stack}`
                    )
  • app/templatesScriptsManager.js:154
                    console.log(
                        'Limiting the number of folders monitored in ' +
                        'templates/scripts...'
                    )
  • app/templatesScriptsManager.js:162
                    console.log(
                        'Limiting submenu depth of folders monitored' +
                        ' in templates/scripts...'
                    )
  • app/templatesScriptsManager.js:262
    console.log('Truncating menu entries templates/scripts submenu')
  • app/templatesScriptsManager.js:273
                    console.warn(
                        'Folder Symlink in monitored templates/scripts folder...\n',
                        'This can lead to unlimited recursion.'
                    )
  • dependencies/gi.js:18
    console.error(e)
  • dependencies/gi.js:26
    console.error(`Install Poppler for proper fallback pdf thumbnailing \n ${e}`)
  • dependencies/gi.js:29
    console.error(`Install Cairo for proper fallback pdf thumbnailing \n ${e}`)
  • dependencies/gi.js:46
    console.error('DesktopAppInfo is not available on this system!')
  • dependencies/gi.js:10
    console.log('GLibUnix not found.')
  • dependencies/gi.js:35
    console.log('GioUnix not found, falling back to Gio...')
  • dependencies/gi.js:51
    console.log(`WebKit GI not found; desktop widgets disabled\n${e}`)
  • dependencies/gi.js:58
    console.log(`Soup GI not found; desktop widgets disabled\n${e}`)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 46 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/utils/dbusUtils.js:106
    console.error(e)
  • app/utils/dbusUtils.js:980
                            console.error(e,
                                'Impossible to determine the parent window'
                            )
  • app/utils/dbusUtils.js:1021
    console.error(e)
  • app/utils/dbusUtils.js:1049
    console.error(e)
  • app/utils/dbusUtils.js:1077
    console.error(e)
  • app/utils/dbusUtils.js:1104
    console.error(e)
  • app/utils/dbusUtils.js:1135
    console.error(e)
  • app/utils/dbusUtils.js:1166
    console.error(e)
  • app/utils/dbusUtils.js:1191
    console.error(e)
  • app/utils/dbusUtils.js:1217
    console.error(e)

EGO-X-004 warning

extensions should avoid synchronous file IO in shell code

Shell code should avoid synchronous file IO APIs like `GLib.file_get_contents()` and `Gio.File.load_contents()`.

File Operations

  • app/utils/desktopFolderUtils.js:137
    GLib.file_get_contents(userDirsGioFile.get_path())
  • app/utils/desktopFolderUtils.js:174
    GLib.file_get_contents(systemDirsGioFile.get_path())
  • app/utils/desktopFolderUtils.js:264
    GLib.file_get_contents(userDirsGioFile.get_path())

EGO-X-002 warning

extensions should not use synchronous subprocess APIs in shell code

Shell code should avoid synchronous subprocess APIs like `GLib.spawn_command_line_sync()` and `GLib.spawn_sync()`.

Complete Examples

  • app/utils/desktopIconsUtil.js:646
    GLib.spawn_command_line_sync(command)
  • app/utils/desktopIconsUtil.js:674
    GLib.spawn_command_line_sync(command)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 24 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/widgetManager.js:53
    console.error('WidgetManager: failed to clone widget config:', e)
  • app/widgetManager.js:294
    console.error('createInstanceForWidget: missing widgetId')
  • app/widgetManager.js:299
    console.error('createInstanceForWidget: widgetRegistry missing')
  • app/widgetManager.js:308
    console.error(`Descriptor load failed for ${widgetId}:`, e)
  • app/widgetManager.js:330
                console.error(
                    `createInstanceForWidget: invalid monitorIndex ${monitorIndex}`
                )
  • app/widgetManager.js:782
    console.error('WidgetManager: listAvailableWidgets failed:', e)
  • app/widgetManager.js:1001
                        console.error(
                            'WidgetManager loadState failed for instance:',
                            {
                                instanceId: instData.instanceId,
                                widgetId: instData.widgetId,
                                monitorIndex: instDat
  • app/widgetManager.js:1030
    console.error('WidgetManager loadState failed:', e)
  • app/widgetManager.js:1428
                console.error(
                    `WidgetManager.createInstance:
                        unknown monitorIndex ${monitorIndex}`
                )
  • app/widgetManager.js:1492
                    console.error(
                        `WidgetManager: grid for monitorIndex ${monitorIndex
                        } is missing widgetContainer`
                    )

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 12 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/widgetRegistry.js:35
    console.error('WidgetRegistry: failed to clone JSON object:', e)
  • app/widgetRegistry.js:64
    console.error('WidgetRegistry.preload():', e)
  • app/widgetRegistry.js:160
                console.error(
                    'WidgetRegistry: getHtmlEntryFile failed for',
                    id,
                    e
                )
  • app/widgetRegistry.js:188
                console.error(
                    'WidgetRegistry: application-id not available; ' +
                    'widget paths will not be resolved.'
                )
  • app/widgetRegistry.js:289
                console.error(
                    'WidgetRegistry: enumerate_children failed for',
                    root.get_path?.(),
                    e
                )
  • app/widgetRegistry.js:432
                console.error(
                    'WidgetRegistry: error scanning root',
                    root.get_path?.(),
                    e
                )
  • app/widgetRegistry.js:441
                    console.error(
                        'WidgetRegistry: error closing enumerator',
                        e
                    )
  • app/widgetRegistry.js:562
                console.error(
                    'WidgetRegistry: backend argv missing/invalid for widget',
                    desc?.id ?? '<unknown>'
                )
  • app/widgetRegistry.js:202
    console.warn('WidgetRegistry: failed to resolve user root:', e)
  • app/widgetRegistry.js:217
    console.warn('WidgetRegistry: failed to build system roots:', e)

EGO-A-004 warning

extension files should not contain excessive ungated console logging

File contains 34 ungated console.log/warn/error calls (threshold: 5).

No excessive logging

  • app/widgetWebContext.js:418
                console.error(
                    'WebWidgetContext: failed to register dingWidget handler:',
                    e
                )
  • app/widgetWebContext.js:462
                console.error(
                    'WebWidgetContext: failed to install WIDGET_API user script:',
                    e
                )
  • app/widgetWebContext.js:541
    console.error('WebWidgetContext: failed to read widget message:', e)
  • app/widgetWebContext.js:558
                console.error(
                    'WebWidgetContext: failed to convert widget message to string:',
                    e
                )
  • app/widgetWebContext.js:582
    console.error('WebWidgetContext: invalid widget JSON payload:', e)
  • app/widgetWebContext.js:867
    console.error('Failed to open external link:', rawUrl, error)
  • app/widgetWebContext.js:1265
    console.error(`No description for ${widgetId}`, e)
  • app/widgetWebContext.js:1285
                console.error(
                    'WebWidgetContext: unhandled error in ding-widget handler:',
                    e
                )
  • app/widgetWebContext.js:1307
    console.error('WebWidgetContext: URI request without URI:', e)
  • app/widgetWebContext.js:1313
    console.error('WebWidgetContext: URI request had no URI')

EGO-I-002 error

Gtk, Gdk and Adw must not be imported in shell process files

GTK library `Adw` must not be imported in extension process files.

Do not import GTK libraries in GNOME Shell

  • dependencies/gi.js:1
    import Adw from 'gi://Adw';

EGO-I-002 error

Gtk, Gdk and Adw must not be imported in shell process files

GTK library `Gdk` must not be imported in extension process files.

Do not import GTK libraries in GNOME Shell

  • dependencies/gi.js:2
    import Gdk from 'gi://Gdk?version=4.0';

EGO-I-002 error

Gtk, Gdk and Adw must not be imported in shell process files

GTK library `Gtk` must not be imported in extension process files.

Do not import GTK libraries in GNOME Shell

  • dependencies/gi.js:22
    import Gtk from 'gi://Gtk';

EGO-P-007 warning

JavaScript files should be reachable from extension.js or prefs.js

Some JavaScript files are not reachable from `extension.js` or `prefs.js` imports.

Don't include unnecessary files

  • app/adw-ding.js

EGO-L-005 warning

owned object references should be released in disable()

Owned references that are cleaned up in `disable()` should also be released with `null` or `undefined`.

Destroy all objects

  • app/preferences.js:56
    this.gtkSettings = new Gio.Settings({settings_schema: schemaGtk})
  • app/preferences.js:91
                this.mutterSettings =
                    new Gio.Settings({settings_schema: schemaMutter})
  • app/preferences.js:82
                this.nautilusCompression =
                    new Gio.Settings({settings_schema: compressionSchema})
  • app/preferences.js:67
                this.nautilusSettings =
                    new Gio.Settings({settings_schema: schemaObj})
  • app/preferences.js:117
                this.schemaGnomeThemeSettings =
                    new Gio.Settings({settings_schema: schemaGnomeSettings})
  • app/preferences.js:100
                this.schemaTerminalSettings =
                    new Gio.Settings({settings_schema: schemaTerminalSettings})
  • app/windowManager.js:84
            this._dbusGeometryIface =
                    Gio.DBusExportedObject.wrapJSObject(signalXml, this)

EGO-L-003 warning

signals connected by extension should be disconnected in disable()

Signals assigned in `enable()` are missing matching disconnect calls in `disable()` or its helper methods.

Disconnect all signals

  • app/adwPreferencesWindow.js:191
            button.connect('clicked', () => {
                this.reloadCSS();
            })
  • app/adwPreferencesWindow.js:176
    this.cssOverrideButton.connect('activated', this.openUserCssOverrideFile.bind(this))
  • app/adwPreferencesWindow.js:257
    this.shortcutButton.connect('activated', this.showShortcuts.bind(this))
  • app/appChooser.js:146
            this.appChooserDialog.connect('close', () => {
                this.appChooserDialog.response(Gtk.ResponseType.CANCEL);
            })
  • app/appChooser.js:150
            this.appChooserDialog.connect('response', (actor, retval) => {
                if (retval === Gtk.ResponseType.OK) {
                    this._checkUpdateDefaultAppForMimeType();
                    this.applicationSelectionComplete(this.selectedAppInfo);
                } else {
                    this.applic
  • app/appChooser.js:129
            this.appChooserWidget.connect(
                'application-activated',
                this._onApplicationActivated.bind(this)
            )
  • app/appChooser.js:134
            this.appChooserWidget.connect(
                'application-selected',
                this._onApplicationSelected.bind(this)
            )
  • app/askRenamePopup.js:80
            this._buttonId =
                this._button.connect(
                    'clicked',
                    this._do_rename.bind(this)
                )
  • app/askRenamePopup.js:122
            this._focusTrackerID =
                this._focusTracker.connect('leave', this.close.bind(this))
  • app/askRenamePopup.js:125
            this._popoverId =
                this._popover.connect('closed', this.close.bind(this))
  • app/askRenamePopup.js:95
            this._textAreaActivateId =
                this._textArea.connect('activate', this._do_rename.bind(this))
  • app/askRenamePopup.js:86
            this._textAreaChangedId =
                this._textArea.connect(
                    'changed',
                    () => {
                        this._validate()
                        .catch(e => console.error(e));
                    }
                )
  • app/autoAr.js:41
            this._progressWindow.connect('close-request', () => {
                return true;
            })
  • app/autoAr.js:296
            this._cancelButton.connect('clicked', () => {
                if (this._buttonPromiseAccept) {
                    this._buttonPromiseAccept(false);
                    return;
                }
                this._cancellable.cancel();
            })
  • app/autoAr.js:334
    this._passEntry.connect('activate', passOKfunc)
  • app/autoAr.js:331
            this._passEntry.connect('icon-release', () => {
                this._passEntry.visibility = !this._passEntry.visibility;
            })
  • app/autoAr.js:313
    this._passOkButton.connect('clicked', passOKfunc)
  • app/autoAr.js:641
            this._dialog.connect('response', (dialog, id) => {
                if (id === Gtk.ResponseType.ACCEPT) {
                    const data =
                        this._desktopManager
                        .autoAr.getFormatAndFilterForExtension(
                            this._compressOptions[this._selectedT
  • app/autoAr.js:629
            this._extensionDropdown.connect('clicked', () => {
                this._extensionPopoverContainer.show();
                this._extensionPopover.popup();
                for (let index in this._compressOptions) {
                    const data = this._compressOptions[index];
                    data.selected_i
  • app/autoAr.js:639
    this._nameEntry.connect('activate', () => this._entryActivated())
  • app/autoAr.js:637
    this._nameEntry.connect('changed', () => this._updateStatus())
  • app/autoAr.js:640
    this._passEntry.connect('activate', () => this._entryActivated())
  • app/autoAr.js:638
    this._passEntry.connect('changed', () => this._updateStatus())
  • app/desktopFolderMonitor.js:216
            this._volumeMonitor.connect(
                'mount-added',
                () => {
                    this.onMountAdded();
                }
            )
  • app/desktopFolderMonitor.js:223
            this._volumeMonitor.connect(
                'mount-removed',
                () => {
                    GLib.timeout_add(
                        GLib.PRIORITY_DEFAULT,
                        500,
                        () => {
                            this.onMountRemoved();
                            return GLib.S
  • app/desktopFolderMonitor.js:63
            changeDesktop.connect('activate', () => {
                this.changeDesktop();
            })
  • app/desktopFolderMonitor.js:72
            this.restoreDefaultDesktopAction.connect('activate', () => {
                this.restoreDefaultDesktop();
            })
  • app/desktopFolderMonitor.js:202
            cancellable.connect(
                () => {
                    this._monitorDesktopDir.disconnect(monitorID);
                    this._monitorDesktopDir.cancel();
                    this._monitorDesktopDir = null;
                    this.monitorDesktopCancellable = null;
                }
            )
  • app/desktopGrid.js:112
            this._window.connect(
                'close-request',
                () => {
                    if (this._destroying)
                        return false;
    
                    if (this._asDesktop) {
                        // Do not destroy window when closing if the instance
                        // is working a
  • app/desktopGrid.js:90
                this._window.connect('map', () => {
                    if (!this._resolveMapped)
                        return;
                    this._resolveMapped(true);
                    this._resolveMapped = null;
                    // Maximize however creates an error where the window can
                    // be
  • app/desktopGrid.js:108
            this._window.connect('notify::css_classes', () => {
                this._window.set_css_classes(['background']);
            })
  • app/desktopGrid.js:1438
            this._buttonClick.connect('pressed', (actor, nPress, x, y) => {
                this._doGesturePress(actor, nPress, x, y);
            })
  • app/desktopGrid.js:1442
            this._buttonClick.connect('released', (actor, nPress, x, y) => {
                if (this._longHandled)
                    this._longHandled = false;
    
                this._doGestureRelease(actor, nPress, x, y, this);
            })
  • app/desktopGrid.js:1434
            this._buttonLongClick.connect('cancelled', _actor => {
                this._longHandled = false;
            })
  • app/desktopGrid.js:1429
            this._buttonLongClick.connect('pressed', (actor, x, y) => {
                this._longHandled = true;
                this._doGestureLongPress(actor, x, y);
            })
  • app/desktopGrid.js:1386
            this._eventKey.connect(
                'key-pressed',
                this._onKeyPress.bind(this)
            )
  • app/desktopGrid.js:1391
            this._eventKeyState.connect(
                'key-pressed',
                this._onModifierUpdate.bind(this)
            )
  • app/desktopGrid.js:1396
            this._eventKeyState.connect(
                'key-released',
                this._onModifierClear.bind(this)
            )
  • app/desktopGrid.js:1405
            this._eventMotion.connect(
                'motion',
                (actor, x, y) => {
                    if (!this._dragManager.rubberBand)
                        return false;
    
                    const [X, Y] = this.coordinatesLocalToGlobal(x, y);
                    this._dragManager.onMotion(X, Y);
            
  • app/desktopGrid.js:1580
            this.gridDropController.connect(
                'accept',
                (actor, drop) => {
                    if (drop.get_formats().match(desktopAcceptFormats))
                        return true;
                    else
                        return false;
                }
            )
  • app/desktopGrid.js:1590
            this.gridDropController.connect(
                'drag-enter',
                (actor, drop) => {
                    this.localDrag = true;
                    drop.status(
                        Gdk.DragAction.COPY |
                            Gdk.DragAction.MOVE |
                            Gdk.DragAction.LINK,
     
  • app/desktopGrid.js:1672
            this.gridDropController.connect('drag-leave', () => {
                this.localDrag = false;
                this._receiveLeave();
            })
  • app/desktopGrid.js:1605
            this.gridDropController.connect(
                'drag-motion',
                (actor, drop, x, y) => {
                    let desktopDropZone = false;
                    let fileItemDropZone = false;
                    const fileItem = this._fileAt(x, y);
                    const [X, Y] = this.coordinatesLoca
  • app/desktopGrid.js:1677
            this.gridDropController.connect('drop', (actor, drop, x, y) => {
                const event = {
                    'parentWindow': this._window,
                    'timestamp': Gdk.CURRENT_TIME,
                };
    
                let desktopDropZone = false;
                let fileItemDropZone = false;
           
  • app/desktopGrid.js:1820
            this.gridDropControllerMotion.connect(
                'motion',
                (actor, x, y) => {
                    if (!this.gridDropControllerMotion.is_pointer) {
                        const fileItem = this._fileAt(x, y);
                        const [X, Y] = this.coordinatesLocalToGlobal(x, y);
          
  • app/desktopGrid.js:1945
            widgetDragController.connect('drag-begin', () => {
                this._dragManager.onReleaseButton(this);
                this._dragManager.onDragBegin(clickItem);
            })
  • app/desktopGrid.js:1950
            widgetDragController.connect(
                'drag-cancel',
                async (actor, drag, reason) => {
                    if (reason === Gdk.DragCancelReason.NO_TARGET ||
                        reason === Gdk.DragCancelReason.ERROR) {
                        const gnomedropDetected =
                      
  • app/desktopGrid.js:1970
            widgetDragController.connect('drag-end', () => {
                this._dragManager.onDragEnd();
                this._dragManager.selected(clickItem, this.Enums.Selection.RELEASE);
            })
  • app/desktopGrid.js:1914
            widgetDragController.connect(
                'prepare',
                // eslint-disable-next-line consistent-return
                (actor, x, y) => {
                    const draggedItem = this._fileAt(x, y);
    
                    if (draggedItem && !this._dragManager.rubberBand) {
                        click
  • app/desktopGrid.js:3129
            this._offsetAnim.connect('done', () => {
                this._setLiveOffset(-this._tweenDelta.dx, -this._tweenDelta.dy);
                // Ensure we end exactly at identity scale
                if (this._moveAway) {
                    this._setLiveTransform(
                        1.0, this._tweenDelta.piv
  • app/desktopMenu.js:480
            fileOperationsManager.connect('changed-status',
                (actor, available) => {
                    if (available)
                        this._syncUndoRedo();
                    else
                        this._syncUndoRedo(true);
                }
            )
  • app/desktopMenu.js:193
            arrangeByDescendingName.connect(
                'activate',
                () => this._mainApp.activate_action(
                    'arrangeaction',
                    new GLib.Variant('s', 'DESCENDINGNAME')
                )
            )
  • app/desktopMenu.js:214
            arrangeByKind.connect(
                'activate',
                () => this._mainApp.activate_action(
                    'arrangeaction',
                    new GLib.Variant('s', 'KIND')
                )
            )
  • app/desktopMenu.js:204
            arrangeByModifiedTime.connect(
                'activate',
                () => this._mainApp.activate_action(
                    'arrangeaction',
                    new GLib.Variant('s', 'MODIFIEDTIME')
                )
            )
  • app/desktopMenu.js:182
            arrangeByName.connect(
                'activate',
                () => this._mainApp.activate_action(
                    'arrangeaction',
                    new GLib.Variant('s', 'NAME')
                )
            )
  • app/desktopMenu.js:224
            arrangeBySize.connect(
                'activate',
                () => this._mainApp.activate_action(
                    'arrangeaction',
                    new GLib.Variant('s', 'SIZE')
                )
            )
  • app/desktopMenu.js:110
            changeBackGround.connect(
                'activate',
                () => {
                    const desktopFile =
                        DesktopAppInfo.new('gnome-background-panel.desktop');
                    const context =
                        Gdk.Display.get_default().get_app_launch_context();
            
  • app/desktopMenu.js:140
            changeDesktopIconSettings.connect(
                'activate',
                this._showPreferences.bind(this)
            )
  • app/desktopMenu.js:125
            changeDisplaySettings.connect(
                'activate',
                () => {
                    const desktopFile =
                        DesktopAppInfo.new('gnome-display-panel.desktop');
                    const context =
                        Gdk.Display.get_default().get_app_launch_context();
          
  • app/desktopMenu.js:313
            chooseIconDown.connect('activate', () => {
                this._selectFileItemInDirection(Gdk.KEY_Down);
            })
  • app/desktopMenu.js:295
            chooseIconLeft.connect('activate', () => {
                this._selectFileItemInDirection(Gdk.KEY_Left);
            })
  • app/desktopMenu.js:301
            chooseIconRight.connect('activate', () => {
                this._selectFileItemInDirection(Gdk.KEY_Right);
            })
  • app/desktopMenu.js:307
            chooseIconUp.connect('activate', () => {
                this._selectFileItemInDirection(Gdk.KEY_Up);
            })
  • app/desktopMenu.js:148
            cleanUpIconsAction.connect(
                'activate',
                () => this._desktopManager.sortAllFilesFromGridsByPosition()
            )
  • app/desktopMenu.js:335
            createDesktopShortcut.connect('activate', (action, parameter) => {
                this._createDesktopShortcut(parameter.recursiveUnpack());
            })
  • app/desktopMenu.js:326
            displayShellBackgroundMenu.connect('activate', () => {
                this._DBusUtils.RemoteExtensionControl.showShellBackgroundMenu();
            })
  • app/desktopMenu.js:57
            this.doPasteSimpleAction.connect(
                'activate',
                async () => {
                    try {
                        if (!(this._desktopManager.popupmenu ||
                            this._desktopManager.fileItemMenu.popupmenu))
                            await this._updateClipboard().ca
  • app/desktopMenu.js:81
            this.doRedoSimpleAction.connect(
                'activate',
                () => this._doRedo()
            )
  • app/desktopMenu.js:74
            this.doUndoSimpleAction.connect(
                'activate',
                () => this._doUndo()
            )
  • app/desktopMenu.js:234
            findFilesAction.connect(
                'activate',
                () => this._desktopManager.findFiles(null)
            )
  • app/desktopMenu.js:319
            menuKeyPressed.connect('activate', () => {
                this._menuKeyPressed();
            })
  • app/desktopMenu.js:342
            newDocument.connect('activate', (action, parameter) => {
                this._newDocument(parameter.deep_unpack());
            })
  • app/desktopMenu.js:51
            newFolder.connect('activate', () => {
                this._desktopManager.doNewFolder().catch(e => console.error(e));
            })
  • app/desktopMenu.js:103
            openDesktopInTerminal.connect(
                'activate',
                this._onOpenTerminalClicked.bind(this)
            )
  • app/desktopMenu.js:276
            previewAction.connect('activate', () => {
                if (this._desktopManager.popupmenu ||
                    this._desktopManager.fileItemMenu.popupmenu ||
                    !this.activeFileItem)
                    return;
                const RemoteOperation =
                    this._DBusUtils.RemoteF
  • app/desktopMenu.js:176
            radioArrangeAction.connect('change-state',
                this._syncArrangeOrder.bind(this))
  • app/desktopMenu.js:88
            selectAll.connect(
                'activate',
                () => this._selectAll()
            )
  • app/desktopMenu.js:96
            showDesktopInFiles.connect(
                'activate',
                () => this._onOpenDesktopInFilesClicked().catch(e => logError(e))
            )
  • app/desktopMenu.js:255
            showHideHiddenFiles.connect(
                'activate',
                () => {
                    this._Prefs.gtkSettings.set_boolean('show-hidden',
                        !this._Prefs.showHidden);
                }
            )
  • app/desktopMenu.js:289
            toggleKeyboardSelection.connect('activate', () => {
                this._toggleKeyboardSelection();
            })
  • app/desktopMenu.js:351
            toggleVisibility.connect('activate', () => {
                this._windowManager.toggleVisibility();
            })
  • app/desktopMenu.js:265
            unselectAll.connect(
                'activate',
                () => {
                    this._desktopManager.unselectAll();
                    if (this.searchString)
                        this.searchString = null;
                }
            )
  • app/desktopMenu.js:241
            updateDesktop.connect(
                'activate',
                async () => {
                    await this._desktopManager.reLoadDesktop().catch(e => {
                        console.log(
                            `Exception while updating desktop after pressing "F5":
                            ${e.message
  • app/fileItemMenu.js:581
            this._docopy.connect(
                'activate',
                this._doCopy.bind(this)
            )
  • app/fileItemMenu.js:574
            this._docut.connect(
                'activate',
                this._doCut.bind(this)
            )
  • app/fileItemMenu.js:621
            allowdisallowlaunching.connect('activate', () => {
                if (!this.activeFileItem)
                    return;
    
                this.activeFileItem
                    .onAllowDisallowLaunchingClicked()
                    .catch(e => console.error(e));
            })
  • app/fileItemMenu.js:720
            bulkCopy.connect(
                'activate',
                this._bulkCopy.bind(this)
            )
  • app/fileItemMenu.js:727
            bulkMove.connect(
                'activate',
                this._bulkMove.bind(this)
            )
  • app/fileItemMenu.js:676
            compressfiles.connect(
                'activate',
                this._doCompressFilesFromSelection.bind(this, null)
            )
  • app/fileItemMenu.js:605
            this.deletePermanantly.connect(
                'activate',
                () => this.doDeletePermanently()
            )
  • app/fileItemMenu.js:745
            desktopAction.connect(
                'activate',
                (_action, parameter) => {
                    const [path, actionName, action] = parameter.deepUnpack();
                    this._desktopFileAction(path, actionName, action);
                }
            )
  • app/fileItemMenu.js:553
            doopenwith.connect('activate', () => {
                this._doOpenWith().catch(e => logError(e));
            })
  • app/fileItemMenu.js:588
            dorename.connect('activate', () => {
                this._desktopManager
                    .doRename(this.activeFileItem, false)
                    .catch(e => logError(e));
            })
  • app/fileItemMenu.js:632
            eject.connect('activate', () => {
                this.activeFileItem.eject().catch(e => console.error(e));
            })
  • app/fileItemMenu.js:613
            emptytrash.connect(
                'activate',
                () => this.doEmptyTrash()
            )
  • app/fileItemMenu.js:644
            extractautoar.connect(
                'activate',
                () => {
                    this._desktopManager.getCurrentSelection()
                    ?.forEach(
                        f => this._desktopManager.autoAr.extractFile(f.fileName));
                }
            )
  • app/fileItemMenu.js:655
            extracthere.connect(
                'activate',
                this._extractFileFromSelection.bind(this, true)
            )
  • app/fileItemMenu.js:662
            extractto.connect(
                'activate',
                this._extractFileFromSelection.bind(this, false)
            )
  • app/fileItemMenu.js:559
            graphicslaunch.connect('activate', () => {
                if (!this.activeFileItem)
                    return;
                this.activeFileItem._doDiscreteGpu();
            })
  • app/fileItemMenu.js:712
            makeLinks.connect(
                'activate',
                this._makeLinks.bind(this)
            )
  • app/fileItemMenu.js:596
            this.moveToTrash.connect(
                'activate',
                () => this.doTrash()
            )
  • app/fileItemMenu.js:684
            newfolderfromselection.connect(
                'activate',
                this._newFolderFromSelection.bind(this)
            )
  • app/fileItemMenu.js:735
            onScriptClicked.connect(
                'activate',
                (_action, parameter) => {
                    this._onScriptClicked(parameter.unpack());
                }
            )
  • app/fileItemMenu.js:519
            openMultipleFileAction.connect(
                'activate',
                this._doMultiOpen.bind(this)
            )
  • app/fileItemMenu.js:527
            openOneFileAction.connect(
                'activate',
                () => {
                    if (this.activeFileItem) {
                        if (this.activeFileItem.isStackMarker) {
                            this._onToggleStackUnstackThisTypeClicked(
                                this.activeFileItem.at
  • app/fileItemMenu.js:705
            openinterminal.connect(
                'activate',
                this._openInTerminal.bind(this)
            )
  • app/fileItemMenu.js:691
            properties.connect(
                'activate',
                this._onPropertiesClicked.bind(this)
            )
  • app/fileItemMenu.js:567
            runasaprogram.connect(
                'activate',
                this._runExecutableScript.bind(this)
            )
  • app/fileItemMenu.js:669
            sendto.connect(
                'activate',
                this._mailFilesFromSelection.bind(this, null)
            )
  • app/fileItemMenu.js:698
            showinfiles.connect(
                'activate',
                this._onShowInFilesClicked.bind(this)
            )
  • app/fileItemMenu.js:545
            stackunstack.connect(
                'activate',
                (_action, paramenter) => {
                    this._onToggleStackUnstackThisTypeClicked(paramenter.unpack());
                })
  • app/fileItemMenu.js:638
            unmount.connect('activate', () => {
                this.activeFileItem.unmount().catch(e => console.error(e));
            })
  • app/shortcutManager.js:463
            this._userShortcutMonitor = this._desktopSettings.connect(
                'changed',
                (obj, key) => {
                    if (key === 'shortcutoverrides')
                        this._refreshUserShortcuts();
                }
            )
  • app/shortcutManager.js:434
            this._mainApp.connect(
                'action-added',
                (_app, name) => this._setAccel(name)
            )
  • app/shortcutManager.js:438
            this._mainApp.connect(
                'action-enabled-changed',
                (_app, name, _enabled) => this._setAccel(name)
            )
  • app/shortcutManager.js:560
            showShortcutViewer.connect('activate', () => {
                this._showShortcutViewer();
            })
  • app/shortcutManager.js:574
            textEntryAccelsTurnOff.connect('activate', () => {
                this._textEntryAccelsTurnOff();
            })
  • app/shortcutManager.js:567
            textEntryAccelsTurnOn.connect('activate', () => {
                this._textEntryAccelsTurnOn();
            })
  • app/showErrorPopup.js:75
    this._dialog.connect('response', this._callback.bind(this))
  • app/symLinkIcon.js:124
                    this._symlinkFileMonitorId = this._symlinkFileMonitor.connect(
                        'changed',
                        this._updateSymlinkIcon.bind(this)
                    )
  • app/templatesScriptsManager.js:50
                this._monitorDir.connect(
                    'changed',
                    () => {
                        this.updateEntries()
                        .catch(
                            e => {
                                console.log(
                                    'Exception while updating entries in '
  • app/utils/dbusUtils.js:86
            dbusManager.connect(
                inSystemBus
                    ? 'changed-availability-system'
                    : 'changed-availability-local',
                () => {
                    this._makeProxy(makeAsync);
                }
            )
  • app/utils/dbusUtils.js:695
            this.archiveConnectionId =
                this.gnomeArchiveManager.connect(
                    'changed-status',
                    (_actor, available) => {
                        if (available) {
                            // wait a second to ensure that everything has settled
                            GLib
  • app/utils/dbusUtils.js:1492
            this.SwitcherooControl.connect('changed-status', (obj, newStatus) => {
                this.discreteGpuAvailable = newStatus;
            })
  • app/utils/gsConnect.js:36
            this.GsConnectManager.connect('changed-status', () => {
                GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
                    this._startGsConnectService();
                    return false;
                });
            })
  • app/utils/gsConnect.js:158
            sendfiles.connect('activate', (action, parameter) => {
                let device = parameter.recursiveUnpack();
                this._send_files(device);
            })
  • app/utils/gsConnect.js:56
                this.signalID =
                    this.gsConnectProxy.connect(
                        'g-signal',
                        this._on_g_signal.bind(this)
                    )
  • app/widgetManager.js:255
            this._dbusScreenSaverActiveChangedId =
                this._desktopManager.DBusUtils.connect(
                    'screen-saver-active-changed',
                    (_dbusUtils, active) => {
                        if (active)
                            return;
    
                        this.schedulePinnedWindowWa
  • app/widgetManager.js:2787
                addButton.connect('clicked', async () => {
                    if (creationInProgress)
                        return;
    
                    const row = list.get_selected_row();
                    if (!row || !row._widgetId) {
                        window.close();
                        resolve(null);
          
  • app/widgetManager.js:2932
            addWidgetAction.connect('activate', () => {
                const parentWindow =
                    this._desktopManager.getDialogParentWindow();
                if (!parentWindow)
                    return;
    
                const monitorIndex = this.getMonitorIndexForWindow(parentWindow);
    
                // Ens
  • app/widgetManager.js:2783
                cancelButton.connect('clicked', () => {
                    window.close();
                })
  • app/widgetManager.js:2977
    closeWidget.connect('activate', this.deleteSelectedInstance.bind(this))
  • app/widgetManager.js:2817
                list.connect('row-activated', () => {
                    addButton.activate();
                })
  • app/widgetManager.js:2949
            showGridAction.connect('activate', () => {
                const parentWindow = this._desktopManager.getDialogParentWindow();
                if (!parentWindow)
                    return;
    
                const parentSurfaceWindow = parentWindow;
                const monitorIndex = this.getMonitorIndexForWind
  • app/widgetManager.js:2984
            updatePinnedWindowPosition.connect('activate', (_action, parameter) => {
                if (!parameter)
                    return;
    
                const [instanceId, x, y] = parameter.deepUnpack();
                this.updatePinnedWindowPosition(instanceId, x, y);
            })
  • app/widgetManager.js:2822
                window.connect('close-request', () => {
                    if (!creationInProgress)
                        resolve(null);
    
                    GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
                        this.restoreWidgetLayerFocus(monitorIndex);
                        return GLib.SOURCE_RE
  • app/widgetWindow.js:421
            this._dragGesture.connect(
                'drag-begin',
                this._onOverlayDragBegin.bind(this)
            )
  • app/widgetWindow.js:336
            this._hoverController.connect('enter', () => {
                this._overlay.add_css_class('pointer-inside');
                this._showControlsStrip();
            })
  • app/widgetWindow.js:340
            this._hoverController.connect('leave', () => {
                this._overlay.remove_css_class('pointer-inside');
                this._hideControlsStrip();
            })
  • app/windowManager.js:541
            action.connect('activate', () => {
                this.toggleWidgetLayers();
            })
  • app/windowManager.js:549
            lowerAction.connect('activate', () => {
                this.lowerWidgetLayers();
            })
  • app/windowManager.js:557
            raiseAction.connect('activate', () => {
                this.raiseWidgetLayers();
            })
  • app/windowManager.js:62
            updateGridWindows.connect('activate', (action, parameter) => {
                this.updateGridWindows(parameter.recursiveUnpack())
                .catch(e => logError(e));
            })
  • windowTypeManager.js:534
            this._restackedBottomID = global.display.connect('restacked',
                this._syncToBottomOfStack.bind(this)
            )
  • windowTypeManager.js:585
            this._restackedTopID = global.display.connect('restacked',
                this._syncToTopOfStack.bind(this)
            )
  • windowTypeManager.js:77
            this._titleID = this._window.connect('notify::title', () => {
                this.refreshProperties();
            })
  • windowTypeManager.js:464
                this._window.connect('position-changed', () => {
                    this._emitWindowPositionUpdate();
                })

EGO-L-004 warning

main loop sources should be removed in disable()

Main loop sources assigned in `enable()` are missing matching removals in `disable()` or its helper methods.

Remove main loop sources

  • app/desktopFolderMonitor.js:226
                    GLib.timeout_add(
                        GLib.PRIORITY_DEFAULT,
                        500,
                        () => {
                            this.onMountRemoved();
                            return GLib.SOURCE_REMOVE;
                        }
                    )
  • app/desktopGrid.js:2257
            this.directoryOpenTimer =
                GLib.timeout_add(
                    GLib.PRIORITY_DEFAULT,
                    this.Enums.DND_HOVER_TIMEOUT,
                    () => {
                        const context =
                            Gdk.Display.get_default()
                            .get_app_launch_c
  • app/utils/dbusUtils.js:448
            this._signalTimerID =
                GLib.timeout_add(
                    GLib.PRIORITY_DEFAULT,
                    1000,
                    () => {
                        this._signalTimerID = 0;
                        this._updateAllAvailabilities();
    
                        if (this._pendingLocalSignal)
          
  • app/utils/dbusUtils.js:701
                            GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
                                try {
                                    this._getExtractionSupportedTypes();
                                } catch (e) {}
                                return false;
                            })
  • app/utils/gsConnect.js:37
                GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, () => {
                    this._startGsConnectService();
                    return false;
                })
  • app/widgetManager.js:243
            this._pendingPinnedWindowReloadId = GLib.idle_add(
                GLib.PRIORITY_DEFAULT_IDLE,
                () => {
                    this._pendingPinnedWindowReloadId = 0;
                    this._reloadPinnedHtmlWidgetsInWindows(reason)
                        .catch(e => logError(e));
                    r
  • app/widgetManager.js:2826
                    GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
                        this.restoreWidgetLayerFocus(monitorIndex);
                        return GLib.SOURCE_REMOVE;
                    })
  • windowTypeManager.js:447
            this._moveIntoPlaceID =
                GLib.timeout_add(GLib.PRIORITY_LOW, 250, () => {
                    if (force || this._needsMoveToParsedPosition())
                        this._window.move_frame(true, this._x, this._y);
    
    
                    this._moveIntoPlaceID = 0;
                    return GLib.S

EGO-M-008 warning

extensions using unlock-dialog must document it in disable() comments

Extensions using `unlock-dialog` should document the reason in `disable()` comments.

Session Modes

  • extension.js:22
        disable() {
            this.dingManager?.disable();
            this.dingManager = null;
            this.DesktopIconsUsableArea = null;
        }

All Versions

Version Status
100.21 (134) Unreviewed
100.20 (133) Rejected
100.19 (132) Active
100.18 (131) Rejected
100.17 (130) Rejected
100.17 (129) Active
100.16 (128) Active
100.15 (127) Inactive
100.14 (126) Active
100.14 (125) Rejected
100.14 (124) Rejected
100.14 (123) Rejected
100.13 (122) Active
100.12 (121) Inactive
100.12 (120) Rejected
100.11 (119) Active
100.9 (118) Active
100.8 (117) Active
100.8 (116) Inactive
100.7 (115) Active
100.6 (114) Inactive
100.5 (113) Active
100.4 (112) Active
100.3 (111) Active
100.2 (110) Active
100.1 (109) Active
100 (108) Active
100 (107) Active
99 (106) Active
98 (105) Active
98 (104) Rejected
97 (103) Active
96 (102) Active
95 (101) Inactive
94 (100) Inactive
93 (99) Inactive
92 (98) Active
91 (97) Inactive
91 (96) Rejected
91 (95) Inactive
90 (94) Active
90 (93) Rejected
89 (92) Active
88 (91) Active
87 (90) Active
86 (89) Active
85 (88) Active
84 (87) Active
83 (86) Active
82 (85) Active
81 (84) Inactive
80 (83) Active
79 (82) Active
78 (81) Active
77 (80) Active
76 (79) Active
75 (78) Inactive
74 (77) Inactive
74 (76) Inactive
74 (75) Rejected
74 (74) Rejected
73 (73) Active
72 (72) Active
71 (71) Active
70 (70) Active
69 (69) Active
68 Active
67 Active
66 Active
65 Rejected
64 Rejected
63 Active
62 Active
61 Active
60 Active
59 Active
58 Inactive
57 Active
56 Active
55 Active
54 Active
53 Rejected
52 Rejected
51 Rejected
50 Rejected
49 Active
48 Rejected
47 Active
46 Active
45 Active
44 Rejected
43 Active
42 Active
41 Active
40 Active
39 Active
38 Active
37 Active
36 Active
35 Active
34 Active
33 Active
32 Active
31 Active
30 Active
29 Rejected
28 Active
27 Active
26 Active
25 Active
24 Active
23 Active
22 Active
21 Active
20 Active
19 Rejected
18 Active
17 Active
16 Active
15 Active
14 Active
13 Active
12 Active
11 Active
10 Active
9 Active
8 Active
7 Active
6 Active
5 Active
4 Rejected
3 Active
2 Active
1 Rejected