fix(electrobun): set_size_request(1,1) not (-1,-1) + revert to begin_resize_drag
Codex review found: set_size_request(-1,-1) means "use preferred size" which RE-ENABLES WebView content-based minimum. Using (1,1) FORCES a 1x1 minimum, actually overriding the preferred size. Reverted to native begin_resize_drag (WM handles resize smoothly). Fixed onResizeStart sync: e.stopPropagation() now runs BEFORE any async work, preventing sidebar drag handler from intercepting. Removed JS mousemove resize loop — native GTK resize is correct approach.
This commit is contained in:
parent
fd2f626c20
commit
d1583f8ce4
2 changed files with 27 additions and 116 deletions
|
|
@ -102,60 +102,9 @@ export function ensureResizable(windowPtr: number | bigint): boolean {
|
|||
const nowResizable = lib.symbols.gtk_window_get_resizable(windowPtr as any);
|
||||
console.log(`[gtk-window] After set_resizable(true): ${nowResizable}`);
|
||||
}
|
||||
// Override minimum size on the entire widget tree.
|
||||
// WebKitWebView requests min_size = content_size, which GTK propagates
|
||||
// to WM_NORMAL_HINTS, blocking resize. Fix: set -1 (no minimum) recursively.
|
||||
console.log("[gtk-window] Resetting minimum size constraints on widget tree");
|
||||
|
||||
function clearMinSize(widget: any, depth: number) {
|
||||
if (!widget || depth > 10) return;
|
||||
lib!.symbols.gtk_widget_set_size_request(widget, -1, -1);
|
||||
// Try as GtkBin (single child)
|
||||
try {
|
||||
const child = lib!.symbols.gtk_bin_get_child(widget);
|
||||
if (child) {
|
||||
console.log(`[gtk-window] ${" ".repeat(depth)}child (bin)`);
|
||||
clearMinSize(child, depth + 1);
|
||||
}
|
||||
} catch { /* not a GtkBin */ }
|
||||
// Try as GtkContainer (multiple children)
|
||||
try {
|
||||
const list = lib!.symbols.gtk_container_get_children(widget);
|
||||
if (list) {
|
||||
const len = lib!.symbols.g_list_length(list);
|
||||
console.log(`[gtk-window] ${" ".repeat(depth)}container (${len} children)`);
|
||||
for (let i = 0; i < len && i < 20; i++) {
|
||||
const child = lib!.symbols.g_list_nth_data(list, i);
|
||||
if (child) clearMinSize(child, depth + 1);
|
||||
}
|
||||
lib!.symbols.g_list_free(list);
|
||||
}
|
||||
} catch { /* not a GtkContainer */ }
|
||||
}
|
||||
clearMinSize(windowPtr as any, 0);
|
||||
// Set geometry hints with small minimum via GdkGeometry struct
|
||||
// GdkGeometry: min_width(i32), min_height(i32), ... (rest are padding)
|
||||
// GdkWindowHints: GDK_HINT_MIN_SIZE = 1<<1 = 2
|
||||
try {
|
||||
// Allocate GdkGeometry struct (18 ints = 72 bytes)
|
||||
const buf = new ArrayBuffer(72);
|
||||
const view = new Int32Array(buf);
|
||||
view[0] = 400; // min_width
|
||||
view[1] = 300; // min_height
|
||||
view[2] = 32767; // max_width
|
||||
view[3] = 32767; // max_height
|
||||
const GDK_HINT_MIN_SIZE = 2;
|
||||
const GDK_HINT_MAX_SIZE = 4;
|
||||
lib.symbols.gtk_window_set_geometry_hints(
|
||||
windowPtr as any,
|
||||
null, // widget = null → applies to window itself
|
||||
ptr(buf) as any, // GdkGeometry*
|
||||
GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE,
|
||||
);
|
||||
console.log("[gtk-window] Set geometry hints: min=400×300 max=32767×32767");
|
||||
} catch (err) {
|
||||
console.error("[gtk-window] geometry hints failed:", err);
|
||||
}
|
||||
// Force small min-size on entire widget tree (1×1 per widget, 400×300 via geometry hints)
|
||||
console.log("[gtk-window] Forcing small min-size on widget tree");
|
||||
forceSmallMinSize(lib, windowPtr as any);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("[gtk-window] ensureResizable failed:", err);
|
||||
|
|
@ -168,10 +117,17 @@ export function ensureResizable(windowPtr: number | bigint): boolean {
|
|||
* WebKitWebView re-propagates content size as minimum on every layout cycle,
|
||||
* so we must clear it each time — not just at init.
|
||||
*/
|
||||
function clearMinSizeTree(lib: NonNullable<typeof gtk3>, windowPtr: any) {
|
||||
/**
|
||||
* Force small minimum size on the entire widget tree.
|
||||
* Key insight (from Codex review): set_size_request(-1, -1) means "use preferred size"
|
||||
* which RE-ENABLES the WebView's content-based minimum. Using set_size_request(1, 1)
|
||||
* FORCES a 1×1 minimum, overriding the preferred size.
|
||||
*/
|
||||
function forceSmallMinSize(lib: NonNullable<typeof gtk3>, windowPtr: any) {
|
||||
function walk(widget: any, depth: number) {
|
||||
if (!widget || depth > 10) return;
|
||||
lib.symbols.gtk_widget_set_size_request(widget, -1, -1);
|
||||
// Force 1x1 minimum — NOT -1,-1 which means "use preferred size"
|
||||
lib.symbols.gtk_widget_set_size_request(widget, 1, 1);
|
||||
try {
|
||||
const child = lib.symbols.gtk_bin_get_child(widget);
|
||||
if (child) walk(child, depth + 1);
|
||||
|
|
@ -189,7 +145,7 @@ function clearMinSizeTree(lib: NonNullable<typeof gtk3>, windowPtr: any) {
|
|||
} catch { /* not a GtkContainer */ }
|
||||
}
|
||||
walk(windowPtr, 0);
|
||||
// Re-apply geometry hints with small minimum
|
||||
// Set geometry hints: min=400×300 (our real minimum), max=32767×32767
|
||||
try {
|
||||
const buf = new ArrayBuffer(72);
|
||||
const view = new Int32Array(buf);
|
||||
|
|
@ -213,7 +169,7 @@ export function beginResizeDrag(
|
|||
if (!lib) return false;
|
||||
try {
|
||||
// Clear min-size RIGHT BEFORE resize so shrinking is allowed
|
||||
clearMinSizeTree(lib, windowPtr as any);
|
||||
forceSmallMinSize(lib, windowPtr as any);
|
||||
lib.symbols.gtk_window_begin_resize_drag(
|
||||
windowPtr as any,
|
||||
edge,
|
||||
|
|
@ -267,7 +223,7 @@ export function gtkSetFrame(
|
|||
if (!lib) return false;
|
||||
try {
|
||||
// Clear min-size on every frame update during resize
|
||||
clearMinSizeTree(lib, windowPtr as any);
|
||||
forceSmallMinSize(lib, windowPtr as any);
|
||||
lib.symbols.gtk_window_resize(windowPtr as any, Math.max(400, Math.round(width)), Math.max(300, Math.round(height)));
|
||||
lib.symbols.gtk_window_move(windowPtr as any, Math.round(x), Math.round(y));
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue