diff --git a/core/chooser_test.go b/core/chooser_test.go index 956d31179f..c7e72ed21c 100644 --- a/core/chooser_test.go +++ b/core/chooser_test.go @@ -89,7 +89,7 @@ func TestChooserEditableClick(t *testing.T) { } func TestChooserEditableTextFieldClick(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() b.Styler(func(s *styles.Style) { s.Min.Set(units.Em(20), units.Em(10)) @@ -112,7 +112,7 @@ func TestChooserAllowNewClick(t *testing.T) { } func TestChooserEditableAllowNewClick(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() b.Styler(func(s *styles.Style) { s.Min.Set(units.Em(20), units.Em(10)) @@ -124,7 +124,7 @@ func TestChooserEditableAllowNewClick(t *testing.T) { } func TestChooserEditableAllowNewTextFieldClick(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() b.Styler(func(s *styles.Style) { s.Min.Set(units.Em(20), units.Em(10)) diff --git a/core/filepicker_test.go b/core/filepicker_test.go index 499f1040d9..23c0f6d851 100644 --- a/core/filepicker_test.go +++ b/core/filepicker_test.go @@ -9,7 +9,7 @@ import ( ) func TestFilePicker(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() NewFilePicker(b) b.AssertRender(t, "file-picker/basic") diff --git a/core/form_test.go b/core/form_test.go index 1c1e6dd5b3..3f19d217f2 100644 --- a/core/form_test.go +++ b/core/form_test.go @@ -36,7 +36,7 @@ func (mp *morePerson) FieldWidget(field string) Value { } func TestForm(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() NewForm(b).SetStruct(&person{Name: "Go", Age: 35}) b.AssertRender(t, "form/basic") diff --git a/core/init.go b/core/init.go index 43bb4c819a..67d265d7d0 100644 --- a/core/init.go +++ b/core/init.go @@ -10,8 +10,8 @@ import ( func init() { system.HandleRecover = handleRecover - system.InitScreenLogicalDPIFunc = AppearanceSettings.applyDPI // called when screens are initialized - TheApp.CogentCoreDataDir() // ensure it exists - theWindowGeometrySaver.needToReload() // gets time stamp associated with open, so it doesn't re-open + system.UpdateLogicalDPIScaleFunc = AppearanceSettings.updateLogicalDPI + TheApp.CogentCoreDataDir() // ensure it exists + theWindowGeometrySaver.needToReload() // gets time stamp associated with open, so it doesn't re-open theWindowGeometrySaver.open() } diff --git a/core/renderwindow.go b/core/renderwindow.go index 76a2fcf8be..36bb76167f 100644 --- a/core/renderwindow.go +++ b/core/renderwindow.go @@ -550,9 +550,12 @@ func (w *renderWindow) handleWindowEvents(e events.Event) { } if !TheApp.Platform().IsMobile() { // native desktop if TheApp.NScreens() > 0 { - AppearanceSettings.Apply() + // if TheApp.Platform() == system.Offscreen { // note: this is not necessary, + // // but matches the testing results in subtle ways + // AppearanceSettings.Apply() + // } UpdateAll() - theWindowGeometrySaver.restoreAll() + // theWindowGeometrySaver.restoreAll() } } else { w.resized() diff --git a/core/settings.go b/core/settings.go index 06e0601085..e45ca41186 100644 --- a/core/settings.go +++ b/core/settings.go @@ -383,9 +383,9 @@ func (as *AppearanceSettingsData) Apply() { //types:add as.applyDPI() } -// applyDPI updates the screen LogicalDPI values according to current -// settings and zoom factor, and then updates all open windows as well. -func (as *AppearanceSettingsData) applyDPI() { +// updateLogicalDPI updates the screen LogicalDPI values according to current +// settings and zoom factor. set this as [system.UpdateLogicalDPIFunc] function. +func (as *AppearanceSettingsData) updateLogicalDPI() { // zoom is percentage, but LogicalDPIScale is multiplier system.LogicalDPIScale = as.Zoom / 100 // fmt.Println("system ldpi:", system.LogicalDPIScale) @@ -401,6 +401,12 @@ func (as *AppearanceSettingsData) applyDPI() { } sc.UpdateLogicalDPI() } +} + +// applyDPI updates the screen LogicalDPI values according to current +// settings and zoom factor, and then updates all open windows as well. +func (as *AppearanceSettingsData) applyDPI() { + as.updateLogicalDPI() for _, w := range AllRenderWindows { w.SystemWindow.SetLogicalDPI(w.SystemWindow.Screen().LogicalDPI) // this isn't DPI-related, but this is the most efficient place to do it diff --git a/core/slider_test.go b/core/slider_test.go index 9bb84caaab..7d13553ff6 100644 --- a/core/slider_test.go +++ b/core/slider_test.go @@ -99,7 +99,7 @@ func TestSliderStart(t *testing.T) { } func TestSliderChange(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() sr := NewSlider(b) n := 0 @@ -142,7 +142,7 @@ func TestSliderChangeClick(t *testing.T) { } func TestSliderInput(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := NewBody() sr := NewSlider(b) n := 0 diff --git a/core/svg.go b/core/svg.go index c7c2c3bd70..33b0e3a1c8 100644 --- a/core/svg.go +++ b/core/svg.go @@ -151,13 +151,14 @@ func (sv *SVG) Render() { if sv.SVG == nil { return } - needsRender := !sv.IsReadOnly() + needsRender := !sv.IsReadOnly() || sv.NeedsRebuild() if !needsRender { if sv.image == nil { needsRender = true } else { - sz := sv.image.Bounds().Size() - if sz != sv.prevSize || sz == (image.Point{}) { + sv.SVG.UpdateSize() + sz := sv.SVG.Geom.Size + if sz != sv.prevSize || sv.image.Bounds().Size() == (image.Point{}) { needsRender = true } } diff --git a/system/driver/android/android.go b/system/driver/android/android.go index 9a4f9b4872..009409f770 100644 --- a/system/driver/android/android.go +++ b/system/driver/android/android.go @@ -352,8 +352,8 @@ func (a *App) MainUI(vm, jniEnv, ctx uintptr) error { a.Scrn.PhysicalDPI = dpi a.Scrn.LogicalDPI = dpi - if system.InitScreenLogicalDPIFunc != nil { - system.InitScreenLogicalDPIFunc() + if system.UpdateLogicalDPIScaleFunc != nil { + system.UpdateLogicalDPIScaleFunc() } physX := 25.4 * float32(widthPx) / dpi diff --git a/system/driver/desktop/app.go b/system/driver/desktop/app.go index 562236dc50..641dedfdaf 100644 --- a/system/driver/desktop/app.go +++ b/system/driver/desktop/app.go @@ -83,11 +83,11 @@ func (a *App) InitGPU() { } func (a *App) NewWindow(opts *system.NewWindowOptions) (system.Window, error) { - if len(a.Windows) == 0 && system.InitScreenLogicalDPIFunc != nil { + if len(a.Windows) == 0 && system.UpdateLogicalDPIScaleFunc != nil { if ScreenDebug { - log.Println("app first new window calling InitScreenLogicalDPIFunc") + log.Println("app first new window calling UpdateLogicalDPIScaleFunc") } - system.InitScreenLogicalDPIFunc() + system.UpdateLogicalDPIScaleFunc() } sc := a.Screens[0] diff --git a/system/driver/desktop/screen.go b/system/driver/desktop/screen.go index 6914ee2fce..4a7cbd6499 100644 --- a/system/driver/desktop/screen.go +++ b/system/driver/desktop/screen.go @@ -35,27 +35,32 @@ var ( // MonitorChange is called when a monitor is connected to or // disconnected from the system. func (a *App) MonitorChange(monitor *glfw.Monitor, event glfw.PeripheralEvent) { - if ScreenDebug { - enm := "Unknown" - if event == glfw.Connected { - enm = "Connected" - } else { - enm = "Disconnected" - } - log.Printf("ScreenDebug: monitorChange: %v event: %v\n", monitor.GetName(), enm) - } - a.GetScreens() - if len(a.Windows) > 0 { - fw := a.Windows[0] + go func() { if ScreenDebug { - log.Println("ScreenDebug: monitorChange: sending screen update") + enm := "Unknown" + if event == glfw.Connected { + enm = "Connected" + } else { + enm = "Disconnected" + } + log.Printf("ScreenDebug: monitorChange: %v event: %v\n", monitor.GetName(), enm) } - fw.Event.Window(events.ScreenUpdate) - } else { - if ScreenDebug { - log.Println("ScreenDebug: monitorChange: no windows, NOT sending screen update") + a.GetScreens() + if len(a.Windows) > 0 { + if ScreenDebug { + log.Println("ScreenDebug: monitorChange: sending screen update") + } + for _, w := range a.Windows { + w.SetLogicalDPI(w.Screen().LogicalDPI) + } + fw := a.Windows[0] + fw.Event.Window(events.ScreenUpdate) + } else { + if ScreenDebug { + log.Println("ScreenDebug: monitorChange: no windows, NOT sending screen update") + } } - } + }() } var lastScreenPoll time.Time @@ -155,9 +160,9 @@ func (a *App) GetScreens() { sc.DevicePixelRatio = 2 sc.PixelSize = sc.Geometry.Max.Mul(2) sc.PhysicalSize = image.Point{344, 222} - sc.UpdatePhysicalDPI() sc.Depth = 24 sc.RefreshRate = 60 + sc.UpdatePhysicalDPI() sc.UpdateLogicalDPI() if ScreenDebug { log.Printf("ScreenDebug: getScreens: MacOS unknown display set to Built-in Retina Display %d:\n%s\n", i, reflectx.StringJSON(sc)) @@ -232,6 +237,9 @@ func (a *App) GetScreens() { a.Screens[1].ScreenNumber = 1 } } + if system.UpdateLogicalDPIScaleFunc != nil { + system.UpdateLogicalDPIScaleFunc() + } } // SaveScreenInfo saves a copy of given screen info to screensAll list if unique diff --git a/system/driver/desktop/window.go b/system/driver/desktop/window.go index 68939d7017..95810a7536 100644 --- a/system/driver/desktop/window.go +++ b/system/driver/desktop/window.go @@ -134,9 +134,6 @@ func (w *Window) Screen() *system.Screen { if w == nil || w.Glw == nil { return TheApp.Screens[0] } - w.Mu.Lock() - defer w.Mu.Unlock() - var sc *system.Screen mon := w.Glw.GetMonitor() // this returns nil for windowed windows -- i.e., most windows // that is super useless it seems. only works for fullscreen @@ -159,6 +156,8 @@ func (w *Window) Screen() *system.Screen { // log.Printf("ScreenDebug: desktop.Window.GetScreenOverlap: %v: got screen: %v\n", w.Nm, sc.Name) // } setScreen: + w.Mu.Lock() + defer w.Mu.Unlock() w.ScreenWindow = sc.Name w.PhysDPI = sc.PhysicalDPI if w.DevicePixelRatio != sc.DevicePixelRatio { @@ -464,21 +463,25 @@ func (w *Window) SetCursorEnabled(enabled, raw bool) { //////// Window Callbacks func (w *Window) Moved(gw *glfw.Window, x, y int) { - w.Mu.Lock() - w.Pos = image.Pt(x, y) - w.Mu.Unlock() - // w.app.GetScreens() // this can crash here on win disconnect.. - w.updateGeometry() // critical to update size etc here. - w.Event.Window(events.WinMove) + go func() { + w.Mu.Lock() + w.Pos = image.Pt(x, y) + w.Mu.Unlock() + // w.app.GetScreens() // this can crash here on win disconnect.. + w.updateGeometry() // critical to update size etc here. + w.Event.Window(events.WinMove) + }() } func (w *Window) WinResized(gw *glfw.Window, width, height int) { - // w.app.GetScreens() // this can crash here on win disconnect.. - if ScreenDebug { - log.Printf("desktop.Window.WinResized: %v: %v (was: %v)\n", w.Nm, image.Pt(width, height), w.PixelSize) - } - w.updateMaximized() - w.updateGeometry() + go func() { + // w.app.GetScreens() // this can crash here on win disconnect.. + if ScreenDebug { + log.Printf("desktop.Window.WinResized: %v: %v (was: %v)\n", w.Nm, image.Pt(width, height), w.PixelSize) + } + w.updateMaximized() + w.updateGeometry() + }() } func (w *Window) updateMaximized() { @@ -511,18 +514,20 @@ func (w *Window) updateGeometry() { } func (w *Window) FbResized(gw *glfw.Window, width, height int) { - if w.Is(system.Fullscreen) { - sc := w.Screen() - width = sc.PixelSize.X - height = sc.PixelSize.Y - } - fbsz := image.Point{width, height} - if w.PixelSize != fbsz { - if ScreenDebug { - log.Printf("desktop.Window.FbResized: %v: %v (was: %v)\n", w.Nm, fbsz, w.PixelSize) + go func() { + if w.Is(system.Fullscreen) { + sc := w.Screen() + width = sc.PixelSize.X + height = sc.PixelSize.Y } - w.updateGeometry() - } + fbsz := image.Point{width, height} + if w.PixelSize != fbsz { + if ScreenDebug { + log.Printf("desktop.Window.FbResized: %v: %v (was: %v)\n", w.Nm, fbsz, w.PixelSize) + } + w.updateGeometry() + } + }() } func (w *Window) OnCloseReq(gw *glfw.Window) { diff --git a/system/driver/ios/ios.go b/system/driver/ios/ios.go index f99c194098..315855d403 100644 --- a/system/driver/ios/ios.go +++ b/system/driver/ios/ios.go @@ -144,8 +144,8 @@ func updateConfig(width, height, orientation int32) { TheApp.Scrn.PhysicalDPI = DisplayMetrics.DPI TheApp.Scrn.LogicalDPI = DisplayMetrics.DPI - if system.InitScreenLogicalDPIFunc != nil { - system.InitScreenLogicalDPIFunc() + if system.UpdateLogicalDPIScaleFunc != nil { + system.UpdateLogicalDPIScaleFunc() } physX := 25.4 * float32(width) / DisplayMetrics.DPI diff --git a/system/driver/offscreen/app.go b/system/driver/offscreen/app.go index 38202fc4a8..84afd84fd2 100644 --- a/system/driver/offscreen/app.go +++ b/system/driver/offscreen/app.go @@ -84,8 +84,8 @@ func (a *App) GetScreens() { sc.PhysicalDPI = dpi sc.LogicalDPI = dpi - if system.InitScreenLogicalDPIFunc != nil { - system.InitScreenLogicalDPIFunc() + if system.UpdateLogicalDPIScaleFunc != nil { + system.UpdateLogicalDPIScaleFunc() } physX := 25.4 * float32(sc.PixelSize.X) / dpi diff --git a/system/driver/web/app.go b/system/driver/web/app.go index c9f0141856..6b7d11bcd0 100644 --- a/system/driver/web/app.go +++ b/system/driver/web/app.go @@ -124,8 +124,8 @@ func (a *App) Resize() { a.Scrn.PhysicalDPI = dpi a.Scrn.LogicalDPI = dpi - if system.InitScreenLogicalDPIFunc != nil { - system.InitScreenLogicalDPIFunc() + if system.UpdateLogicalDPIScaleFunc != nil { + system.UpdateLogicalDPIScaleFunc() } vv := js.Global().Get("visualViewport") diff --git a/system/screen.go b/system/screen.go index f66759320e..426c47f294 100644 --- a/system/screen.go +++ b/system/screen.go @@ -25,6 +25,10 @@ var ( // these can be set from preferences (as in gi/prefs) on a per-screen // basis. LogicalDPIScales map[string]float32 + + // UpdateLogicalDPIScaleFunc is a function that updates the system + // LogicalDPIScale and the per-screen LogicalDPIScales map + UpdateLogicalDPIScaleFunc func() ) // note: fields obtained from QScreen in Qt @@ -217,8 +221,3 @@ func ConstrainWindowGeometry(pos, sz, scSize image.Point) (cpos, csz image.Point } return } - -// InitScreenLogicalDPIFunc is a function that can be set to initialize the -// screen LogicalDPI values based on user preferences etc. Called just before -// first window is opened. -var InitScreenLogicalDPIFunc func() diff --git a/text/textcore/base_test.go b/text/textcore/base_test.go index 42b28aeefa..92daaa44fd 100644 --- a/text/textcore/base_test.go +++ b/text/textcore/base_test.go @@ -91,7 +91,7 @@ func TestBaseOpen(t *testing.T) { } func TestBaseScroll(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := core.NewBody() ed := NewBase(b) ed.Styler(func(s *styles.Style) { @@ -117,7 +117,7 @@ func TestBaseMulti(t *testing.T) { } func TestEditorChange(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := core.NewBody() ed := NewEditor(b) n := 0 @@ -146,7 +146,7 @@ func TestEditorChange(t *testing.T) { } func TestEditorInput(t *testing.T) { - t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") + // t.Skip("todo: unreliable, https://github.com/cogentcore/core/issues/1641") b := core.NewBody() ed := NewEditor(b) n := 0