mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:51:26 +08:00
[v2] Add smart default context-menu functionality (backported from v3) (#2748)
* [v2] Add smart default context-menu functionality (backported from v3) * Update changelog
This commit is contained in:
parent
cdbe77a0fc
commit
8acbdc246c
@ -230,7 +230,7 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
|||||||
} else if (!self.defaultContextMenu) {
|
} else if (!self.defaultContextMenu) {
|
||||||
// Disable default context menus
|
// Disable default context menus
|
||||||
WKUserScript *initScript = [WKUserScript new];
|
WKUserScript *initScript = [WKUserScript new];
|
||||||
[initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;"
|
[initScript initWithSource:@"window.wails.flags.disableDefaultContextMenu = true;"
|
||||||
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
||||||
forMainFrameOnly:false];
|
forMainFrameOnly:false];
|
||||||
[userContentController addUserScript:initScript];
|
[userContentController addUserScript:initScript];
|
||||||
|
50
v2/internal/frontend/runtime/desktop/contextmenu.js
Normal file
50
v2/internal/frontend/runtime/desktop/contextmenu.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
--default-contextmenu: auto; (default) will show the default context menu if contentEditable is true OR text has been selected OR element is input or textarea
|
||||||
|
--default-contextmenu: show; will always show the default context menu
|
||||||
|
--default-contextmenu: hide; will always hide the default context menu
|
||||||
|
|
||||||
|
This rule is inherited like normal CSS rules, so nesting works as expected
|
||||||
|
*/
|
||||||
|
export function processDefaultContextMenu(event) {
|
||||||
|
// Process default context menu
|
||||||
|
const element = event.target;
|
||||||
|
const computedStyle = window.getComputedStyle(element);
|
||||||
|
const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim();
|
||||||
|
switch (defaultContextMenuAction) {
|
||||||
|
case "show":
|
||||||
|
return;
|
||||||
|
case "hide":
|
||||||
|
event.preventDefault();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
// Check if contentEditable is true
|
||||||
|
if (element.isContentEditable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if text has been selected and action is on the selected elements
|
||||||
|
const selection = window.getSelection();
|
||||||
|
const hasSelection = (selection.toString().length > 0)
|
||||||
|
if (hasSelection) {
|
||||||
|
for (let i = 0; i < selection.rangeCount; i++) {
|
||||||
|
const range = selection.getRangeAt(i);
|
||||||
|
const rects = range.getClientRects();
|
||||||
|
for (let j = 0; j < rects.length; j++) {
|
||||||
|
const rect = rects[j];
|
||||||
|
if (document.elementFromPoint(rect.left, rect.top) === element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if tagname is input or textarea
|
||||||
|
if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") {
|
||||||
|
if (hasSelection || (!element.readOnly && !element.disabled)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide default context menu
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ import * as Window from "./window";
|
|||||||
import * as Screen from "./screen";
|
import * as Screen from "./screen";
|
||||||
import * as Browser from "./browser";
|
import * as Browser from "./browser";
|
||||||
import * as Clipboard from "./clipboard";
|
import * as Clipboard from "./clipboard";
|
||||||
|
import * as ContextMenu from "./contextmenu";
|
||||||
|
|
||||||
|
|
||||||
export function Quit() {
|
export function Quit() {
|
||||||
@ -61,7 +62,7 @@ window.wails = {
|
|||||||
callbacks,
|
callbacks,
|
||||||
flags: {
|
flags: {
|
||||||
disableScrollbarDrag: false,
|
disableScrollbarDrag: false,
|
||||||
disableWailsDefaultContextMenu: false,
|
disableDefaultContextMenu: false,
|
||||||
enableResize: false,
|
enableResize: false,
|
||||||
defaultCursor: null,
|
defaultCursor: null,
|
||||||
borderThickness: 6,
|
borderThickness: 6,
|
||||||
@ -187,8 +188,13 @@ window.addEventListener('mousemove', function (e) {
|
|||||||
|
|
||||||
// Setup context menu hook
|
// Setup context menu hook
|
||||||
window.addEventListener('contextmenu', function (e) {
|
window.addEventListener('contextmenu', function (e) {
|
||||||
if (window.wails.flags.disableWailsDefaultContextMenu) {
|
// always show the contextmenu in debug & dev
|
||||||
|
if (DEBUG) return;
|
||||||
|
|
||||||
|
if (window.wails.flags.disableDefaultContextMenu) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
} else {
|
||||||
|
ContextMenu.processDefaultContextMenu(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -420,8 +420,28 @@ Type: `string`
|
|||||||
|
|
||||||
### EnableDefaultContextMenu
|
### EnableDefaultContextMenu
|
||||||
|
|
||||||
EnableDefaultContextMenu enables the browser's default context-menu in production (Without the devtools inspector).
|
EnableDefaultContextMenu enables the browser's default context-menu in production.
|
||||||
This menu is already enabled in development, as well as in debug builds and production builds with the `-devtools` flag.
|
|
||||||
|
By default, the browser's default context-menu is only available in development and in a `-debug` or `-devtools` [build](../reference/cli.mdx#build) along with the devtools inspector, Using this option you can enable the default context-menu in `production` while the devtools inspector won't be available unless the `-devtools` build flag is used.
|
||||||
|
|
||||||
|
When this option is enabled, by default the context-menu will only be shown for text contexts (where Cut/Copy/Paste is needed), to override this behavior, you can use the CSS property `--default-contextmenu` on any HTML element (including the `body`) with the following values :
|
||||||
|
|
||||||
|
| CSS Style | Behavior |
|
||||||
|
|--------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `--default-contextmenu: auto;` | (**default**) will show the default context menu only if :<br/> contentEditable is true OR text has been selected OR element is input or textarea |
|
||||||
|
| `--default-contextmenu: show;` | will always show the default context menu |
|
||||||
|
| `--default-contextmenu: hide;` | will always hide the default context menu |
|
||||||
|
|
||||||
|
This rule is inherited like any normal CSS rule, so nesting works as expected.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
This filtering functionality is only enabled in production, so in development and in debug build, the full context-menu is always available everywhere.
|
||||||
|
:::
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
This filtering functionality is NOT a security measure, the developer should expect that the full context-menu could be leaked anytime which could contain commands like (Download image, Reload, Save webpage), if this is a concern, the developer SHOULD NOT enable the default context-menu.
|
||||||
|
:::
|
||||||
|
|
||||||
|
|
||||||
Name: EnableDefaultContextMenu<br/>
|
Name: EnableDefaultContextMenu<br/>
|
||||||
Type: `bool`
|
Type: `bool`
|
||||||
|
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725)
|
- Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725)
|
||||||
- Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733)
|
- Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733)
|
||||||
|
- Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user