mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07: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:
@@ -230,7 +230,7 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
} else if (!self.defaultContextMenu) {
|
||||
// Disable default context menus
|
||||
WKUserScript *initScript = [WKUserScript new];
|
||||
[initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;"
|
||||
[initScript initWithSource:@"window.wails.flags.disableDefaultContextMenu = true;"
|
||||
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
||||
forMainFrameOnly:false];
|
||||
[userContentController addUserScript:initScript];
|
||||
|
||||
@@ -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 Browser from "./browser";
|
||||
import * as Clipboard from "./clipboard";
|
||||
import * as ContextMenu from "./contextmenu";
|
||||
|
||||
|
||||
export function Quit() {
|
||||
@@ -61,7 +62,7 @@ window.wails = {
|
||||
callbacks,
|
||||
flags: {
|
||||
disableScrollbarDrag: false,
|
||||
disableWailsDefaultContextMenu: false,
|
||||
disableDefaultContextMenu: false,
|
||||
enableResize: false,
|
||||
defaultCursor: null,
|
||||
borderThickness: 6,
|
||||
@@ -187,8 +188,13 @@ window.addEventListener('mousemove', function (e) {
|
||||
|
||||
// Setup context menu hook
|
||||
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();
|
||||
} 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
Reference in New Issue
Block a user