Review of "Clipo" version 1

Details Page Preview

Lightweight, fast, keyboard-driven clipboard manager with rich text and image support. This extension accesses clipboard data locally to maintain clipboard history.

Extension Homepage
https://github.com/Aditya190803/clipo

No comments.

FAQ

Files

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

Shexli (experimental) warning 4 manual_review 1

Shexli found 5 issues that may need reviewer attention.

EGO-A-005 manual_review

extensions should not access the clipboard directly

Direct clipboard access via `St.Clipboard.get_default()` requires reviewer scrutiny.

Review Guidelines

  • extension.js:1128
    St.Clipboard.get_default()

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

  • extension.js:282
    console.error('[Clipo] Failed to load image preview:', e)
  • extension.js:309
    console.error('[Clipo] Failed to create thumbnail:', e)
  • extension.js:342
    console.error('[Clipo] Invalid image data: empty or null')
  • extension.js:350
    console.error('[Clipo] Failed to create pixbuf from stream')
  • extension.js:356
    console.error('[Clipo] Failed to load image:', e.message)
  • extension.js:408
    console.error('[Clipo] No compatible image content API found')
  • extension.js:412
    console.error('[Clipo] Failed to set image content:', e)
  • extension.js:578
    console.error('[Clipo] Failed to show image preview:', e)
  • extension.js:353
    console.log('[Clipo] Successfully loaded image:', pixbuf.get_width(), 'x', pixbuf.get_height())
  • store.js:120
    console.error('[Clipo] Failed to load history:', e)
  • store.js:250
    console.error('[Clipo] Error reading log:', e)
  • store.js:272
    console.error('[Clipo] Failed to move corrupted database:', e)
  • store.js:281
    console.error('[Clipo] Operation failed:', e)
  • store.js:570
    console.error('[Clipo] Failed to replace db during compact', e)
  • store.js:270
    console.log('[Clipo] Moved corrupted database to corrupted.log')
  • store.js:496
    console.log('[Clipo] Compacting database...')
  • store.js:568
    console.log(`[Clipo] Compacted ${entries.length} entries`)
  • store.js:244
    console.warn(`[Clipo] Unknown operation type: ${opType}`)

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

  • store.js:198
    imageFile.load_contents(null)

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

  • extension.js:484
            this._thumbnailActor.connect('enter-event', () => {
                this._showImagePreview();
                return Clutter.EVENT_PROPAGATE;
            })
  • extension.js:489
            this._thumbnailActor.connect('leave-event', () => {
                this._hideImagePreview();
                return Clutter.EVENT_PROPAGATE;
            })
  • extension.js:633
            button.connect('button-press-event', (actor, event) => {
                if (event.get_button() === 1) {
                    handler();
                    return Clutter.EVENT_STOP;
                }
                return Clutter.EVENT_PROPAGATE;
            })
  • extension.js:641
    button.connect('button-release-event', () => Clutter.EVENT_STOP)
  • extension.js:1083
            this.menu.actor.connect('key-press-event', (actor, event) => {
                const symbol = event.get_key_symbol();
                const state = event.get_state();
                const searchFocused = global.stage.get_key_focus() === this._searchEntry?.clutter_text;
    
                // Type-ahead focus:
  • extension.js:1069
            this.menu.connect('open-state-changed', (menu, open) => {
                if (open) {
                    this._onMenuOpened();
                } else {
                    if (this._itemsBox) {
                        for (const item of this._itemsBox.get_children()) {
                            if (typeof item._
  • extension.js:835
            this.menu.connect('open-state-changed', (menu, isOpen) => {
                if (isOpen && this._settings.get_string('popup-position') === 'cursor') {
                    // Use idle_add to ensure we run after BoxPointer's positioning
                    GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
         

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

  • extension.js:1759
            this._focusTimeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 50, () => {
                if (this._searchEntry) {
                    this._searchEntry.grab_key_focus();
                    return GLib.SOURCE_REMOVE;
                }
    
                if (this._itemsBox.get_n_children() > 0) {
                    c
  • extension.js:838
                    GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
                        this._repositionAtCursor();
                        return GLib.SOURCE_REMOVE;
                    })
  • extension.js:1950
    timeoutId

All Versions

Version Status
3 Unreviewed
2 Rejected
1 Rejected

Previous Reviews on this Version

Aditya Mer auto- rejected
Auto-rejected because of new version 2 was uploaded