Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
</key>
<key name="paste-on-copy" type="b">
<default>true</default>
<summary>Automatically paste clipboard items when selected from clipboard history</summary>
<summary>Automatically paste clipboard items when selected from clipboard history (Deprecated)</summary>
</key>
<key name="sync-primary" type="b">
<default>false</default>
Expand Down Expand Up @@ -361,6 +361,11 @@
<summary>Action to perform when the middle mouse button is clicked</summary>
</key>

<key name="swap-copy-shortcut" type="b">
<default>false</default>
<summary>Swaps copy and paste shortcuts</summary>
</key>

<key name="swap-scroll-shortcut" type="b">
<default>false</default>
<summary>Swaps scroll shortcuts of cycling item types and item tags</summary>
Expand Down
7 changes: 7 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { LanguageFn } from 'highlight.js';

import { ClipboardHistory, getDataPath, getHljsLanguages, getHljsPath } from './lib/common/constants.js';
import { DbusService } from './lib/common/dbus.js';
import { migrateSettings } from './lib/common/settings.js';
import { SoundManager, tryCreateSoundManager } from './lib/common/sound.js';
import { ClipboardEntry } from './lib/database/database.js';
import { ClipboardEntryTracker } from './lib/database/entryTracker.js';
Expand Down Expand Up @@ -47,6 +48,8 @@ export default class CopyousExtension extends Extension {

override enable() {
this.settings = this.getSettings();
migrateSettings(this.settings);

this.logger = this.getLogger();
const error = this.logger.error.bind(this.logger);

Expand All @@ -64,6 +67,10 @@ export default class CopyousExtension extends Extension {
await this.entryTracker?.deleteOldest();
}
});
this.clipboardDialog.connect('copy', async (_, entry: ClipboardEntry) => {
await this.clipboardManager?.copyEntry(entry);
this.indicator?.showEntry(entry);
});
this.clipboardDialog.connect('paste', async (_, entry: ClipboardEntry) => {
await this.clipboardManager?.pasteEntry(entry);
this.indicator?.showEntry(entry);
Expand Down
7 changes: 7 additions & 0 deletions src/lib/common/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ export function bind_flags(settings: Gio.Settings, key: string, object: GObject.
if (value != null) settings.set_flags(key, value);
});
}

export function migrateSettings(settings: Gio.Settings): void {
// inverted paste-on-copy -> swap-copy-shortcut
const pasteOnCopy = settings.get_user_value<'b'>('paste-on-copy');
if (pasteOnCopy !== null) settings.set_boolean('swap-copy-shortcut', !pasteOnCopy.get_boolean());
settings.reset('paste-on-copy');
}
18 changes: 13 additions & 5 deletions src/lib/misc/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ export class ClipboardManager extends GObject.Object {
public pasteContent(content: ClipboardContent) {
this.copyContent(content);

if (!this.ext.settings.get_boolean('paste-on-copy')) return;

if (this.pasteSignalId >= 0) GLib.source_remove(this.pasteSignalId);
this.pasteSignalId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 250, () => {
// https://github.com/Tudmotu/gnome-shell-extension-clipboard-indicator/blob/89c57703641a9d5d15f899f6e780174641911d95/extension.js#L1094
Expand Down Expand Up @@ -167,7 +165,17 @@ export class ClipboardManager extends GObject.Object {
this.emit('image', data, width, height);
}

public async copyEntry(entry: ClipboardEntry) {
await this.handleEntry(entry, false);
}

public async pasteEntry(entry: ClipboardEntry) {
await this.handleEntry(entry, true);
}

private async handleEntry(entry: ClipboardEntry, paste: boolean) {
const fn = paste ? this.pasteContent.bind(this) : this.copyContent.bind(this);

if (this.ext.settings.get_boolean('update-date-on-copy')) {
entry.datetime = GLib.DateTime.new_now_utc();
}
Expand All @@ -178,7 +186,7 @@ export class ClipboardManager extends GObject.Object {
case ItemType.Link:
case ItemType.Character:
case ItemType.Color:
return this.pasteContent({ type: ContentType.Text, text: entry.content });
return fn({ type: ContentType.Text, text: entry.content });
case ItemType.Image:
try {
const image = Gio.File.new_for_uri(entry.content);
Expand All @@ -190,14 +198,14 @@ export class ClipboardManager extends GObject.Object {
const checksum = GLib.compute_checksum_for_bytes(GLib.ChecksumType.MD5, contents);
if (!checksum) return;

return this.pasteContent({ type: ContentType.Image, mimetype, data: contents, checksum });
return fn({ type: ContentType.Image, mimetype, data: contents, checksum });
} catch {
break;
}
case ItemType.File:
case ItemType.Files: {
const paths = entry.content.split('\n');
return this.pasteContent({ type: ContentType.File, paths, operation: FileOperation.Copy });
return fn({ type: ContentType.File, paths, operation: FileOperation.Copy });
}
}
}
Expand Down
34 changes: 18 additions & 16 deletions src/lib/misc/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class ShortcutBinding extends GObject.Object {
})
export class ShortcutManager extends GObject.Object {
private _actor: Clutter.Actor | null;
private _keyPressSignalId: number = -1;
private _keyReleaseSignalId: number = -1;
private _destroySignalId: number = -1;

private _shortcuts: { [shortcut in Shortcut]?: ShortcutBinding } = {};
private _actions: { [shortcut in string]: string } = {};
Expand All @@ -87,9 +84,17 @@ export class ShortcutManager extends GObject.Object {
this.registerShortcut(Shortcut.Menu);

this._actor = actor;
this._keyPressSignalId = actor.connect('key-press-event', this.keyPressEvent.bind(this));
this._keyReleaseSignalId = actor.connect('key-release-event', this.keyReleaseEvent.bind(this));
this._destroySignalId = actor.connect('destroy', () => (this._actor = null));
actor.connectObject(
'key-press-event',
this.keyPressEvent.bind(this),
'key-release-event',
this.keyReleaseEvent.bind(this),
'hide',
this.hideEvent.bind(this),
'destroy',
() => (this._actor = null),
this,
);

this._monitor = getActionsConfigPath(ext).monitor(Gio.FileMonitorFlags.NONE, null);
this._monitor.connect('changed', (_source, _file, _otherFile, eventType) => {
Expand Down Expand Up @@ -136,6 +141,12 @@ export class ShortcutManager extends GObject.Object {
}
}

private hideEvent(_actor: Clutter.Actor) {
this._shiftL = false;
this._shiftR = false;
this.notify('shift');
}

private updateActions(save: boolean = false) {
this._actions = {};

Expand Down Expand Up @@ -177,16 +188,7 @@ export class ShortcutManager extends GObject.Object {
this.unregisterGlobalShortcut(Shortcut.Incognito);

this._shortcuts = {};

if (this._actor) {
if (this._keyPressSignalId >= 0) this._actor.disconnect(this._keyPressSignalId);
if (this._keyReleaseSignalId >= 0) this._actor.disconnect(this._keyReleaseSignalId);
if (this._destroySignalId >= 0) this._actor.disconnect(this._destroySignalId);
}

this._keyPressSignalId = -1;
this._keyReleaseSignalId = -1;
this._destroySignalId = -1;
this._actor?.disconnectObject(this);
this._monitor.cancel();
}
}
7 changes: 0 additions & 7 deletions src/lib/preferences/general/behaviorSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ export class BehaviorSettings extends Adw.PreferencesGroup {
});
this.add(protectTagged);

const pasteOnCopy = new Adw.SwitchRow({
title: _('Paste on Copy'),
subtitle: _('Automatically paste clipboard items when selected from clipboard history'),
});
this.add(pasteOnCopy);

const syncPrimary = new Adw.SwitchRow({
title: _('Sync Primary Clipboard'),
subtitle: _('Also copy clipboard items to the primary clipboard'),
Expand All @@ -67,7 +61,6 @@ export class BehaviorSettings extends Adw.PreferencesGroup {
settings.bind('exclude-tagged', excludeTagged, 'active', Gio.SettingsBindFlags.DEFAULT);
settings.bind('protect-pinned', protectPinned, 'active', Gio.SettingsBindFlags.DEFAULT);
settings.bind('protect-tagged', protectTagged, 'active', Gio.SettingsBindFlags.DEFAULT);
settings.bind('paste-on-copy', pasteOnCopy, 'active', Gio.SettingsBindFlags.DEFAULT);
settings.bind('sync-primary', syncPrimary, 'active', Gio.SettingsBindFlags.DEFAULT);
settings.bind('update-date-on-copy', updateDateOnCopy, 'active', Gio.SettingsBindFlags.DEFAULT);
}
Expand Down
26 changes: 24 additions & 2 deletions src/lib/preferences/shortcuts/itemShortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,32 @@ export class ItemShortcuts extends Adw.PreferencesGroup {

@registerClass()
export class ItemActivationShortcuts extends Adw.PreferencesGroup {
constructor() {
constructor(prefs: ExtensionPreferences) {
super();

this.add(new ShortcutRow(_('Copy Item'), 'Return space'));
const swapCopyPasteRow = new Adw.SwitchRow({
title: _('Swap Copy Shortcut'),
subtitle: _('Swap copy and paste shortcuts'),
});
this.add(swapCopyPasteRow);

const pasteRow = new ShortcutRow(_('Paste Item'), 'Return space');
this.add(pasteRow);
const copyRow = new ShortcutRow(_('Copy Item'), '<Shift>Return space');
this.add(copyRow);
this.add(new ShortcutRow(_('Activate Default Action'), '<Ctrl>Return space'));

swapCopyPasteRow.connect('notify::active', () => {
if (swapCopyPasteRow.active) {
pasteRow.shortcuts = ['<Shift>Return space'];
copyRow.shortcuts = ['Return space'];
} else {
pasteRow.shortcuts = ['Return space'];
copyRow.shortcuts = ['<Shift>Return space'];
}
});

const settings = prefs.getSettings();
settings.bind('swap-copy-shortcut', swapCopyPasteRow, 'active', null);
}
}
19 changes: 11 additions & 8 deletions src/lib/ui/clipboardDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,9 @@ class ClipboardDialogFooter extends St.BoxLayout {
opened: GObject.ParamSpec.boolean('opened', null, null, GObject.ParamFlags.READABLE, false),
},
Signals: {
'paste': {
param_types: [GObject.TYPE_JSOBJECT],
},
'clear-history': {
param_types: [GObject.TYPE_INT],
},
'copy': { param_types: [GObject.TYPE_JSOBJECT] },
'paste': { param_types: [GObject.TYPE_JSOBJECT] },
'clear-history': { param_types: [GObject.TYPE_INT] },
},
})
export class ClipboardDialog extends St.Widget {
Expand Down Expand Up @@ -604,10 +601,16 @@ export class ClipboardDialog extends St.Widget {

// Connect activation
item.connect('activate', () => {
this.emit('paste', entry);
const swap = this.ext.settings.get_boolean('swap-copy-shortcut');
this.emit(swap ? 'copy' : 'paste', entry);
this.close();
});
item.connect('activate-default', () => {
item.connect('activate-shift', () => {
const swap = this.ext.settings.get_boolean('swap-copy-shortcut');
this.emit(swap ? 'paste' : 'copy', entry);
this.close();
});
item.connect('activate-ctrl', () => {
if (this._clipboardItemMenu.activateDefaultAction(entry)) this.close();
});
item.connect('activate-action', (_, id: string) => {
Expand Down
15 changes: 7 additions & 8 deletions src/lib/ui/items/clipboardItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@ export type MiddleClickAction = (typeof MiddleClickAction)[keyof typeof MiddleCl
},
Signals: {
'activate': {},
'activate-default': {},
'activate-action': {
param_types: [GObject.TYPE_STRING],
},
'activate-shift': {},
'activate-ctrl': {},
'activate-action': { param_types: [GObject.TYPE_STRING] },
'edit': {},
'open-menu': {
param_types: [GObject.TYPE_INT, GObject.TYPE_INT, GObject.TYPE_INT, GObject.TYPE_INT],
},
'open-menu': { param_types: [GObject.TYPE_INT, GObject.TYPE_INT, GObject.TYPE_INT, GObject.TYPE_INT] },
},
})
export class ClipboardItem extends St.Button {
Expand Down Expand Up @@ -216,7 +213,9 @@ export class ClipboardItem extends St.Button {
if (clicked_button === 1) {
const event = Clutter.get_current_event();
if (event.has_control_modifier()) {
this.emit('activate-default');
this.emit('activate-ctrl');
} else if (event.has_shift_modifier()) {
this.emit('activate-shift');
} else {
this.emit('activate');
}
Expand Down
6 changes: 5 additions & 1 deletion src/prefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Gtk from 'gi://Gtk';
import { ExtensionPreferences, gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';

import { Icon } from './lib/common/icons.js';
import { migrateSettings } from './lib/common/settings.js';
import { ActionsPage } from './lib/preferences/actions/actionsPage.js';
import { DialogCustomization } from './lib/preferences/customization/dialogCustomization.js';
import { HeaderCustomization } from './lib/preferences/customization/headerCustomization.js';
Expand Down Expand Up @@ -59,6 +60,9 @@ export default class Preferences extends ExtensionPreferences {
// Enable search
window.search_enabled = true;

// Migrate settings
migrateSettings(this.getSettings());

// Add dependencies button to headerbar
const headerBar = findHeaderBar(window);
const dependenciesButton = new DependenciesWarningButton(this, window);
Expand Down Expand Up @@ -111,7 +115,7 @@ export default class Preferences extends ExtensionPreferences {

shortcuts.add(new DialogShortcuts(this));
shortcuts.add(new ItemShortcuts(this));
shortcuts.add(new ItemActivationShortcuts());
shortcuts.add(new ItemActivationShortcuts(this));
shortcuts.add(new PopupMenuShortcuts());
shortcuts.add(new NavigationShortcuts());
shortcuts.add(new SearchShortcuts());
Expand Down