ui: Add SetInitFocused

Fixes #769
This commit is contained in:
Hajime Hoshi 2020-02-09 23:03:03 +09:00
parent dea716c9a6
commit 77fa0cb9ef
7 changed files with 83 additions and 1 deletions

View File

@ -61,6 +61,7 @@ var (
flagFloating = flag.Bool("floating", false, "make the window floating") flagFloating = flag.Bool("floating", false, "make the window floating")
flagMaximize = flag.Bool("maximize", false, "maximize the window") flagMaximize = flag.Bool("maximize", false, "maximize the window")
flagVsync = flag.Bool("vsync", true, "enable vsync") flagVsync = flag.Bool("vsync", true, "enable vsync")
flagInitFocused = flag.Bool("initfocused", true, "whether the window is focused on start")
) )
func init() { func init() {
@ -420,6 +421,11 @@ func main() {
ebiten.SetWindowResizable(true) ebiten.SetWindowResizable(true)
} }
ebiten.SetInitFocused(*flagInitFocused)
if !*flagInitFocused {
ebiten.SetRunnableOnUnfocused(true)
}
const title = "Window Size (Ebiten Demo)" const title = "Window Size (Ebiten Demo)"
if *flagLegacy { if *flagLegacy {
update := func(screen *ebiten.Image) error { update := func(screen *ebiten.Image) error {

View File

@ -54,6 +54,7 @@ type UI interface {
IsScreenTransparent() bool IsScreenTransparent() bool
SetScreenTransparent(transparent bool) SetScreenTransparent(transparent bool)
SetInitFocused(focused bool)
Input() Input Input() Input
Window() Window Window() Window

View File

@ -79,6 +79,7 @@ const (
Decorated = Hint(0x00020005) Decorated = Hint(0x00020005)
Floating = Hint(0x00020007) Floating = Hint(0x00020007)
Focused = Hint(0x00020001) Focused = Hint(0x00020001)
FocusOnShow = Hint(0x0002000C)
Iconified = Hint(0x00020002) Iconified = Hint(0x00020002)
Maximized = Hint(0x00020008) Maximized = Hint(0x00020008)
Resizable = Hint(0x00020003) Resizable = Hint(0x00020003)

View File

@ -72,6 +72,7 @@ type UserInterface struct {
initWindowMaximized bool initWindowMaximized bool
initScreenTransparent bool initScreenTransparent bool
initIconImages []image.Image initIconImages []image.Image
initFocused bool
vsyncInited bool vsyncInited bool
@ -102,6 +103,8 @@ var (
initWindowPositionYInDP: invalidPos, initWindowPositionYInDP: invalidPos,
initWindowWidthInDP: 640, initWindowWidthInDP: 640,
initWindowHeightInDP: 480, initWindowHeightInDP: 480,
initFocused: true,
vsync: true,
} }
) )
@ -371,6 +374,18 @@ func (u *UserInterface) isInitWindowMaximized() bool {
func (u *UserInterface) setInitWindowMaximized(floating bool) { func (u *UserInterface) setInitWindowMaximized(floating bool) {
u.m.Lock() u.m.Lock()
u.initWindowMaximized = floating u.initWindowMaximized = floating
}
func (u *UserInterface) isInitFocused() bool {
u.m.Lock()
v := u.initFocused
u.m.Unlock()
return v
}
func (u *UserInterface) setInitFocused(focused bool) {
u.m.Lock()
u.initFocused = focused
u.m.Unlock() u.m.Unlock()
} }
@ -693,6 +708,12 @@ func (u *UserInterface) run() error {
} }
glfw.WindowHint(glfw.Floating, floating) glfw.WindowHint(glfw.Floating, floating)
focused := glfw.False
if u.isInitFocused() {
focused = glfw.True
}
glfw.WindowHint(glfw.FocusOnShow, focused)
// Set the window visible explicitly or the application freezes on Wayland (#974). // Set the window visible explicitly or the application freezes on Wayland (#974).
if os.Getenv("WAYLAND_DISPLAY") != "" { if os.Getenv("WAYLAND_DISPLAY") != "" {
glfw.WindowHint(glfw.Visible, glfw.True) glfw.WindowHint(glfw.Visible, glfw.True)
@ -1109,6 +1130,30 @@ func (u *UserInterface) ResetForFrame() {
u.input.resetForFrame() u.input.resetForFrame()
} }
func (u *UserInterface) MonitorPosition() (int, int) {
if !u.isRunning() {
return u.monitorPosition()
}
var mx, my int
_ = u.t.Call(func() error {
mx, my = u.monitorPosition()
return nil
})
return mx, my
}
func (u *UserInterface) SetInitFocused(focused bool) {
if u.isRunning() {
panic("ui: SetInitFocused must be called before the main loop")
}
u.setInitFocused(focused)
}
func (u *UserInterface) monitorPosition() (int, int) {
// TODO: toDeviceIndependentPixel might be required.
return u.currentMonitor().GetPos()
}
func (u *UserInterface) Input() driver.Input { func (u *UserInterface) Input() driver.Input {
return &u.input return &u.input
} }

View File

@ -34,6 +34,7 @@ type UserInterface struct {
runnableOnUnfocused bool runnableOnUnfocused bool
vsync bool vsync bool
running bool running bool
initFocused bool
sizeChanged bool sizeChanged bool
contextLost bool contextLost bool
@ -47,6 +48,7 @@ type UserInterface struct {
var theUI = &UserInterface{ var theUI = &UserInterface{
sizeChanged: true, sizeChanged: true,
vsync: true, vsync: true,
initFocused: true,
} }
func init() { func init() {
@ -404,7 +406,9 @@ func init() {
} }
func (u *UserInterface) Run(context driver.UIContext) error { func (u *UserInterface) Run(context driver.UIContext) error {
canvas.Call("focus") if u.initFocused {
canvas.Call("focus")
}
u.running = true u.running = true
ch := u.loop(context) ch := u.loop(context)
if runtime.GOARCH == "wasm" { if runtime.GOARCH == "wasm" {
@ -460,6 +464,13 @@ func (u *UserInterface) ResetForFrame() {
u.input.resetForFrame() u.input.resetForFrame()
} }
func (u *UserInterface) SetInitFocused(focused bool) {
if u.running {
panic("ui: SetInitFocused must be called before the main loop")
}
u.initFocused = focused
}
func (u *UserInterface) Input() driver.Input { func (u *UserInterface) Input() driver.Input {
return &u.input return &u.input
} }

View File

@ -441,6 +441,10 @@ func (u *UserInterface) ResetForFrame() {
u.input.resetForFrame() u.input.resetForFrame()
} }
func (u *UserInterface) SetInitFocused(focused bool) {
// Do nothing
}
func (u *UserInterface) Input() driver.Input { func (u *UserInterface) Input() driver.Input {
return &u.input return &u.input
} }

14
run.go
View File

@ -618,3 +618,17 @@ func IsScreenTransparent() bool {
func SetScreenTransparent(transparent bool) { func SetScreenTransparent(transparent bool) {
uiDriver().SetScreenTransparent(transparent) uiDriver().SetScreenTransparent(transparent)
} }
// SetInitFocused sets whether the application is focused on show.
// The default value is true, i.e., the application is focused.
// Note that the application does not proceed if this is not focused by default.
// This behavior can be changed by SetRunnableInBackground.
//
// SetInitFocused does nothing on mobile.
//
// SetInitFocused panics if this is called after the main loop.
//
// SetInitFocused is cuncurrent-safe.
func SetInitFocused(focused bool) {
uiDriver().SetInitFocused(focused)
}