Panels: Right click Reload, use Qt context menu #163
No reviewers
Labels
No labels
area/accessibility
area/dependency
Confirmed
Crash Report
Delayed
Design Issue
Duplicate
Feedback required
Good first issue
kind/bug
kind/cleanup
kind/enhancement
platform/linux
platform/macos
platform/windows
priority/high
Question
Request for Comments
Seeking Other Contributors
Seeking Testers
Won't Fix / By Design
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-obsproject/obs-browser!163
Loading…
Reference in a new issue
No description provided.
Delete branch "custom-context-menu"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
This PR introduces two core changes, split into their own two commits (Gif examples at the end).
It allows for the modification of the contents of the CEF context menu. This is a native capability, and I've used it to perform two minor changes: the first is to enable a Reload option, to refresh the page. The second is to hide the Print option, as it's not needed. I considered also hiding "View page source". Feedback here would be good. This change overall is quite small, and can be used down the line to add/remove any options, whether they're native ones (like the Reload one) or completely custom functions.
Next I added a function to replace the native CEF context menu with a Qt menu. This is also a native capability, and ensures that not only the context menu is consistent with others, but also matches the OBS theme.
The second change went through a few iterations, but in the end I settled on this.
Motivation and Context
The primary motivation is consistency. The context menu for browser docks doesn't currently follow the same design rules as all other context menus in OBS, making it feel out of place and "tacked on". It also behaves unexpectedly when the user presses the context menu key on the keyboard, where it opens two menus where one cannot be closed.
The second motivation is extensibility. By using native CEF functions to modify the dropdown, it opens the doors to further options in the future: like a "Dock Configuration" button, for example. In this case, it starts off simple by adding a much-requested Reload option.
Implementation details:
RunContextMenurequires a "return true" if you're rendering your own context menu (which, we are). The callback can be run synchronously or asynchronously, and has no time limitparamsormodeloutside of this callback." therefore I had to create a new object to store the basics of the contents of the dropdown. Themodelgives us everything we need - thetext,command id,enabledstatus, and menu itemtype.model, we create aQMenuin the UI thread, and populate it with the items, creating separators as needed.exec()was chosen as it's used in other places in OBS, and because it allowed for the smallest bit of code: it synchronously returns whether an action was clicked or not, allowing the ability to then run the necessary CEF callback. If you don't run the Cancel() callback if an item hasn't been chosen, then you can't open the dropdown a second time. The event just never triggers.How Has This Been Tested?
Add a custom browser dock, or enable service integration, and right click anywhere within the webpage. Depending on whether text is selected, and what element you right click on, CEF will give you different options in the context menu. Example: right click a random area where there's no text, and then right click a text input field (the latter will unlock Copy/Paste).
Before:

After:

Types of changes
Checklist:
Rebased with clang-format.
Discussed on call with @WizardCM . Leaving review notes here to help keep a paper trail.
@ -186,6 +194,72 @@ bool QCefBrowserClient::OnBeforePopup(return true;You can probably only check one of these conditions, or check if "Copy" does not exist, since the intent was to not add the Reload button when text is highlighted.
I don't think you need to nest this here if the intent is to always remove the Print menu item.
Also, do we actually need to check if Print is visible? Does it throw an exception/error if you try to remove print if it's not visible?
Discussed with @WizardCM , but I'd split this into a separate function and call it similar to how we use
QMetaObject::invokeMethodelsewhere. That should help with indenting and line length.@ -186,6 +194,72 @@ bool QCefBrowserClient::OnBeforePopup(return true;Done
@ -186,6 +194,72 @@ bool QCefBrowserClient::OnBeforePopup(return true;Done. Even if it doesn't currently throw an exception, I'd rather check before deleting.
I attempted this, but
invokeMethodfrom a non-Qt thread can only invoke slots/signals from QThread.Is this then creating an anonymous slot/signal?
Pretty much?
What happens if a URL overwrites the right-click menu?
@jp9000 Solid question! I have verified on this page that the page's custom context menu takes priority in the correct situations. By the looks of it the CEF code never gets hit, so V8 (Chrome's JavaScript engine) probably handles that internally.