More Sorting options / paste consumption behaviour
Firstofall, thank you for creating this project! If this issue is fixed, I will likely use this software every day! I am super grateful for all people creating awesome FOSS projects like this 🙏
I want to apologise in advance for the slightly long issue 🙇♂️, but I hope it will be worth working through.
Before Submitting Your Feature Request
- [x] Check that there isn't already a similar feature request to avoid creating a duplicate.
- [x] I have seen the FAQ.
Problem
I would REALLY like, if there were more sorting options / behaviours for what happens when pasting something..
The main reason I want to use Maccy is for transferring text from a discrete set of input fields to another, so I'll frequently have to copy item1, switch app, paste item1, switch back, copy item2....
I could imagine many users benefiting from this option, that are currently just copying everything and then pasting it via selection through cmd+number or arrow keys + enter, which is very suboptimal for this use case, once the amount of things to transfer get bigger than 6
Also the selection via cmd+number combined with the Time of first copy sorting option would only fix this until 9 items...
Solution
one sorting mechanism I'm thus thinking about:
- remove (or at least put to bottom of the list) an item upon pasting it
- in case of removal of the copied item, that's it!
- in case of the no-removal option, I suppose you could call the sorting criterion for this "Time of last paste (most recent last)", i.e. a list that looked like this (from top to bottom, all just freshly copied): a, b, c, d, e would look like this after (successfully?) hitting paste twice: c, d, e, a, b
Honestly, one might want to revamp the "Sort by:" Storage settings into two parts entirely actually:
- Action on copy item (via the native cmd+c or similar)
- Action on paste item (via Maccy window or also via the native cmd+v or similar) which would then have options like:
- for 1.:
- always put item at top of list (equivalent to "Time of last copy" sorting)
- put only NEW items at top of list (equivalent to "Time of first copy" sorting)
- sort into list by times copied (equivalent to "Number of copies" sorting)
- etc
- for 2.:
- do nothing (equivalent to current default behaviour when pressing cmd+v)
- remove item
- put item at bottom of list
- put item at top of list (equivalent to current default behaviour when pasting via Maccy window [since that actually copies the item under the hood])
- etc
I think this is probably the best way, since it doesn't impact previous users, due to the equivalence/compatibility with the previous options, but still allowing more fine grained control for those who need it.
I've just noticed that this would also make this https://github.com/p0deje/Maccy/issues/239 much easier. While you wouldn't have the "paste in one go" option here, you could just copy the items one by one and then paste them quickly one by one, alternating between "cmd+v" and "enter" (producing a newline, or whatever you want to write in between), which seems like pretty good ux to me (and actually even less work than going into the Maccy window and selecting the items to past. Although that ofc would give you more fine grained control, if you wanted to skip an item)
btw, this solution https://github.com/p0deje/Maccy/issues/239#issuecomment-1837293023 somehow didn't work for me (after one "sequential paste" the action continues to delete maccy clipboard items but doesn't paste them anymore.)
Moreover, I'd really just like to paste with cmd+v, a shortcut that can't be set for MacOS Shortcuts. Edit: Or - if that's really not feasible - via "open Maccy shortcut" + "enter" (i.e. select topmost item)
(Also it's a bit laggy for me, i.e. there's an uncomfortable delay between pressing the shortcut and the item being pasted, something that's the case for many Shortcuts of mine)
@p0deje If I can help here in any way, I'd be glad to! (I'd maybe just need a little guidance on which code areas this should touch exactly)
One thing that makes me wonder right now is:
Why are there these TWO options on selecting an item with a modifier key (which both use either option or cmd):
-
- copy
-
- copy and paste
This doesn't really make sense to me, since "just clicking" (= pressing enter on an item) already does one of these anyway (based on my Behavior setting). So there should only be ONE extra option. Suggestions: When "Behavior" is "paste automatically", it should say "Select with cmd pressed to only copy item". Else it should say "Select with cmd pressed to copy and paste item."
another (side) note:
Because of the difference between the current default behaviour on "Maccy paste"
- put item at top of list (equivalent to current default behaviour when pasting via Maccy window [since that actually copies the item under the hood])
vs native cmd+v action:
- do nothing (equivalent to current default behaviour when pressing cmd+v)
One miiight want to even create three parts: 1. Action on copy, 2. Action on cmd+v, 3. Action on paste via Maccy. Honestly I would NOT though.
I'm wondering myself right now, why Maccy even has a difference between what happens on cmd+v and paste via Maccy window... (I'm leaving these thoughts in for someone to comment on, in case they're wrong, but I'm realizing right now that it's probably because Maccy can't paste - because of permissions or smth - directly into apps, so it has to use the native clipboard and emit "paste")
So another question is: Is it even possible for Maccy to listen to the user pressing "cmd+v" in the first place? If NOT, just think of every time I said "cmd+v or similar" in this issue as "selecting the item (with Behavior: paste automatically enabled" or "selecting the item with cmd" otherwise (see comment above https://github.com/p0deje/Maccy/issues/1175#issuecomment-3168365700)
There is a lot here, but for the main point about performing an action on paste, there could be no realiable way to listen for CMD+V events and/or perform logic on top of it. I would need to investigate if it's possible at all. If it's doable, then maybe we can introduce the "Action on paste" concept to implement sequential pasting.
As for the modifiers, when "Paste automatically" is enabled and you want to only copy item, you need to click/enter it with Option pressed. Otherwise, it's going to be pasted after copying.
Assuming this part is an answer to https://github.com/p0deje/Maccy/issues/1175#issuecomment-3168365700:
As for the modifiers, when "Paste automatically" is enabled and you want to only copy item, you need to click/enter it with Option pressed. Otherwise, it's going to be pasted after copying.
I understand that! I was just wondering, why there is a "duplicate action" to copy+paste when "paste automatically" is enabled.
- you could just click/enter
- you could cmd+click/enter
And to only copy, you press option+click/enter. The same is true when "paste automatically" is disabled, just the duplicate action is then for just copying (just click/enter or cmd+click/enter).
There's really no harm done in having these 2 ways to do things, but it just seemed unnecessary to me. And users probably wont be missing them either, since they expect the default click/enter to do something anyway (depending on their "paste automatically" setting, and thus wont ever use the duplicate option)
There is a lot here, but for the main point about performing an action on paste, there could be no realiable way to listen for CMD+V events and/or perform logic on top of it. I would need to investigate if it's possible at all. If it's doable, then maybe we can introduce the "Action on paste" concept to implement sequential pasting.
Yeah I feared! But then the main point of this issue still stands! Which is this part:
revamp the "Sort by:" Storage settings into two parts entirely actually:
- Action on copy item (via the native cmd+c or similar)
- Action on paste item (via Maccy window or also via the native cmd+v or similar) which would then have options like:
for 1.:
- always put item at top of list (equivalent to "Time of last copy" sorting)
- put only NEW items at top of list (equivalent to "Time of first copy" sorting)
- sort into list by times copied (equivalent to "Number of copies" sorting)
- etc
for 2.:
- do nothing (equivalent to current default behaviour when pressing cmd+v)
- remove item
- put item at bottom of list
- put item at top of list (equivalent to current default behaviour when pasting via Maccy window [since that actually copies the item under the hood])
- etc
I think this is probably the best way, since it doesn't impact previous users, due to the equivalence/compatibility with the previous options, but still allowing more fine grained control for those who need it.
You said:
If [listening to cmd+v is] doable, then maybe we can introduce the "Action on paste" concept to implement sequential pasting.
I don't think we need to wait for that! One can of course still do research in that direction, but for now this "action on paste" is just going to be an "action on 'Maccy paste'" i.e. "on click/enter" when "paste automatically" is enabled and "on option+click/enter" otherwise.
I think that has Maccy having to differentiate then, between the external "copy" of the user "via cmd+c" and the internal "paste" via the interal "copy+paste" so as to not confuse the two. So action 1. would then only act on "cmd+c" and action 2. on "internal paste"
If we'd want just a veery quick (minimal) implementation of the primary point of the issue, I've made a draft pull request
And/Or one could add the option in settings to "delete item on paste" (where paste is only meant as "paste via maccy" for now)
This would already serve me quite well. Please tell me what you think!
After playing around with Carbon, I think it's possible to observe global paste shortcut, so we should be able to implement this behavior w/o popping up Maccy every time.
Now, when it comes to UX, I have concerns. I think there has to be a way to user to say that "I want Maccy to behave like a paste stack" for certain period of time, while not interfering with normal usage. One potential solution would be to:
- Allow selecting multiple elements by holding Shift and pressing arrow keys.
- Pressing Enter creates a stack from the selected items.
- The order of elements in the stack is determined by the order of selection. For example, if you copy 1, 2, 3, they would be shown in Maccy as 3, 2, 1. You can Shift+Down 2 times, which would make the stack - 3, 2, 1. Alternatively, you can highlight 3, then Shift+Up 2 times, which would make the queue - 1, 2, 3.
- Within that stack, pressing Cmd+V would pop the first element from the stack and move it to the end of the stack in Maccy Maccy UI.
- Once the stack is empty, Maccy would switch to normal usage.
- If during stack execution something is copied or pasted outside of Maccy, the stack execution is going to be aborted.
I think this might be more involving from frequent stack users, but at the same time it would allow to avoid going to Settings everyt time you want to turn on/off the "On Paste" behavior. What are your thoughts on this?
Yeah, I've just noticed that the UX - using what I've proposed so far - isn't all that great 😅
This issue (and the related pull request I made) has made me realize that this "paste pushes item to bottom" isn't all that needed, actually! (although the pull request almost successfully implements it as of now)
The (updated) goal is now (as far as my thoughts have come):
(maybe we should update this issue name accordingly, or create a new issue entirely to discuss this)
Have Maccy have 2 modes:
- normal (everything works like it does by default now)
- paste queue
What you just wrote sound really good to me already!
It's just that - if I understand point 3. correctly - it's a little bit harder to fulfill the, in my opinion more used, need (see ***) (imagine I copied 7 items, which I want in a paste queue. With the stack UX as you described, you would have to arrow down (or hover over the item you'd want at the bottom/end of the stack) and then press Shift+Up 7 times)
A small extra way to fix this might be: In general, when holding Shift while hovering over (/ having selected via arrows) an item, the item and all items "above it" (i.e. later in the Maccy stack) would be highlighted, maybe with some visual indicator that these items are about to be put in a paste stack. Importantly, the "selection order" here is one, such that: (Then,) upon pressing enter (as you described) the stack is created - here with the specialty though, that when you create a paste stack while having Shift still pressed, the paste stack is created from the bottom-most selected item to the top-most item of the Maccy stack, such that paste order is then from that bottom-most item until that top-most one.
*** I can copy item1, copy item2, copy item3, then do some very minimal action to mark/put these three items into a paste queue, and then paste, paste, paste emits item1, item2, item3 - in that order
Example to verify we're on the same page here:
(capital letters mean the item(s) is/are selected)
Initial Maccy stack layout (leftmost here is topmost in Maccy):
E - d - c - b - a (tho topmost item is always selected just after opening)
(this ⬇️ would be my most used mode)
When - having selected (via arrows or mouse) item c - holding Shift:
E - D - C - b - a (the "paste stack selection order" here would be, such that pasting would paste like c then d then e)
(This state is equivalent to: - having selected (via arrows or mouse) item c - pressing Shift+Up two times)
Or, When - having selected (via arrows or mouse) item d - pressing Shift+Down two times:
e - D - C - B - a (the "paste stack selection order" here would be, such that pasting would paste like d then c then b)
For ALL cases above: When pressing Enter AND the number of selected items > 1: => create a stack from the selected items (respecting selection order) and apply point 4., 5. and 6. from your response Maybe this means (just for making the selection order easier to implement) that we always create a "mock stack" on item select and on enter the paste stack is created from that "mock stack"?
for visual UX: I would put the paste stack (when it's active) above ALL other items (even above pinned). Such that that visually top-most item is the one that would be pasted next.
Any comments or issues on this?
After playing around with Carbon, I think it's possible to observe global paste shortcut, so we should be able to implement this behavior w/o popping up Maccy every time.
Have you read about how to do this with Quartz or Cocoa? From my limited research (also using AI, so no guarantees there) Carbon is deprecated in modern MacOS versions and might not work anymore in sandboxed apps
First, adding thanks to you @p0deje ! Maccy is awesome
The simplest version of this (as I understand it) is "pop on past", so you can copy a series of things, and then "pop" them back off the list. I've build the bad version of this in a past life for, as @merlondev and many others in #239 described semi-automate transferring text fields back and forward
Perhaps it could take another similar shortcut to opening Maccy? (Cmd + Shift + V)
@p0deje I have a working version for multi-selection/paste stack on the UI side in this branch: https://github.com/weisJ/Maccy/commits/custom/
If you can tell me how to do paste event detection globally I could prototype a working version the proposed workflow in https://github.com/p0deje/Maccy/issues/1175#issuecomment-3179700597
@weisJ I simply tried using KeyboardShorcuts on CMD+V and it worked, so I assumed that whatever Carbon implementation it has underneath can be used too (https://github.com/sindresorhus/KeyboardShortcuts/blob/2927f7037492c193111e753c41fc5588b3317007/Sources/KeyboardShortcuts/CarbonKeyboardShortcuts.swift#L137-L144)
I now have the following working:
Selecting multiple items:
Either use the arrow keys while holding down shift or click individual items while holding down command. Once multi-selection mode is entered moving the mouse no longer auto selects the hovered item. If multi-selection mode is active the items have a badge indicating the order they have been selected in.
Paste stack
Pressing enter while multiple items are selected creates a "Paste stack". The current stack is displayed at the top of the history list (maybe this should be above the pins. Not sure though). When the paste stack is created the first item is copied to the clipboard. After each paste the item is popped from the stack and the next item is copied to the clipboard.
The paste stack remembers the shortcut used to create it i.e. if the shortcut for "paste without formatting" is used, then all pastes from that stack will be copied without formatting. Not sure if it is the most intuitive, however it was the easiest to implement.
The items in the stack only move their position in the history when they are consumed by being copied though popping off an earlier item. After all items have been pasted the items will be at the top of the list in reversed order.
Creating a new paste stack simply replaces the old one
If a copy outside of the stack is detected the stack is discarded. This was the easiest to implement. I am unsure what the most natural behaviour would be here.
Here is a short clip demonstrating the current state:
https://github.com/user-attachments/assets/e2d0478f-f0b5-4150-9cec-1ba90f4f4f45
@weisJ this is awesome!!
My 2c is that the two times you said "Not sure if it is the most intuitive" are both the most intuitive ways for it to behave.
The only other thing to come to mind is cancellation behavior. Cmd + Shift + C again and Esc? Having to copy a new thing doesn't quite feel right
I might pull your branch and give it a whirl. Thanks again
The only other thing to come to mind is cancellation behavior.
Cmd + Shift + Cagain andEsc? Having to copy a new thing doesn't quite feel right
I haven't yet thought about explicit cancellation. Stopping the queue when an external copy happens is due to there not being a clear behaviour what should happen otherwise.
I don't think that Esc is the correct approach here. What if someone opens the popup after a stack has been created. Now there is no way to close it without using the mouse. Esc would clear the stack and copying an item also clears it. My idea would be to somehow reuse the Option + delete shortcut to cancel the stack. Not sure about the details yet though.
@weisJ when is this feature available? I think Option + delete is good option to cancel the stack. I think it's good if you provide a global shortcut button to starting add item to stack, example Cmd + shift + B
We are working on releasing a version with the feature included. However, for now we'll probably not add any additional global shortcut (they may clash with application shortcuts and limit available pin letters). That doesn't mean a "start recording" shortcut will never be added, but we first need to evaluate the design space here.
@weisJ
I tried a simple approach: reversing “Time of last copy” and adding a new option in the dropdown called “LastCopiedAtReversed”. After clearing the history, I can copy items one by one and paste them using Cmd+C followed by Enter. The item that was just pasted moves to the end of the list.
What are your thoughts?
I thought about this approach, but my concern were the following:
- New copies appear at the end of the list. This is quite cumbersome during regular use.
- It seems intuitive enough for "synthetic" short history, but for very long histories it could be unintuitive that items disappear to the end.
- People would need to manually switch to this mode whenever they want stacked pastes and also remember to disable it again when they want to return to normal usage.
That's why the paste stack approach felt the more natural solution to me. The last point above could be mitigated by using a different sorting mechanism depending on which shortcut is used, however that would pollute the global shortcut list with yet another key combination, which is something we generally want to avoid.
Do you have any usability concerns with the paste stack approach? I have to admit that while I use stacked pasting sometimes I am not a heavy user of it and therefore might oversee some UX issues.
@weisJ
My colleagues and I frequently work on data entry tasks, moving information from files, tables, or websites into databases. Previously, we used the classic method: copy in App 1, Cmd+Tab to App 2, find the input field, and paste. In most cases, the data is already structured, and we just need to paste it into the corresponding fields—sometimes even pasting the same data across multiple applications.
While Maccy has already made our work much easier by providing a clipboard history, there is one specific area that could be improved to create a much more efficient workflow.
To illustrate our current workflow with Maccy: everything copied is added to the top of the list, meaning the first item copied becomes the last one in the history. We currently use it this way, but it requires us to scroll to the end of the list every time to find the first item we copied. (see curent workflow gif)
What I am proposing is a "reverse toggle" for the history. When enabled, the first item copied stays at the top (Position 1), the second item at Position 2, and so on. Once an item is pasted, it should automatically move to the end of the history. This way, the next required item is always just one click away at the top of the list, eliminating the need to move the mouse to the bottom of the history. (see Suggested workflow gif)
In the image, I have added a 'reverse toggle' to show that there is no need to add new shortcuts or overcomplicate the program.
Please see the examples below for a better visualization:
1. Current workflow
2. Suggested workflow: simply adding a reverse toggle.
As you can see, in last example, pasting a list where each element has a fixed order is much more convenient. From a UI/UX perspective, it is more advantageous than the current behavior. Furthermore, considering the discussion so far, this method seems simple enough and easy to understand even for non-technical users.
What are your thoughts on this?
PS: Hope I'm not giving you a headache with these suggestions! Since it's almost Christmas, I wish you a wonderful holiday season and a very Merry Christmas!