fix(electrobun): disable WebView sensitivity during resize to prevent grab loss
Codex review #3 identified: the issue is NOT min-size but pointer grab conflict. WebKitGTK steals the WM's X11 pointer grab when cursor enters the WebView during inward resize. Fix: gtk_widget_set_sensitive(webview, false) before begin_resize_drag, re-enable after 5s. Also added findWebView() to cache the deepest GtkBin child pointer for fast access.
This commit is contained in:
parent
300bd30ca3
commit
7bb08697d6
1 changed files with 53 additions and 2 deletions
|
|
@ -104,6 +104,15 @@ function getGtk() {
|
||||||
args: [FFIType.ptr],
|
args: [FFIType.ptr],
|
||||||
returns: FFIType.void,
|
returns: FFIType.void,
|
||||||
},
|
},
|
||||||
|
// Sensitivity (disable input processing on widget)
|
||||||
|
gtk_widget_set_sensitive: {
|
||||||
|
args: [FFIType.ptr, FFIType.bool],
|
||||||
|
returns: FFIType.void,
|
||||||
|
},
|
||||||
|
gtk_widget_get_sensitive: {
|
||||||
|
args: [FFIType.ptr],
|
||||||
|
returns: FFIType.bool,
|
||||||
|
},
|
||||||
// Expand flags
|
// Expand flags
|
||||||
gtk_widget_set_hexpand: {
|
gtk_widget_set_hexpand: {
|
||||||
args: [FFIType.ptr, FFIType.bool],
|
args: [FFIType.ptr, FFIType.bool],
|
||||||
|
|
@ -210,9 +219,41 @@ function forceSmallMinSize(lib: NonNullable<typeof gtk3>, windowPtr: any) {
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Cache the WebView widget pointer for sensitivity toggling during resize */
|
||||||
|
let cachedWebView: any = null;
|
||||||
|
|
||||||
|
function findWebView(lib: NonNullable<typeof gtk3>, windowPtr: any): any {
|
||||||
|
if (cachedWebView) return cachedWebView;
|
||||||
|
try {
|
||||||
|
// Window → container → scrolledwindow/webview
|
||||||
|
let widget = lib.symbols.gtk_bin_get_child(windowPtr);
|
||||||
|
// Walk down the bin chain to find the deepest child (the WebView)
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
const child = lib.symbols.gtk_bin_get_child(widget);
|
||||||
|
if (!child) break;
|
||||||
|
widget = child;
|
||||||
|
}
|
||||||
|
cachedWebView = widget;
|
||||||
|
return widget;
|
||||||
|
} catch { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporarily disable WebView input during resize to prevent grab interference.
|
||||||
|
* Re-enable after resize completes (WM sends configure-event).
|
||||||
|
*/
|
||||||
|
export function setWebViewSensitive(windowPtr: number | bigint, sensitive: boolean) {
|
||||||
|
const lib = getGtk();
|
||||||
|
if (!lib) return;
|
||||||
|
const wv = findWebView(lib, windowPtr as any);
|
||||||
|
if (wv) {
|
||||||
|
lib.symbols.gtk_widget_set_sensitive(wv, sensitive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate resize to the window manager.
|
* Delegate resize to the window manager.
|
||||||
* Clears min-size constraints first so resize-in (shrink) works.
|
* Disables WebView input first to prevent grab interference.
|
||||||
*/
|
*/
|
||||||
export function beginResizeDrag(
|
export function beginResizeDrag(
|
||||||
windowPtr: number | bigint,
|
windowPtr: number | bigint,
|
||||||
|
|
@ -224,8 +265,12 @@ export function beginResizeDrag(
|
||||||
const lib = getGtk();
|
const lib = getGtk();
|
||||||
if (!lib) return false;
|
if (!lib) return false;
|
||||||
try {
|
try {
|
||||||
// Clear min-size RIGHT BEFORE resize so shrinking is allowed
|
// 1. Force small min-size
|
||||||
forceSmallMinSize(lib, windowPtr as any);
|
forceSmallMinSize(lib, windowPtr as any);
|
||||||
|
// 2. Disable WebView input to prevent grab interference
|
||||||
|
const wv = findWebView(lib, windowPtr as any);
|
||||||
|
if (wv) lib.symbols.gtk_widget_set_sensitive(wv, false);
|
||||||
|
// 3. Start WM resize
|
||||||
lib.symbols.gtk_window_begin_resize_drag(
|
lib.symbols.gtk_window_begin_resize_drag(
|
||||||
windowPtr as any,
|
windowPtr as any,
|
||||||
edge,
|
edge,
|
||||||
|
|
@ -234,6 +279,12 @@ export function beginResizeDrag(
|
||||||
Math.round(rootY),
|
Math.round(rootY),
|
||||||
0, // GDK_CURRENT_TIME
|
0, // GDK_CURRENT_TIME
|
||||||
);
|
);
|
||||||
|
// 4. Re-enable WebView after resize drag likely ends
|
||||||
|
// The WM holds the grab until mouse-up. 5s covers long drags.
|
||||||
|
// Shorter would risk re-enabling mid-drag.
|
||||||
|
setTimeout(() => {
|
||||||
|
if (wv) lib.symbols.gtk_widget_set_sensitive(wv, true);
|
||||||
|
}, 5000);
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("[gtk-window] begin_resize_drag failed:", err);
|
console.error("[gtk-window] begin_resize_drag failed:", err);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue