[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:
Mohamed Gharib
2023-06-28 06:35:02 +10:00
committed by GitHub
parent cdbe77a0fc
commit 8acbdc246c
7 changed files with 128 additions and 9 deletions
@@ -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();
}
}
+8 -2
View File
@@ -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