Skip to content

Add clipboard widget with history, search, and image support#666

Open
stylebending wants to merge 1 commit intoamnweb:mainfrom
stylebending:add-clipboard-widget
Open

Add clipboard widget with history, search, and image support#666
stylebending wants to merge 1 commit intoamnweb:mainfrom
stylebending:add-clipboard-widget

Conversation

@stylebending
Copy link
Contributor

@stylebending stylebending commented Jan 29, 2026

Summary

This PR adds a new clipboard widget to YASB, providing a searchable clipboard history with long text preview and support for both text and images.

Features

Built-in search bar.
Clear history or delete single item.
Preview long text per history item by hovering over it.
Full support for copying and previewing images directly in the history list.

This is my first contribution of this size to a free and open-source project, so any feedback (code, structure, or UX) is very welcome 🙂

Tested with both text and image clipboard content on Windows 11.

@amnweb
Copy link
Owner

amnweb commented Jan 29, 2026

Isn't it better to use the official API to access Windows clipboard data in realtime? https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard

@stylebending
Copy link
Contributor Author

Isn't it better to use the official API to access Windows clipboard data in realtime? https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard

Thanks for the suggestion and the link! That makes sense, and I agree that using the official Windows clipboard API is the better approach for real-time access.

Would you prefer that I update this PR with the new approach, or close it and open a fresh one once the changes are ready?

@amnweb
Copy link
Owner

amnweb commented Jan 30, 2026

Would you prefer that I update this PR with the new approach, or close it and open a fresh one once the changes are ready?

As you wish, your choice.

@stylebending stylebending changed the title Add clipboard widget with history, pinning, search, and image support Add clipboard widget with history, search, and image support Jan 31, 2026
@stylebending
Copy link
Contributor Author

This is as complete as I could get it, only thing missing is the pinning feature but the Python WinRT package doesn't support clipboard pinning it seems. Sorry for the multiple commits.

@amnweb
Copy link
Owner

amnweb commented Feb 4, 2026

I will probably check this this week when I have some free time, but let me know, using WinRT will require having the clipboard enabled in Windows OS, right?

@Video-Nomad
Copy link
Contributor

Thanks for the PR @stylebending. Same issue as with your other PR regarding the new validation schema format. It was a necessary change, so please check other widgets to get the general idea. Also Writing Widgets was updated.

@stylebending
Copy link
Contributor Author

I will probably check this this week when I have some free time, but let me know, using WinRT will require having the clipboard enabled in Windows OS, right?

Yes it specifically requires 'Clipboard History' to be toggled On in Windows System Settings. If disabled, the WinRT API won't have a history buffer to pull from, and the widget will default to 'No items match your search.' I can add a small note to the widgets' README/Docs about this if you think it's necessary!

Thanks for the PR @stylebending. Same issue as with your other PR regarding the new validation schema format. It was a necessary change, so please check other widgets to get the general idea. Also Writing Widgets was updated.

Thanks again for the heads-up! I've updated the validation schema to follow the new Pydantic format, using the other widgets and the updated documentation as a reference. This is ready for another look, let me know if any further tweaks are needed!

@amnweb
Copy link
Owner

amnweb commented Feb 8, 2026

Ok, tested.

  1. This widget requires winrt.windows.applicationmodel.datatransfer to work, which is not defined in the project.
  2. .clipboard-menu .clipboard-item [icon] should use a class name if needed, not [icon].
  3. QScrollBar should be defined inside the widget, same as we have in the GitHub widget, for example.
  4. Style and example are not correct; many things are missing to make this widget work out of the box.
  5. If clipboard is not enabled in Windows, we should show a message inside the widget that users need to enable it.
  6. Remove container_padding: PaddingConfig = PaddingConfig(); this is deprecated, and new widgets should not include it. Just use margin 0,0,0,0 in the widget.
  7. Showing copied text inside the bar looks bad. We need to have an icon inside the config so users can define their own icons or text string for each action, and also delete button icon, copy, copied, etc.
  8. That's all for now what i found...

@stylebending
Copy link
Contributor Author

Thanks for the review! Here's an update on each point:

  1. Done, removed the [icon] CSS selector. The widget uses proper class names now.
  2. Done, scrollbar styles are now injected programmatically on the QScrollArea .
  3. Done, updated the docs CSS example with complete, working styles using hardcoded colors (no CSS variables).
  4. Done, when Clipboard.IsHistoryEnabled() returns false, the popup shows: "Clipboard History is disabled. Enable it in Windows Settings (Win+V)."
  5. Done, removed the deprecated container_padding and replaced by margin 0,0,0,0.
  6. Done, ClipboardIconsConfig provides clear_icon and delete_icon for customization. The "Copied!" feedback is now handled via the copied_feedback option which supports HTML/icons (for example checkmark \uf00c ).

For point 1. it seems like there is no Win32/ctypes equivalent for the clipboard history api, the standard Win32 clipboard API can only access the current clipboard, not the history. Since the project already depends on several winrt.* packages, should we add winrt-windows.applicationmodel.datatransfer to pyproject.toml as a project dependency? Currently I handle this with a try/except fallback and a note for users in the docs to install the small package manually. Would love to hear what you think.

@TheGamer1445891
Copy link

wish the clipboard widget existed for yasb. it will be very useful to replace the win+v keyboard shortcut

@amnweb
Copy link
Owner

amnweb commented Feb 17, 2026

@stylebending thanks. Yeah, I already included datatransfer in the project dependencies because we needed it for the new quick_launch widget, so everything is OK. But I found that the Windows clipboard can be bad in some cases. For example, I have 20 items in history, then I make one big screenshot and copy it to the clipboard, and this deletes all the other items from history. I mean, this is not related to the widget, this is just how Windows works.

@stylebending stylebending force-pushed the add-clipboard-widget branch 5 times, most recently from 45dccd3 to 8668158 Compare February 17, 2026 19:01
@stylebending
Copy link
Contributor Author

stylebending commented Feb 17, 2026

@amnweb great! I've removed the note for users about that package in the widget's docs. This should be ready now.

About the native Windows clipboard history being weird: I feel like for now, only showing the native Windows clipboard is fine. Later/In the future, I would like to add options to use a separate locally stored clipboard history and an option to choose whether to show the preview in a tooltip (by default) or split the clipboard widget window.

@amnweb
Copy link
Owner

amnweb commented Feb 17, 2026

I tested this PR, it works great, but I think there is still room for improvement :)

For example, when you have an image in the history in this widget, you just show [IMAGE]. This can be changed. You can get an idea from my quick_launch widget.
image

Also, the Qt native tooltip looks bad, which is why we have our own set_tooltip function that you should use if you really need it.

@stylebending
Copy link
Contributor Author

stylebending commented Feb 18, 2026

Updated! I've replaced the tooltip, and also made it configurable to enable_tooltip, show_image_thumbnail, image_replacement_text, show_image_tooltip_info, and show_image_list_info. Also improved the example CSS in the docs a bit, let me know what you think @amnweb :)

@amnweb
Copy link
Owner

amnweb commented Feb 18, 2026

image

This tooltip goes over all screens.

@stylebending stylebending force-pushed the add-clipboard-widget branch 2 times, most recently from 28c33cc to ec93b76 Compare February 19, 2026 00:33
@stylebending
Copy link
Contributor Author

stylebending commented Feb 19, 2026

This tooltip goes over all screens.

Thanks for testing again! I've added textwrap for the tooltip, @amnweb please check this out again whenever you have the spare time.

@amnweb
Copy link
Owner

amnweb commented Feb 19, 2026

I think this really should be limited by the number of characters.

image

Image also is problem
image

And by the way, I am not sure why we need a tooltip for images when we can already see them ?

@stylebending
Copy link
Contributor Author

Thanks a lot for helping out! I've removed the tooltip for images, and set the character limit for the text tooltip to 750 characters (it will add three dots "..." at the end to show there's more text).

image

@amnweb
Copy link
Owner

amnweb commented Feb 20, 2026

@stylebending There are still a few things that need to be better. I think you can remove all the hardcoded spacing from item_layout and content_layout, move item_container and content_area to QFrame so everything should work from CSS, and I think you need to set the tooltip on item_container, also set text left, now is centered.
Another thing I noticed is that there are a few things with hardcoded CSS, like buttons. Is there any reason for this? Also, there is background: transparent; in a few places as well.

2026-02-20.20-13-09.mp4

@stylebending
Copy link
Contributor Author

@amnweb I've processed all those points, please try this out with the new CSS example in the widget's docs. All hardcoded CSS is removed except for the QScrollBar (I believe all other widgets have that as well).
Thanks again for helping out!

@amnweb
Copy link
Owner

amnweb commented Feb 23, 2026

Thanks, I think you forgot about the default item spacing :D

container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.setSpacing(0)
        
item_layout.setContentsMargins(0, 0, 0, 0)
item_layout.setSpacing(0)

content_layout.setContentsMargins(0, 0, 0, 0)
content_layout.setSpacing(0)

You should set everything to 0 so we can allow CSS to handle it as users need. Also, I’m not sure about this delete button. It somehow looks bad when it’s stretched. Maybe we can simply add the copy and delete buttons in the same column without stretching them? Or do you have any idea about this?

Edit: What about the thumb? Can we align it to the left like the text as well?

@stylebending
Copy link
Contributor Author

@amnweb added those margins, thanks! 👍
The delete button is now configurable by the user, by default it stays the same size and doesn't stretch, the user can set a min-height in the CSS to make it taller if preferred or change width as well.
The image is now aligned via separate CSS as well in case the user wants to swap image and info position (see below)
Also added an option to swap the image and info positions if the user wants to.
I feel like there's no need for a separate copy button, it's a better user experience being able to click anywhere to copy.
Please test this out with the new config and new CSS whenever you have the spare time. Let me know what you think!

@amnweb
Copy link
Owner

amnweb commented Mar 3, 2026

OK, I have checked all of this carefully now, and there is one part I do not understand well. What is the reason for subclassing the existing PopupWidget and calling _hide_tooltips, hide_animated, and hide?

Another problem I found is that when you copy an item, you end up with duplicated items. I am not sure if this is Windows behavior as well, but we are free to promote the existing history entry to the top inside this popup when we copy it, without duplication.

There are many things I would like to change here, but let me know if there is any real reason for all of the above.

@stylebending
Copy link
Contributor Author

stylebending commented Mar 3, 2026

Another problem I found is that when you copy an item, you end up with duplicated items. I am not sure if this is Windows behavior as well, but we are free to promote the existing history entry to the top inside this popup when we copy it, without duplication.

This widget just shows Windows clipboard history + I've added search functionality. The duplication is how Windows clipboard works (not something I added/made), you can check by pressing Win + V and you will see that Windows clipboard duplicates. You said you wanted this widget to show native Windows clipboard history so that is what this widget does.
The Windows clipboard API doesn't have a promote or re-order method without duplication, correct me if I'm wrong.

What is the reason for subclassing the existing PopupWidget and calling _hide_tooltips, hide_animated, and hide?

Those were added because I was told to switch to the custom tooltip in earlier comments, and I noticed while using the widget with that custom tooltip that the tooltip would not close if I started typing in the search field.

Feel free to change whatever you want.

Edit: Thanks for helping out btw!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants