roxane 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0ef9393493008dcc4763293fa6ebd36ebb6fdd891b1e2358100eb442ed729ec
4
- data.tar.gz: 1fbfe739d81d37b48fcaf9ac428db7d60319c864a63e6b3a9ef9819cb305a65f
3
+ metadata.gz: 949821f1324cd761b172fc4b4f7519459b3d70c3a53db0bc9ba3ad694ffe3e80
4
+ data.tar.gz: dd6ea3c05680732a4c6d8cb08702626735675b2035d6cdc1c7822a08e43fac93
5
5
  SHA512:
6
- metadata.gz: 2a84c3f0dc6f20488b7d1bfea51a327fafa1b77e4cd393685645b64e843dc8609c3eeb2a5fc6ab7cff8ec810610cd36afafc8766860003732073b8111464e11f
7
- data.tar.gz: 100d61215f9c9c821da5c76648ac6bebd4b59a19aabf342f8928246fe8530243730a73128c013cdb094d3555f4d9933e5bb5e1ff115b2506dcbdcb4891bb4a8c
6
+ metadata.gz: edbfde719e7560dcd6f2e68c8509be66d44118035fe02009f6d285482583abf14c5f6bcdfc8bb577c62f60db7cd615c720b9ca18f13c7259269fb8bb52b341bf
7
+ data.tar.gz: c70573dc5ad95b1d59ab06ed5714dd88a420410857e5c3fcad2c974834429f19a8679a85b2933408a40f821374064ea675d6f3980e3f7f93a9d720797fdaf243
data/README.md CHANGED
@@ -65,6 +65,15 @@ rake test # host: unit tests only (the asset server); the windowed
65
65
  # smoke test self-skips unless ROXANE_INTEGRATION=1
66
66
  ```
67
67
 
68
+ ## Linux / Wayland note (window size)
69
+
70
+ On GTK3, upstream `libwebview` implements `WEBVIEW_HINT_NONE` with
71
+ `gtk_window_resize`. Under Wayland that does **not** set the initial xdg
72
+ geometry, so floating compositors (e.g. Hyprland) often map the window at a
73
+ tiny 200×200 square; GNOME hides the same bug. Roxane compensates on Linux by
74
+ calling `gtk_window_set_default_size` and briefly pinning a size-request through
75
+ first map (then releasing it so the window stays resizable).
76
+
68
77
  ## Status
69
78
 
70
79
  Early but working. The runtime (window + system webview + invoke/emit bridge +
data/lib/roxane/gtk.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Roxane
4
+ # Direct GTK3 bindings for window-size affordances the webview C API gets wrong
5
+ # on Wayland. libwebview 0.12 (GTK3) implements WEBVIEW_HINT_NONE with
6
+ # gtk_window_resize only; on Wayland that does not set the initial xdg
7
+ # geometry, so the client commits 200×200 and floating compositors (Hyprland,
8
+ # etc.) keep the tiny square. GNOME/Mutter is more forgiving, which hides the
9
+ # bug there. GTK4 webview already uses gtk_window_set_default_size — we do the
10
+ # same from Ruby, plus a brief size-request so the first map advertises the
11
+ # right min/geometry, then release it so the window stays user-resizable.
12
+ #
13
+ # Where libgtk-3 isn't loadable (macOS/Windows — their backends are separate),
14
+ # AVAILABLE is false and callers no-op.
15
+ module Gtk
16
+ extend ::FFI::Library
17
+
18
+ begin
19
+ ffi_lib "libgtk-3.so.0"
20
+ attach_function :gtk_window_set_default_size, [:pointer, :int, :int], :void
21
+ attach_function :gtk_window_resize, [:pointer, :int, :int], :void
22
+ attach_function :gtk_widget_set_size_request, [:pointer, :int, :int], :void
23
+ attach_function :gtk_widget_get_realized, [:pointer], :int
24
+ AVAILABLE = true
25
+ rescue LoadError, ::FFI::NotFoundError
26
+ AVAILABLE = false
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Roxane
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
data/lib/roxane/webkit.rb CHANGED
@@ -19,10 +19,11 @@ module Roxane
19
19
  end
20
20
  end
21
21
 
22
- # GLib main-loop scheduling. g_idle_add is thread-safe and runs the callback
23
- # as a TOP-LEVEL main-loop iteration — a clean stack, never nested inside a
24
- # webview dispatch callback (layout-triggering WebKit calls made from inside
25
- # one can reenter the engine and crash; see the zoom work, 2026-07-03).
22
+ # GLib main-loop scheduling. g_idle_add / g_timeout_add are thread-safe and
23
+ # run the callback as a TOP-LEVEL main-loop iteration — a clean stack, never
24
+ # nested inside a webview dispatch callback (layout-triggering WebKit calls
25
+ # made from inside one can reenter the engine and crash; see the zoom work,
26
+ # 2026-07-03).
26
27
  module GLib
27
28
  extend ::FFI::Library
28
29
 
@@ -30,6 +31,7 @@ module Roxane
30
31
  ffi_lib "libglib-2.0.so.0"
31
32
  callback :g_source_func, [:pointer], :int
32
33
  attach_function :g_idle_add, [:g_source_func, :pointer], :uint
34
+ attach_function :g_timeout_add, [:uint, :g_source_func, :pointer], :uint
33
35
  AVAILABLE = true
34
36
  rescue LoadError, ::FFI::NotFoundError
35
37
  AVAILABLE = false
data/lib/roxane/window.rb CHANGED
@@ -132,9 +132,59 @@ module Roxane
132
132
  private
133
133
 
134
134
  def apply_size(size, min_size, resizable)
135
- width, height = size
135
+ width, height = Integer(size[0]), Integer(size[1])
136
136
  FFI.webview_set_size(@w, width, height, resizable ? FFI::HINT_NONE : FFI::HINT_FIXED)
137
137
  FFI.webview_set_size(@w, min_size[0], min_size[1], FFI::HINT_MIN) if min_size && resizable
138
+ # GTK3/Wayland: compensate for libwebview using gtk_window_resize (ignored
139
+ # as initial geometry). No-ops on macOS/Windows where Gtk is unavailable.
140
+ apply_gtk_wayland_size(width, height, min_size, resizable)
141
+ end
142
+
143
+ # See Roxane::Gtk — set_default_size + a temporary size-request so the first
144
+ # xdg configure isn't 200×200 under floating Wayland compositors.
145
+ def apply_gtk_wayland_size(width, height, min_size, resizable)
146
+ return unless Gtk::AVAILABLE && GLib::AVAILABLE
147
+
148
+ handle = FFI.webview_get_native_handle(@w, FFI::NATIVE_HANDLE_UI_WINDOW)
149
+ return if handle.null?
150
+
151
+ Gtk.gtk_window_set_default_size(handle, width, height)
152
+ return unless resizable
153
+
154
+ # Pin geometry through the first map, then release so the user can shrink.
155
+ # (Non-resizable windows keep webview's FIXED size-request permanently.)
156
+ Gtk.gtk_widget_set_size_request(handle, width, height)
157
+ release_initial_gtk_size_request(width, height, min_size)
158
+ end
159
+
160
+ # Poll until the GtkWindow is realized (shown), then drop the temporary
161
+ # size-request. Scheduled from construction — safe if run() is delayed;
162
+ # continues until realize or the window is destroyed.
163
+ def release_initial_gtk_size_request(width, height, min_size)
164
+ state = { seen_realized: false }
165
+ cb = ::FFI::Function.new(:int, [:pointer]) do |_data|
166
+ handle = FFI.webview_get_native_handle(@w, FFI::NATIVE_HANDLE_UI_WINDOW)
167
+ if handle.null?
168
+ 0 # G_SOURCE_REMOVE — window gone
169
+ elsif Gtk.gtk_widget_get_realized(handle) == 0
170
+ 1 # G_SOURCE_CONTINUE — not mapped yet
171
+ elsif !state[:seen_realized]
172
+ # One extra tick after realize so the compositor has acked min_size.
173
+ state[:seen_realized] = true
174
+ 1
175
+ else
176
+ if min_size
177
+ Gtk.gtk_widget_set_size_request(handle, Integer(min_size[0]), Integer(min_size[1]))
178
+ else
179
+ Gtk.gtk_widget_set_size_request(handle, -1, -1)
180
+ end
181
+ Gtk.gtk_window_set_default_size(handle, width, height)
182
+ Gtk.gtk_window_resize(handle, width, height)
183
+ 0 # G_SOURCE_REMOVE
184
+ end
185
+ end
186
+ @callbacks << cb
187
+ GLib.g_timeout_add(50, cb, nil)
138
188
  end
139
189
 
140
190
  # One persistent dispatch callback drains a queue of procs on the UI thread —
data/lib/roxane.rb CHANGED
@@ -37,5 +37,6 @@ end
37
37
 
38
38
  require_relative "roxane/ffi"
39
39
  require_relative "roxane/webkit"
40
+ require_relative "roxane/gtk"
40
41
  require_relative "roxane/static_server"
41
42
  require_relative "roxane/window"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roxane
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - BKK Riese
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-03 00:00:00.000000000 Z
11
+ date: 2026-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -39,6 +39,7 @@ files:
39
39
  - assets/bridge.js
40
40
  - lib/roxane.rb
41
41
  - lib/roxane/ffi.rb
42
+ - lib/roxane/gtk.rb
42
43
  - lib/roxane/static_server.rb
43
44
  - lib/roxane/version.rb
44
45
  - lib/roxane/webkit.rb