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],
|
||||
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
|
||||
gtk_widget_set_hexpand: {
|
||||
args: [FFIType.ptr, FFIType.bool],
|
||||
|
|
@ -210,9 +219,41 @@ function forceSmallMinSize(lib: NonNullable<typeof gtk3>, windowPtr: any) {
|
|||
} 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.
|
||||
* Clears min-size constraints first so resize-in (shrink) works.
|
||||
* Disables WebView input first to prevent grab interference.
|
||||
*/
|
||||
export function beginResizeDrag(
|
||||
windowPtr: number | bigint,
|
||||
|
|
@ -224,8 +265,12 @@ export function beginResizeDrag(
|
|||
const lib = getGtk();
|
||||
if (!lib) return false;
|
||||
try {
|
||||
// Clear min-size RIGHT BEFORE resize so shrinking is allowed
|
||||
// 1. Force small min-size
|
||||
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(
|
||||
windowPtr as any,
|
||||
edge,
|
||||
|
|
@ -234,6 +279,12 @@ export function beginResizeDrag(
|
|||
Math.round(rootY),
|
||||
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;
|
||||
} catch (err) {
|
||||
console.error("[gtk-window] begin_resize_drag failed:", err);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue