mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
ebiten: add SetWindowMousePassthrough and IsWindowMousePassthrough
Closes #2511
This commit is contained in:
parent
c8d38f7f25
commit
14f2ee198e
@ -142,6 +142,7 @@ func main() {
|
||||
ebiten.SetWindowDecorated(false)
|
||||
ebiten.SetWindowFloating(true)
|
||||
ebiten.SetWindowSize(width, height)
|
||||
ebiten.SetWindowMousePassthrough(true)
|
||||
|
||||
op := &ebiten.RunGameOptions{}
|
||||
op.ScreenTransparent = true
|
||||
|
@ -147,6 +147,7 @@ func (g *game) Update() error {
|
||||
floating := ebiten.IsWindowFloating()
|
||||
resizingMode := ebiten.WindowResizingMode()
|
||||
screenCleared := ebiten.IsScreenClearedEveryFrame()
|
||||
mousePassthrough := ebiten.IsWindowMousePassthrough()
|
||||
|
||||
const d = 16
|
||||
toUpdateWindowSize := false
|
||||
@ -267,6 +268,9 @@ func (g *game) Update() error {
|
||||
restore = inpututil.IsKeyJustPressed(ebiten.KeyE)
|
||||
}
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyP) {
|
||||
mousePassthrough = !mousePassthrough
|
||||
}
|
||||
|
||||
if toUpdateWindowSize {
|
||||
g.width = screenWidth
|
||||
@ -304,6 +308,8 @@ func (g *game) Update() error {
|
||||
ebiten.SetWindowIcon([]image.Image{createRandomIconImage()})
|
||||
}
|
||||
|
||||
ebiten.SetWindowMousePassthrough(mousePassthrough)
|
||||
|
||||
g.count++
|
||||
return nil
|
||||
}
|
||||
@ -357,6 +363,7 @@ func (g *game) Draw(screen *ebiten.Image) {
|
||||
[D] Switch the window decoration (only for desktops)
|
||||
[L] Switch the window floating state (only for desktops)
|
||||
[W] Switch whether to skip clearing the screen
|
||||
[P] Switch whether a mouse cursor passthroughs the window (only for desktops)
|
||||
%s
|
||||
IsFocused?: %s
|
||||
Window Position: (%d, %d)
|
||||
|
@ -84,16 +84,17 @@ type userInterfaceImpl struct {
|
||||
initFullscreenWidthInDIP int
|
||||
initFullscreenHeightInDIP int
|
||||
|
||||
initFullscreen bool
|
||||
initCursorMode CursorMode
|
||||
initWindowDecorated bool
|
||||
initWindowMonitor int
|
||||
initWindowPositionXInDIP int
|
||||
initWindowPositionYInDIP int
|
||||
initWindowWidthInDIP int
|
||||
initWindowHeightInDIP int
|
||||
initWindowFloating bool
|
||||
initWindowMaximized bool
|
||||
initFullscreen bool
|
||||
initCursorMode CursorMode
|
||||
initWindowDecorated bool
|
||||
initWindowMonitor int
|
||||
initWindowPositionXInDIP int
|
||||
initWindowPositionYInDIP int
|
||||
initWindowWidthInDIP int
|
||||
initWindowHeightInDIP int
|
||||
initWindowFloating bool
|
||||
initWindowMaximized bool
|
||||
initWindowMousePassthrough bool
|
||||
|
||||
// bufferOnceSwapped must be accessed from the main thread.
|
||||
bufferOnceSwapped bool
|
||||
@ -525,6 +526,18 @@ func (u *userInterfaceImpl) setInitWindowMaximized(maximized bool) {
|
||||
u.m.Unlock()
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) isInitWindowMousePassthrough() bool {
|
||||
u.m.RLock()
|
||||
defer u.m.RUnlock()
|
||||
return u.initWindowMousePassthrough
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) setInitWindowMousePassthrough(enabled bool) {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
u.initWindowMousePassthrough = enabled
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) isWindowClosingHandled() bool {
|
||||
u.m.RLock()
|
||||
v := u.windowClosingHandled
|
||||
@ -984,6 +997,12 @@ func (u *userInterfaceImpl) initOnMainThread(options *RunOptions) error {
|
||||
}
|
||||
glfw.WindowHint(glfw.FocusOnShow, focused)
|
||||
|
||||
mousePassthrough := glfw.False
|
||||
if u.isInitWindowMousePassthrough() {
|
||||
mousePassthrough = glfw.True
|
||||
}
|
||||
glfw.WindowHint(glfw.MousePassthrough, mousePassthrough)
|
||||
|
||||
// Set the window visible explicitly or the application freezes on Wayland (#974).
|
||||
if os.Getenv("WAYLAND_DISPLAY") != "" {
|
||||
glfw.WindowHint(glfw.Visible, glfw.True)
|
||||
@ -1717,6 +1736,19 @@ func (u *userInterfaceImpl) setOrigWindowPos(x, y int) {
|
||||
u.origWindowPosY = y
|
||||
}
|
||||
|
||||
// setWindowMousePassthrough must be called from the main thread.
|
||||
func (u *userInterfaceImpl) setWindowMousePassthrough(enabled bool) {
|
||||
if microsoftgdk.IsXbox() {
|
||||
return
|
||||
}
|
||||
|
||||
v := glfw.False
|
||||
if enabled {
|
||||
v = glfw.True
|
||||
}
|
||||
u.window.SetAttrib(glfw.MousePassthrough, v)
|
||||
}
|
||||
|
||||
func IsScreenTransparentAvailable() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ type Window interface {
|
||||
Restore()
|
||||
SetClosingHandled(handled bool)
|
||||
IsClosingHandled() bool
|
||||
SetMousePassthrough(enabled bool)
|
||||
IsMousePassthrough() bool
|
||||
}
|
||||
|
||||
type nullWindow struct{}
|
||||
@ -119,3 +121,10 @@ func (*nullWindow) SetClosingHandled(handled bool) {
|
||||
func (*nullWindow) IsClosingHandled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (*nullWindow) SetMousePassthrough(enabled bool) {
|
||||
}
|
||||
|
||||
func (*nullWindow) IsMousePassthrough() bool {
|
||||
return false
|
||||
}
|
||||
|
@ -387,3 +387,36 @@ func (w *glfwWindow) SetClosingHandled(handled bool) {
|
||||
func (w *glfwWindow) IsClosingHandled() bool {
|
||||
return w.ui.isWindowClosingHandled()
|
||||
}
|
||||
|
||||
func (w *glfwWindow) SetMousePassthrough(enabled bool) {
|
||||
if w.ui.isTerminated() {
|
||||
return
|
||||
}
|
||||
if !w.ui.isRunning() {
|
||||
w.ui.setInitWindowMousePassthrough(enabled)
|
||||
return
|
||||
}
|
||||
w.ui.mainThread.Call(func() {
|
||||
if w.ui.isTerminated() {
|
||||
return
|
||||
}
|
||||
w.ui.setWindowMousePassthrough(enabled)
|
||||
})
|
||||
}
|
||||
|
||||
func (w *glfwWindow) IsMousePassthrough() bool {
|
||||
if w.ui.isTerminated() {
|
||||
return false
|
||||
}
|
||||
if !w.ui.isRunning() {
|
||||
return w.ui.isInitWindowMousePassthrough()
|
||||
}
|
||||
var v bool
|
||||
w.ui.mainThread.Call(func() {
|
||||
if w.ui.isTerminated() {
|
||||
return
|
||||
}
|
||||
v = w.ui.window.GetAttrib(glfw.MousePassthrough) == glfw.True
|
||||
})
|
||||
return v
|
||||
}
|
||||
|
50
window.go
50
window.go
@ -54,7 +54,7 @@ func IsWindowDecorated() bool {
|
||||
// The window is decorated by default.
|
||||
//
|
||||
// SetWindowDecorated works only on desktops.
|
||||
// SetWindowDecorated does nothing on other platforms.
|
||||
// SetWindowDecorated does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowDecorated is concurrent-safe.
|
||||
func SetWindowDecorated(decorated bool) {
|
||||
@ -99,7 +99,7 @@ func SetWindowResizable(resizable bool) {
|
||||
|
||||
// SetWindowTitle sets the title of the window.
|
||||
//
|
||||
// SetWindowTitle does nothing on browsers or mobiles.
|
||||
// SetWindowTitle does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowTitle is concurrent-safe.
|
||||
func SetWindowTitle(title string) {
|
||||
@ -123,7 +123,7 @@ func SetWindowTitle(title string) {
|
||||
//
|
||||
// As macOS windows don't have icons, SetWindowIcon doesn't work on macOS.
|
||||
//
|
||||
// SetWindowIcon doesn't work on browsers or mobiles.
|
||||
// SetWindowIcon doesn't work if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowIcon is concurrent-safe.
|
||||
func SetWindowIcon(iconImages []image.Image) {
|
||||
@ -138,7 +138,7 @@ func SetWindowIcon(iconImages []image.Image) {
|
||||
//
|
||||
// WindowPosition returns the original window position in fullscreen mode.
|
||||
//
|
||||
// WindowPosition returns (0, 0) on browsers and mobiles.
|
||||
// WindowPosition returns (0, 0) if the platform is not a desktop.
|
||||
//
|
||||
// WindowPosition is concurrent-safe.
|
||||
func WindowPosition() (x, y int) {
|
||||
@ -151,7 +151,7 @@ func WindowPosition() (x, y int) {
|
||||
//
|
||||
// SetWindowPosition sets the original window position in fullscreen mode.
|
||||
//
|
||||
// SetWindowPosition does nothing on browsers and mobiles.
|
||||
// SetWindowPosition does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowPosition is concurrent-safe.
|
||||
func SetWindowPosition(x, y int) {
|
||||
@ -215,7 +215,7 @@ func SetWindowSizeLimits(minw, minh, maxw, maxh int) {
|
||||
|
||||
// IsWindowFloating reports whether the window is always shown above all the other windows.
|
||||
//
|
||||
// IsWindowFloating returns false on browsers and mobiles.
|
||||
// IsWindowFloating returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowFloating is concurrent-safe.
|
||||
func IsWindowFloating() bool {
|
||||
@ -224,7 +224,7 @@ func IsWindowFloating() bool {
|
||||
|
||||
// SetWindowFloating sets the state whether the window is always shown above all the other windows.
|
||||
//
|
||||
// SetWindowFloating does nothing on browsers or mobiles.
|
||||
// SetWindowFloating does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowFloating is concurrent-safe.
|
||||
func SetWindowFloating(float bool) {
|
||||
@ -235,7 +235,7 @@ func SetWindowFloating(float bool) {
|
||||
//
|
||||
// MaximizeWindow does nothing when the window is not resizable (WindowResizingModeEnabled).
|
||||
//
|
||||
// MaximizeWindow does nothing on browsers or mobiles.
|
||||
// MaximizeWindow does nothing if the platform is not a desktop.
|
||||
//
|
||||
// MaximizeWindow is concurrent-safe.
|
||||
func MaximizeWindow() {
|
||||
@ -246,7 +246,7 @@ func MaximizeWindow() {
|
||||
//
|
||||
// IsWindowMaximized returns false when the window is not resizable (WindowResizingModeEnabled).
|
||||
//
|
||||
// IsWindowMaximized always returns false on browsers and mobiles.
|
||||
// IsWindowMaximized always returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowMaximized is concurrent-safe.
|
||||
func IsWindowMaximized() bool {
|
||||
@ -257,7 +257,7 @@ func IsWindowMaximized() bool {
|
||||
//
|
||||
// If the main loop does not start yet, MinimizeWindow does nothing.
|
||||
//
|
||||
// MinimizeWindow does nothing on browsers or mobiles.
|
||||
// MinimizeWindow does nothing if the platform is not a desktop.
|
||||
//
|
||||
// MinimizeWindow is concurrent-safe.
|
||||
func MinimizeWindow() {
|
||||
@ -266,7 +266,7 @@ func MinimizeWindow() {
|
||||
|
||||
// IsWindowMinimized reports whether the window is minimized or not.
|
||||
//
|
||||
// IsWindowMinimized always returns false on browsers and mobiles.
|
||||
// IsWindowMinimized always returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowMinimized is concurrent-safe.
|
||||
func IsWindowMinimized() bool {
|
||||
@ -289,7 +289,7 @@ func RestoreWindow() {
|
||||
// As the window is closed immediately by default,
|
||||
// you might want to call SetWindowClosingHandled(true) to prevent the window is automatically closed.
|
||||
//
|
||||
// IsWindowBeingClosed always returns false on other platforms.
|
||||
// IsWindowBeingClosed always returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowBeingClosed is concurrent-safe.
|
||||
func IsWindowBeingClosed() bool {
|
||||
@ -304,7 +304,7 @@ func IsWindowBeingClosed() bool {
|
||||
// To end the game, you have to return an error value at the Game's Update function.
|
||||
//
|
||||
// SetWindowClosingHandled works only on desktops.
|
||||
// SetWindowClosingHandled does nothing on other platforms.
|
||||
// SetWindowClosingHandled does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowClosingHandled is concurrent-safe.
|
||||
func SetWindowClosingHandled(handled bool) {
|
||||
@ -313,9 +313,31 @@ func SetWindowClosingHandled(handled bool) {
|
||||
|
||||
// IsWindowClosingHandled reports whether the window closing is handled or not on desktops by SetWindowClosingHandled.
|
||||
//
|
||||
// IsWindowClosingHandled always returns false on other platforms.
|
||||
// IsWindowClosingHandled always returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowClosingHandled is concurrent-safe.
|
||||
func IsWindowClosingHandled() bool {
|
||||
return ui.Get().Window().IsClosingHandled()
|
||||
}
|
||||
|
||||
// SetWindowMousePassthrough sets whether a mouse cursor passthroughs the window or not on desktops. The default state is false.
|
||||
//
|
||||
// Even if this is set true, some platforms might requrie a window to be undecorated
|
||||
// in order to make the mouse cursor passthrough the window.
|
||||
//
|
||||
// SetWindowMousePassthrough works only on desktops.
|
||||
// SetWindowMousePassthrough does nothing if the platform is not a desktop.
|
||||
//
|
||||
// SetWindowMousePassthrough is concurrent-safe.
|
||||
func SetWindowMousePassthrough(enabled bool) {
|
||||
ui.Get().Window().SetMousePassthrough(enabled)
|
||||
}
|
||||
|
||||
// IsWindowMousePassthrough reports whether a mouse cursor passthroughs the window or not on desktops.
|
||||
//
|
||||
// IsWindowMousePassthrough alaywas returns false if the platform is not a desktop.
|
||||
//
|
||||
// IsWindowMousePassthrough is concurrent-safe.
|
||||
func IsWindowMousePassthrough() bool {
|
||||
return ui.Get().Window().IsMousePassthrough()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user