mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 18:05:35 +00:00
app/internal/window: [wasm] add support for insets and cache window-size
Currently, on iOS, the keyboard can block the content since it doesn't trigger the "resize". Now, the `insets` will provide the size of the keyboard (on iOS) and scrollbars. It's compatible with the Android (and desktop), but Chrome automatic resizes the windows, so the `Inset` will be 0. Signed-off-by: Inkeliz <inkeliz@inkeliz.com>
This commit is contained in:
@@ -30,12 +30,15 @@ type window struct {
|
|||||||
clipboardCallback js.Func
|
clipboardCallback js.Func
|
||||||
requestAnimationFrame js.Value
|
requestAnimationFrame js.Value
|
||||||
browserHistory js.Value
|
browserHistory js.Value
|
||||||
|
visualViewport js.Value
|
||||||
cleanfuncs []func()
|
cleanfuncs []func()
|
||||||
touches []js.Value
|
touches []js.Value
|
||||||
composing bool
|
composing bool
|
||||||
requestFocus bool
|
requestFocus bool
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
size f32.Point
|
||||||
|
viewport f32.Point
|
||||||
scale float32
|
scale float32
|
||||||
animating bool
|
animating bool
|
||||||
}
|
}
|
||||||
@@ -56,6 +59,10 @@ func NewWindow(win Callbacks, opts *Options) error {
|
|||||||
}
|
}
|
||||||
w.requestAnimationFrame = w.window.Get("requestAnimationFrame")
|
w.requestAnimationFrame = w.window.Get("requestAnimationFrame")
|
||||||
w.browserHistory = w.window.Get("history")
|
w.browserHistory = w.window.Get("history")
|
||||||
|
w.visualViewport = w.window.Get("visualViewport")
|
||||||
|
if w.visualViewport.IsUndefined() {
|
||||||
|
w.visualViewport = w.window
|
||||||
|
}
|
||||||
w.redraw = w.funcOf(func(this js.Value, args []js.Value) interface{} {
|
w.redraw = w.funcOf(func(this js.Value, args []js.Value) interface{} {
|
||||||
w.animCallback()
|
w.animCallback()
|
||||||
return nil
|
return nil
|
||||||
@@ -73,6 +80,7 @@ func NewWindow(win Callbacks, opts *Options) error {
|
|||||||
w.w.SetDriver(w)
|
w.w.SetDriver(w)
|
||||||
w.blur()
|
w.blur()
|
||||||
w.w.Event(system.StageEvent{Stage: system.StageRunning})
|
w.w.Event(system.StageEvent{Stage: system.StageRunning})
|
||||||
|
w.resize()
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
select {}
|
select {}
|
||||||
}()
|
}()
|
||||||
@@ -123,7 +131,8 @@ func (w *window) cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) addEventListeners() {
|
func (w *window) addEventListeners() {
|
||||||
w.addEventListener(w.window, "resize", func(this js.Value, args []js.Value) interface{} {
|
w.addEventListener(w.visualViewport, "resize", func(this js.Value, args []js.Value) interface{} {
|
||||||
|
w.resize()
|
||||||
w.draw(true)
|
w.draw(true)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -466,14 +475,34 @@ func (w *window) ShowTextInput(show bool) {
|
|||||||
// Close the window. Not implemented for js.
|
// Close the window. Not implemented for js.
|
||||||
func (w *window) Close() {}
|
func (w *window) Close() {}
|
||||||
|
|
||||||
func (w *window) draw(sync bool) {
|
func (w *window) resize() {
|
||||||
width, height, scale, cfg := w.config()
|
w.mu.Lock()
|
||||||
if cfg == (unit.Metric{}) || width == 0 || height == 0 {
|
defer w.mu.Unlock()
|
||||||
|
|
||||||
|
w.scale = float32(w.window.Get("devicePixelRatio").Float())
|
||||||
|
|
||||||
|
rect := w.cnv.Call("getBoundingClientRect")
|
||||||
|
w.size.X = float32(rect.Get("width").Float()) * w.scale
|
||||||
|
w.size.Y = float32(rect.Get("height").Float()) * w.scale
|
||||||
|
|
||||||
|
if vx, vy := w.visualViewport.Get("width"), w.visualViewport.Get("height"); !vx.IsUndefined() && !vy.IsUndefined() {
|
||||||
|
w.viewport.X, w.viewport.Y = float32(vx.Float())*w.scale, float32(vy.Float())*w.scale
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.size.X == 0 || w.size.Y == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.mu.Lock()
|
|
||||||
w.scale = float32(scale)
|
w.cnv.Set("width", int(w.size.X+.5))
|
||||||
w.mu.Unlock()
|
w.cnv.Set("height", int(w.size.Y+.5))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *window) draw(sync bool) {
|
||||||
|
width, height, insets, metric := w.config()
|
||||||
|
if metric == (unit.Metric{}) || width == 0 || height == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
w.w.Event(FrameEvent{
|
w.w.Event(FrameEvent{
|
||||||
FrameEvent: system.FrameEvent{
|
FrameEvent: system.FrameEvent{
|
||||||
Now: time.Now(),
|
Now: time.Now(),
|
||||||
@@ -481,27 +510,23 @@ func (w *window) draw(sync bool) {
|
|||||||
X: width,
|
X: width,
|
||||||
Y: height,
|
Y: height,
|
||||||
},
|
},
|
||||||
Metric: cfg,
|
Insets: insets,
|
||||||
|
Metric: metric,
|
||||||
},
|
},
|
||||||
Sync: sync,
|
Sync: sync,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) config() (int, int, float32, unit.Metric) {
|
func (w *window) config() (int, int, system.Insets, unit.Metric) {
|
||||||
rect := w.cnv.Call("getBoundingClientRect")
|
w.mu.Lock()
|
||||||
width, height := rect.Get("width").Float(), rect.Get("height").Float()
|
defer w.mu.Unlock()
|
||||||
scale := w.window.Get("devicePixelRatio").Float()
|
|
||||||
width *= scale
|
return int(w.size.X + .5), int(w.size.Y + .5), system.Insets{
|
||||||
height *= scale
|
Bottom: unit.Px(w.size.Y - w.viewport.Y),
|
||||||
iw, ih := int(width+.5), int(height+.5)
|
Right: unit.Px(w.size.X - w.viewport.X),
|
||||||
// Adjust internal size of canvas if necessary.
|
}, unit.Metric{
|
||||||
if cw, ch := w.cnv.Get("width").Int(), w.cnv.Get("height").Int(); iw != cw || ih != ch {
|
PxPerDp: w.scale,
|
||||||
w.cnv.Set("width", iw)
|
PxPerSp: w.scale,
|
||||||
w.cnv.Set("height", ih)
|
|
||||||
}
|
|
||||||
return iw, ih, float32(scale), unit.Metric{
|
|
||||||
PxPerDp: float32(scale),
|
|
||||||
PxPerSp: float32(scale),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user