### Cache and Retrieve Images with Javascript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This snippet demonstrates how to store and retrieve images using a registry, likely for caching purposes. It shows the creation of an image entry, writing it to a file, obtaining its filename, and loading it as a St.Icon widget. Dependencies include 'Registry', 'ClipboardEntry', and 'gi://St'. ```javascript import { Registry, ClipboardEntry } from './registry.js'; import St from 'gi://St'; const registry = new Registry({ settings: settings, uuid: 'clipboard-indicator@tudmotu.com' }); // Create image entry const imageBytes = new Uint8Array([/* PNG data */]); const imageEntry = new ClipboardEntry('image/png', imageBytes, false); // Write image to cache file (stored as hash-based filename) await registry.writeEntryFile(imageEntry); // Get filename path const filename = registry.getEntryFilename(imageEntry); // Returns: ~/.cache/clipboard-indicator@tudmotu.com/ // Load image as St.Icon widget const stIcon = await registry.getEntryAsImage(imageEntry); stIcon.add_style_class_name('clipboard-indicator-img-preview'); // Can now be added to GNOME Shell UI ``` -------------------------------- ### Initialize GNOME Shell Clipboard Indicator Extension Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Initializes and enables the Clipboard Indicator extension within the GNOME Shell environment. It sets up the necessary components like clipboard access, settings, and preference handling, then adds the indicator to the GNOME panel. ```javascript import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; export default class ClipboardIndicatorExtension extends Extension { enable () { this.clipboardIndicator = new ClipboardIndicator({ clipboard: St.Clipboard.get_default(), settings: this.getSettings(), openSettings: this.openPreferences, uuid: this.uuid }); Main.panel.addToStatusArea('clipboardIndicator', this.clipboardIndicator, 1); } disable () { this.clipboardIndicator.destroy(); this.clipboardIndicator = null; } } ``` -------------------------------- ### Manage Extension Settings with Javascript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This snippet shows how to interact with GNOME Shell extension settings using GSettings. It covers reading various setting types (integer, boolean, string array), writing new values, and connecting to 'changed' signals to react to modifications. It also demonstrates how to disconnect from signals for cleanup. Dependencies include 'PrefsFields'. ```javascript import { PrefsFields } from './constants.js'; // Get settings instance const settings = this.getSettings(); // Read settings const historySize = settings.get_int(PrefsFields.HISTORY_SIZE); // 15 const previewSize = settings.get_int(PrefsFields.PREVIEW_SIZE); // 30 const notifyOnCopy = settings.get_boolean(PrefsFields.NOTIFY_ON_COPY); // false const excludedApps = settings.get_strv(PrefsFields.EXCLUDED_APPS); // ['KeePassXC'] const displayMode = settings.get_int(PrefsFields.TOPBAR_DISPLAY_MODE_ID); // 0-3 // Write settings settings.set_int(PrefsFields.HISTORY_SIZE, 50); settings.set_boolean(PrefsFields.CACHE_IMAGES, true); settings.set_strv(PrefsFields.EXCLUDED_APPS, ['KeePassXC', 'gnome-terminal']); // Listen for changes const settingsChangedId = settings.connect('changed', (settings, key) => { console.log(`Setting changed: ${key}`); if (key === PrefsFields.HISTORY_SIZE) { const newSize = settings.get_int(PrefsFields.HISTORY_SIZE); console.log(`New history size: ${newSize}`); } }); // Cleanup settings.disconnect(settingsChangedId); ``` -------------------------------- ### Clipboard Entry Management (Text and Image) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Demonstrates the creation and manipulation of clipboard entries, supporting both plain text and image data. It shows how to check entry types, retrieve string values, handle image data as bytes, and manage favorite (pinned) status. ```javascript import { ClipboardEntry } from './registry.js'; // Create text entry const textData = new TextEncoder().encode('Sample clipboard text'); const textEntry = new ClipboardEntry('text/plain;charset=utf-8', textData, false); console.log(textEntry.isText()); // true console.log(textEntry.isImage()); // false console.log(textEntry.getStringValue()); // 'Sample clipboard text' console.log(textEntry.isFavorite()); // false // Mark as favorite (pinned) textEntry.favorite = true; console.log(textEntry.isFavorite()); // true // Create image entry from clipboard const imageData = new Uint8Array([0x89, 0x50, 0x4E, 0x47, /* ... PNG data ... */]); const imageEntry = new ClipboardEntry('image/png', imageData, false); console.log(imageEntry.isImage()); // true console.log(imageEntry.mimetype()); // 'image/png' console.log(imageEntry.asBytes()); // GLib.Bytes object // Compare entries const isDuplicate = textEntry.equals(textEntry); // true ``` -------------------------------- ### Create and Interact with Menu Items for Clipboard Entries (JavaScript) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This function creates a menu item for a clipboard entry, including a preview (text or image), and action buttons for pinning, pasting, and deleting. It handles adding the item to either the favorites or history section of the popup menu. Dependencies include Gnome Shell's PopupMenu, St, and Clutter modules. ```javascript import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; import St from 'gi://St'; import Clutter from 'gi://Clutter'; function addEntry(entry, autoSelect = true, autoSetClip = true) { // Create menu item let menuItem = new PopupMenu.PopupMenuItem(''); menuItem.entry = entry; menuItem.clipContents = entry.getStringValue(); menuItem.radioGroup = this.clipItemsRadioGroup; // Set label/preview if (entry.isText()) { const truncated = entry.getStringValue().substring(0, 50); menuItem.label.set_text(truncated); } else if (entry.isImage()) { const img = await registry.getEntryAsImage(entry); img.add_style_class_name('clipboard-menu-img-preview'); menuItem.insert_child_below(img, menuItem.label); } // Add pin button let pinButton = new St.Button({ style_class: 'ci-pin-btn ci-action-btn', child: new St.Icon({ icon_name: 'view-pin-symbolic' }) }); pinButton.connect('clicked', () => { menuItem.entry.favorite = !menuItem.entry.favorite; this._updateCache(); }); menuItem.actor.add_child(pinButton); // Add paste button let pasteButton = new St. Button({ style_class: 'ci-action-btn', child: new St.Icon({ icon_name: 'edit-paste-symbolic' }) }); pasteButton.connect('clicked', () => this.pasteItem(menuItem)); menuItem.actor.add_child(pasteButton); // Add delete button let deleteButton = new St.Button({ style_class: 'ci-action-btn', child: new St.Icon({ icon_name: 'edit-delete-symbolic' }) }); deleteButton.connect('clicked', () => this.removeEntry(menuItem)); menuItem.actor.add_child(deleteButton); // Add to appropriate section if (entry.isFavorite()) { this.favoritesSection.addMenuItem(menuItem, 0); } else { this.historySection.addMenuItem(menuItem, 0); } this.clipItemsRadioGroup.push(menuItem); if (autoSelect) { menuItem.setOrnament(PopupMenu.Ornament.DOT); menuItem.currentlySelected = true; } } ``` -------------------------------- ### Implement Search with Case-Sensitivity and Regex Support in JavaScript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This function handles text changes in a search entry, applying either case-sensitive or case-insensitive matching. It supports simple substring searching and regular expression matching with multiline support. It iterates through menu items, updating their visibility based on whether they match the search criteria. ```javascript function onSearchTextChanged() { let searchedText = this.searchEntry.get_text(); // Apply case sensitivity setting if (!CASE_SENSITIVE_SEARCH) { searchedText = searchedText.toLowerCase(); } if (searchedText === '') { // Show all items this._getAllIMenuItems().forEach(mItem => { mItem.actor.visible = true; }); } else { // Filter items this._getAllIMenuItems().forEach(mItem => { let text = mItem.clipContents; if (!CASE_SENSITIVE_SEARCH) { text = text.toLowerCase(); } let isMatching = false; if (REGEX_SEARCH) { // Use regex matching with multiline support const flags = 'm' + (CASE_SENSITIVE_SEARCH ? '' : 'i'); const regex = new RegExp(searchedText, flags); isMatching = regex.test(text); } else { // Simple substring matching isMatching = text.indexOf(searchedText) >= 0; } mItem.actor.visible = isMatching; }); } } // Usage example: // User types "error" in search box // - Case insensitive: matches "Error", "ERROR", "error" // - Regex enabled: "err.*" matches "error", "errno", "erroneous" ``` -------------------------------- ### Simulate Keyboard Input for Pasting Clipboard Content in JavaScript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This function simulates keyboard input to paste clipboard content. It first sets the clipboard to the selected item's content, then uses a setTimeout to simulate key presses for pasting. It handles special paste combinations for terminals (Ctrl+Shift+Insert) and standard paste (Shift+Insert), and restores the original clipboard content afterward. ```javascript import Clutter from 'gi://Clutter'; import { Keyboard } from './keyboard.js'; function pasteItem(menuItem) { const keyboard = new Keyboard(); const currentlySelected = this._getCurrentlySelectedItem(); // Temporarily set clipboard to item to paste this.preventIndicatorUpdate = true; this.extension.clipboard.set_content( CLIPBOARD_TYPE, menuItem.entry.mimetype(), menuItem.entry.asBytes() ); setTimeout(() => { // Detect if terminal (requires Ctrl+Shift+Insert) if (keyboard.purpose === Clutter.InputContentPurpose.TERMINAL) { keyboard.press(Clutter.KEY_Control_L); keyboard.press(Clutter.KEY_Shift_L); keyboard.press(Clutter.KEY_Insert); keyboard.release(Clutter.KEY_Insert); keyboard.release(Clutter.KEY_Shift_L); keyboard.release(Clutter.KEY_Control_L); } else { // Standard paste: Shift+Insert keyboard.press(Clutter.KEY_Shift_L); keyboard.press(Clutter.KEY_Insert); keyboard.release(Clutter.KEY_Insert); keyboard.release(Clutter.KEY_Shift_L); } // Restore original clipboard setTimeout(() => { this.preventIndicatorUpdate = false; this.extension.clipboard.set_content( CLIPBOARD_TYPE, currentlySelected.entry.mimetype(), currentlySelected.entry.asBytes() ); }, 50); }, 50); this.menu.close(); } ``` -------------------------------- ### Detect Clipboard Content with Javascript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This function retrieves clipboard content by iterating through a list of common MIME types. It returns the first successfully retrieved entry, which can be either text or an image. Dependencies include 'gi://St' and 'ClipboardEntry'. The function handles potential null or empty bytes and logs the type of content retrieved. ```javascript import St from 'gi://St'; import { ClipboardEntry } from './registry.js'; const CLIPBOARD_TYPE = St.ClipboardType.CLIPBOARD; const clipboard = St.Clipboard.get_default(); async function getClipboardContent() { const mimetypes = [ "text/plain;charset=utf-8", "UTF8_STRING", "text/plain", "STRING", 'image/gif', 'image/png', 'image/jpg', 'image/jpeg', 'image/webp', 'image/svg+xml', 'text/html', ]; for (let type of mimetypes) { let result = await new Promise(resolve => { clipboard.get_content(CLIPBOARD_TYPE, type, (clipBoard, bytes) => { if (bytes === null || bytes.get_size() === 0) { resolve(null); return; } const entry = new ClipboardEntry(type, bytes.get_data(), false); resolve(entry); }); }); if (result) { return result; // Returns first matching mimetype } } return null; } const currentClip = await getClipboardContent(); if (currentClip) { console.log(`Got ${currentClip.isText() ? 'text' : 'image'} from clipboard`); } ``` -------------------------------- ### Write Clipboard Entries to Registry (Cache) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Writes an array of clipboard entries to a persistent cache file. This function is used to save the clipboard history, supporting both text and image data. The registry file is typically located in the user's cache directory. ```javascript import { Registry, ClipboardEntry } from './registry.js'; const registry = new Registry({ settings: settings, uuid: 'clipboard-indicator@tudmotu.com' }); // Create clipboard entries const entries = [ new ClipboardEntry('text/plain;charset=utf-8', new TextEncoder().encode('Hello World'), false), new ClipboardEntry('text/plain;charset=utf-8', new TextEncoder().encode('Sample text'), true) ]; // Write to registry file (stored in ~/.cache/clipboard-indicator@tudmotu.com/registry.txt) registry.write(entries); ``` -------------------------------- ### Display Confirmation Dialog (JavaScript) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Implements a modal confirmation dialog for destructive actions, requiring user confirmation before proceeding. It uses a DialogManager class for opening and managing dialogs and includes callbacks for user actions. The dialog manager should be properly destroyed upon extension disable. ```javascript import { DialogManager } from './confirmDialog.js'; const dialogManager = new DialogManager(); // Show confirmation before clearing history function confirmRemoveAll() { const title = "Clear all?"; const message = "Are you sure you want to delete all clipboard items?"; const subMessage = "This operation cannot be undone."; dialogManager.open( title, message, subMessage, "Clear", // OK button label "Cancel", // Cancel button label () => { // Callback executed on confirm this._clearHistory(); } ); } // Cleanup on disable dialogManager.destroy(); ``` -------------------------------- ### Bind and Unbind Global Keyboard Shortcuts for Gnome Shell (JavaScript) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This code defines functions to bind and unbind global keyboard shortcuts for various clipboard operations within a Gnome Shell extension. It uses Gnome Shell's main window manager API to register keybindings associated with specific actions like clearing history, navigating entries, toggling the menu, and enabling private mode. It handles compatibility with different Gnome Shell versions regarding keybinding modes. ```javascript import Meta from 'gi://Meta'; import Shell from 'gi://Shell'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import { PrefsFields } from './constants.js'; function bindShortcuts() { const ModeType = Shell.hasOwnProperty('ActionMode') ? Shell.ActionMode : Shell.KeyBindingMode; // Clear history: Ctrl+F10 Main.wm.addKeybinding( PrefsFields.BINDING_CLEAR_HISTORY, this.extension.settings, Meta.KeyBindingFlags.NONE, ModeType.ALL, () => this._removeAll() ); // Previous entry: Ctrl+F11 Main.wm.addKeybinding( PrefsFields.BINDING_PREV_ENTRY, this.extension.settings, Meta.KeyBindingFlags.NONE, ModeType.ALL, () => this._previousEntry() ); // Next entry: Ctrl+F12 Main.wm.addKeybinding( PrefsFields.BINDING_NEXT_ENTRY, this.extension.settings, Meta.KeyBindingFlags.NONE, ModeType.ALL, () => this._nextEntry() ); // Toggle menu: Ctrl+F9 Main.wm.addKeybinding( PrefsFields.BINDING_TOGGLE_MENU, this.extension.settings, Meta.KeyBindingFlags.NONE, ModeType.ALL, () => this.menu.toggle() ); // Private mode: Ctrl+F8 Main.wm.addKeybinding( PrefsFields.BINDING_PRIVATE_MODE, this.extension.settings, Meta.KeyBindingFlags.NONE, ModeType.ALL, () => this.togglePrivateMode() ); } function unbindShortcuts() { Main.wm.removeKeybinding(PrefsFields.BINDING_CLEAR_HISTORY); Main.wm.removeKeybinding(PrefsFields.BINDING_PREV_ENTRY); Main.wm.removeKeybinding(PrefsFields.BINDING_NEXT_ENTRY); Main.wm.removeKeybinding(PrefsFields.BINDING_TOGGLE_MENU); Main.wm.removeKeybinding(PrefsFields.BINDING_PRIVATE_MODE); } ``` -------------------------------- ### Read Clipboard History from Registry (Cache) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Reads all cached clipboard entries from the persistence file. This function asynchronously retrieves the clipboard history, allowing for iteration and processing of both text and image entries, and checks if an entry is pinned. ```javascript import { Registry } from './registry.js'; import GLib from 'gi://GLib'; const registry = new Registry({ settings: settings, uuid: 'clipboard-indicator@tudmotu.com' }); // Asynchronously read all cached entries const clipHistory = await registry.read(); // Process entries for (let entry of clipHistory) { if (entry.isText()) { console.log(`Text: ${entry.getStringValue()}`); } else if (entry.isImage()) { console.log(`Image: ${entry.asBytes().hash()}`); } if (entry.isFavorite()) { console.log('Entry is pinned'); } } ``` -------------------------------- ### Monitor Clipboard Changes and Update History in JavaScript Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt This code sets up a listener for clipboard changes using Gnome Shell's metaDisplay. When the clipboard owner changes, it triggers a refresh of the indicator, provided private mode is not active and the focused application is not in the exclusion list. It checks for existing entries, adds new ones to history, and optionally shows a notification. ```javascript import Shell from 'gi://Shell'; import Meta from 'gi://Meta'; function setupListener() { const metaDisplay = Shell.Global.get().get_display(); const selection = metaDisplay.get_selection(); this._selectionOwnerChangedId = selection.connect( 'owner-changed', (selection, selectionType, selectionSource) => { if (selectionType === Meta.SelectionType.SELECTION_CLIPBOARD) { this._refreshIndicator(); } } ); } async function refreshIndicator() { if (PRIVATEMODE) return; // Check if focussed window is excluded const focussedWindow = Shell.Global.get().display.focusWindow; const wmClass = focussedWindow?.get_wm_class(); if (wmClass && EXCLUDED_APPS.includes(wmClass)) { return; // Don't track clipboard from excluded apps } try { const result = await this.getClipboardContent(); if (result) { // Check if entry already exists for (let menuItem of this.clipItemsRadioGroup) { if (menuItem.entry.equals(result)) { this._selectMenuItem(menuItem, false); return; } } // New entry - add to history this.addToCache(result); this._addEntry(result, true, false); this._removeOldestEntries(); // Enforce size limit if (NOTIFY_ON_COPY) { this._showNotification('Copied to clipboard'); } } } catch (e) { console.error('Failed to refresh indicator:', e); } } ``` -------------------------------- ### Schedule Automatic History Clearing (JavaScript) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Sets up and manages automatic clearing of clipboard history at configured intervals. It reads settings for enabling the feature, the clearing interval, and the next scheduled clear time. The function schedules a timeout for clearing and an interval for updating a countdown display. ```javascript import GLib from 'gi://GLib'; import { PrefsFields } from './constants.js'; function setupHistoryIntervalClearing() { const CLEAR_HISTORY_ON_INTERVAL = this.extension.settings.get_boolean( PrefsFields.CLEAR_HISTORY_ON_INTERVAL ); const CLEAR_HISTORY_INTERVAL = this.extension.settings.get_int( PrefsFields.CLEAR_HISTORY_INTERVAL ); // in minutes let NEXT_HISTORY_CLEAR = this.extension.settings.get_int( PrefsFields.NEXT_HISTORY_CLEAR ); if (!CLEAR_HISTORY_ON_INTERVAL) { return; } const currentTime = Math.ceil(new Date().getTime() / 1000); if (NEXT_HISTORY_CLEAR === -1) { // Schedule new timer NEXT_HISTORY_CLEAR = currentTime + CLEAR_HISTORY_INTERVAL * 60; this.extension.settings.set_int( PrefsFields.NEXT_HISTORY_CLEAR, NEXT_HISTORY_CLEAR ); } else if (NEXT_HISTORY_CLEAR < currentTime) { // Timer expired - clear now this._clearHistory(true); NEXT_HISTORY_CLEAR = currentTime + CLEAR_HISTORY_INTERVAL * 60; this.extension.settings.set_int( PrefsFields.NEXT_HISTORY_CLEAR, NEXT_HISTORY_CLEAR ); } // Schedule timeout const timeoutMs = (NEXT_HISTORY_CLEAR - currentTime) * 1000; this._historyClearTimeoutId = setTimeout(() => { this._clearHistory(true); this._scheduleNextHistoryClear(); }, timeoutMs); // Update countdown display every second this._timerIntervalId = setInterval(() => { this._updateIntervalTimer(); }, 1000); } function updateIntervalTimer() { const currentTime = Math.ceil(new Date().getTime() / 1000); const timeLeft = NEXT_HISTORY_CLEAR - currentTime; if (timeLeft <= 0) { this.timerLabel.set_text(''); return; } const hours = Math.floor(timeLeft / 3600); const minutes = Math.floor((timeLeft % 3600) / 60); const seconds = Math.floor(timeLeft % 60); let formattedTime = ''; if (hours > 0) formattedTime += `${hours}h `; if (minutes > 0) formattedTime += `${minutes}m `; formattedTime += `${seconds}s`; this.timerLabel.set_text(formattedTime); // Shows: "1h 23m 45s" } ``` -------------------------------- ### Toggle Private Mode (JavaScript) Source: https://context7.com/tudmotu/gnome-shell-extension-clipboard-indicator/llms.txt Manages the private mode functionality, which temporarily disables clipboard tracking. When entering private mode, history sections are hidden, and the indicator UI is updated. When exiting private mode, it restores the previous clipboard selection or clears it if no previous state exists. This function is typically triggered by a keyboard shortcut or a menu toggle. ```javascript function onPrivateModeSwitch() { const PRIVATEMODE = this.privateModeMenuItem.state; // Hide history sections in private mode this.scrollViewMenuSection.actor.visible = !PRIVATEMODE; this.scrollViewFavoritesMenuSection.actor.visible = !PRIVATEMODE; if (!PRIVATEMODE) { // Exiting private mode - restore previous clipboard let selectList = this.clipItemsRadioGroup.filter( item => item.currentlySelected ); if (selectList.length) { this._selectMenuItem(selectList[0]); } else { // Clear clipboard if nothing to restore this.extension.clipboard.set_text(CLIPBOARD_TYPE, ""); } this.hbox.remove_style_class_name('private-mode'); this.#updateIndicatorContent(await this.getClipboardContent()); } else { // Entering private mode this.hbox.add_style_class_name('private-mode'); this._buttonText.set_text("..."); this._buttonImgPreview.destroy_all_children(); } } // Usage: Press Ctrl+F8 or toggle switch in menu // Private mode indicator shown in top bar with dimmed styling ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.