fix(electrobun): GTK FFI direct resize via gtk_window_resize/move
Electrobun's setSize respects WebView min-size constraint. Bypass it with direct gtk_window_resize() + gtk_window_move() FFI calls. clearMinSizeTree() runs on every resize frame to suppress WebView re-propagation. gtkSetFrame() exported as new RPC endpoint.
This commit is contained in:
parent
e6635e436c
commit
fd2f626c20
3 changed files with 39 additions and 1 deletions
|
|
@ -49,6 +49,14 @@ function getGtk() {
|
||||||
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.i32],
|
args: [FFIType.ptr, FFIType.ptr, FFIType.ptr, FFIType.i32],
|
||||||
returns: FFIType.void,
|
returns: FFIType.void,
|
||||||
},
|
},
|
||||||
|
gtk_window_resize: {
|
||||||
|
args: [FFIType.ptr, FFIType.i32, FFIType.i32],
|
||||||
|
returns: FFIType.void,
|
||||||
|
},
|
||||||
|
gtk_window_move: {
|
||||||
|
args: [FFIType.ptr, FFIType.i32, FFIType.i32],
|
||||||
|
returns: FFIType.void,
|
||||||
|
},
|
||||||
// Container traversal
|
// Container traversal
|
||||||
gtk_bin_get_child: {
|
gtk_bin_get_child: {
|
||||||
args: [FFIType.ptr],
|
args: [FFIType.ptr],
|
||||||
|
|
@ -247,6 +255,28 @@ export function beginMoveDrag(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct GTK resize — bypasses Electrobun's setSize which respects WebView min-size.
|
||||||
|
* Clears min-size tree first, then calls gtk_window_resize + gtk_window_move.
|
||||||
|
*/
|
||||||
|
export function gtkSetFrame(
|
||||||
|
windowPtr: number | bigint,
|
||||||
|
x: number, y: number, width: number, height: number,
|
||||||
|
) {
|
||||||
|
const lib = getGtk();
|
||||||
|
if (!lib) return false;
|
||||||
|
try {
|
||||||
|
// Clear min-size on every frame update during resize
|
||||||
|
clearMinSizeTree(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;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("[gtk-window] gtkSetFrame failed:", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Edge string → GDK_EDGE mapping
|
// Edge string → GDK_EDGE mapping
|
||||||
const EDGE_MAP: Record<string, GdkEdge> = {
|
const EDGE_MAP: Record<string, GdkEdge> = {
|
||||||
n: GDK_EDGE.N, s: GDK_EDGE.S, e: GDK_EDGE.E, w: GDK_EDGE.W,
|
n: GDK_EDGE.N, s: GDK_EDGE.S, e: GDK_EDGE.E, w: GDK_EDGE.W,
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,13 @@ const rpc = BrowserView.defineRPC<PtyRPCSchema>({
|
||||||
return { ok: true };
|
return { ok: true };
|
||||||
} catch (err) { console.error("[window.clearMinSize]", err); return { ok: false }; }
|
} catch (err) { console.error("[window.clearMinSize]", err); return { ok: false }; }
|
||||||
},
|
},
|
||||||
|
"window.gtkSetFrame": ({ x, y, width, height }: { x: number; y: number; width: number; height: number }) => {
|
||||||
|
try {
|
||||||
|
const { gtkSetFrame } = require("./gtk-window.ts");
|
||||||
|
const ok = gtkSetFrame((mainWindow as any).ptr, x, y, width, height);
|
||||||
|
return { ok };
|
||||||
|
} catch (err) { console.error("[window.gtkSetFrame]", err); return { ok: false }; }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
messages: {},
|
messages: {},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,8 @@
|
||||||
if (resizeEdge.includes('s')) height = Math.max(MIN_H, height + dy);
|
if (resizeEdge.includes('s')) height = Math.max(MIN_H, height + dy);
|
||||||
if (resizeEdge.includes('n')) { const nh = Math.max(MIN_H, height - dy); y += height - nh; height = nh; }
|
if (resizeEdge.includes('n')) { const nh = Math.max(MIN_H, height - dy); y += height - nh; height = nh; }
|
||||||
|
|
||||||
appRpc.request['window.setFrame']({ x: Math.round(x), y: Math.round(y), width: Math.round(width), height: Math.round(height) }).catch(() => {});
|
// Use GTK FFI directly — bypasses Electrobun's setSize which respects WebView min-size
|
||||||
|
appRpc.request['window.gtkSetFrame']({ x: Math.round(x), y: Math.round(y), width: Math.round(width), height: Math.round(height) }).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onResizeEnd() {
|
function onResizeEnd() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue