mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
parent
1dd7c1cce3
commit
0bec1e65fa
@ -145,6 +145,7 @@ func main() {
|
||||
|
||||
op := &ebiten.RunGameOptions{}
|
||||
op.ScreenTransparent = true
|
||||
op.SkipTaskbar = true
|
||||
if err := ebiten.RunGameWithOptions(&mascot{}, op); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -17,15 +17,37 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
_SM_CYCAPTION = 4
|
||||
_CLSCTX_INPROC_SERVER = 0x1
|
||||
_CLSCTX_LOCAL_SERVER = 0x4
|
||||
_CLSCTX_REMOTE_SERVER = 0x10
|
||||
_CLSCTX_SERVER = _CLSCTX_INPROC_SERVER | _CLSCTX_LOCAL_SERVER | _CLSCTX_REMOTE_SERVER
|
||||
_MONITOR_DEFAULTTONEAREST = 2
|
||||
_SM_CYCAPTION = 4
|
||||
)
|
||||
|
||||
var (
|
||||
_CLSID_TaskbarList = windows.GUID{
|
||||
Data1: 0x56FDF344,
|
||||
Data2: 0xFD6D,
|
||||
Data3: 0x11D0,
|
||||
Data4: [...]byte{0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90},
|
||||
}
|
||||
_IID_ITaskbarList = windows.GUID{
|
||||
Data1: 0x56FDF342,
|
||||
Data2: 0xFD6D,
|
||||
Data3: 0x11D0,
|
||||
Data4: [...]byte{0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90},
|
||||
}
|
||||
)
|
||||
|
||||
type _RECT struct {
|
||||
@ -48,14 +70,28 @@ type _POINT struct {
|
||||
}
|
||||
|
||||
var (
|
||||
ole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||
user32 = windows.NewLazySystemDLL("user32.dll")
|
||||
|
||||
procCoCreateInstance = ole32.NewProc("CoCreateInstance")
|
||||
|
||||
procGetSystemMetrics = user32.NewProc("GetSystemMetrics")
|
||||
procMonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
||||
procGetMonitorInfoW = user32.NewProc("GetMonitorInfoW")
|
||||
procGetCursorPos = user32.NewProc("GetCursorPos")
|
||||
)
|
||||
|
||||
func _CoCreateInstance(rclsid *windows.GUID, pUnkOuter unsafe.Pointer, dwClsContext uint32, riid *windows.GUID) (unsafe.Pointer, error) {
|
||||
var ptr unsafe.Pointer
|
||||
r, _, _ := procCoCreateInstance.Call(uintptr(unsafe.Pointer(rclsid)), uintptr(pUnkOuter), uintptr(dwClsContext), uintptr(unsafe.Pointer(riid)), uintptr(unsafe.Pointer(&ptr)))
|
||||
runtime.KeepAlive(rclsid)
|
||||
runtime.KeepAlive(riid)
|
||||
if uint32(r) != uint32(windows.S_OK) {
|
||||
return nil, fmt.Errorf("ui: CoCreateInstance failed: error code: HRESULT(%d)", uint32(r))
|
||||
}
|
||||
return ptr, nil
|
||||
}
|
||||
|
||||
func _GetSystemMetrics(nIndex int) (int32, error) {
|
||||
r, _, _ := procGetSystemMetrics.Call(uintptr(nIndex))
|
||||
if int32(r) == 0 {
|
||||
@ -77,7 +113,7 @@ func _GetMonitorInfoW(hMonitor uintptr) (_MONITORINFO, error) {
|
||||
|
||||
r, _, e := procGetMonitorInfoW.Call(hMonitor, uintptr(unsafe.Pointer(&mi)))
|
||||
if int32(r) == 0 {
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
if e != nil && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||
return _MONITORINFO{}, fmt.Errorf("ui: GetMonitorInfoW failed: error code: %w", e)
|
||||
}
|
||||
return _MONITORINFO{}, fmt.Errorf("ui: GetMonitorInfoW failed: returned 0")
|
||||
@ -89,10 +125,38 @@ func _GetCursorPos() (int32, int32, error) {
|
||||
var pt _POINT
|
||||
r, _, e := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt)))
|
||||
if int32(r) == 0 {
|
||||
if e != nil && e != windows.ERROR_SUCCESS {
|
||||
if e != nil && !errors.Is(e, windows.ERROR_SUCCESS) {
|
||||
return 0, 0, fmt.Errorf("ui: GetCursorPos failed: error code: %w", e)
|
||||
}
|
||||
return 0, 0, fmt.Errorf("ui: GetCursorPos failed: returned 0")
|
||||
}
|
||||
return pt.x, pt.y, nil
|
||||
}
|
||||
|
||||
type _ITaskbarList struct {
|
||||
vtbl *_ITaskbarList_Vtbl
|
||||
}
|
||||
|
||||
type _ITaskbarList_Vtbl struct {
|
||||
QueryInterface uintptr
|
||||
AddRef uintptr
|
||||
Release uintptr
|
||||
|
||||
HrInit uintptr
|
||||
AddTab uintptr
|
||||
DeleteTab uintptr
|
||||
ActivateTab uintptr
|
||||
SetActiveAlt uintptr
|
||||
}
|
||||
|
||||
func (i *_ITaskbarList) DeleteTab(hwnd windows.HWND) error {
|
||||
r, _, _ := syscall.Syscall(i.vtbl.DeleteTab, 2, uintptr(unsafe.Pointer(i)), uintptr(hwnd), 0)
|
||||
if uint32(r) != uint32(windows.S_OK) {
|
||||
return fmt.Errorf("ui: ITaskbarList::DeleteTab failed: HRESULT(%d)", uint32(r))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *_ITaskbarList) Release() {
|
||||
syscall.Syscall(i.vtbl.Release, 1, uintptr(unsafe.Pointer(i)), 0, 0)
|
||||
}
|
||||
|
@ -100,4 +100,5 @@ type RunOptions struct {
|
||||
GraphicsLibrary GraphicsLibrary
|
||||
InitUnfocused bool
|
||||
ScreenTransparent bool
|
||||
SkipTaskbar bool
|
||||
}
|
||||
|
@ -940,6 +940,11 @@ func (u *userInterfaceImpl) init(options *RunOptions) error {
|
||||
|
||||
u.setWindowResizingModeForOS(u.windowResizingMode)
|
||||
|
||||
if options.SkipTaskbar {
|
||||
// Ignore the error.
|
||||
_ = u.skipTaskbar()
|
||||
}
|
||||
|
||||
u.window.Show()
|
||||
|
||||
if g, ok := u.graphicsDriver.(interface{ SetWindow(uintptr) }); ok {
|
||||
|
@ -385,3 +385,7 @@ func initializeWindowAfterCreation(w *glfw.Window) {
|
||||
delegate := objc.ID(class_EbitengineWindowDelegate).Send(objc.RegisterName("alloc")).Send(objc.RegisterName("initWithOrigDelegate:"), nswindow.Send(sel_delegate))
|
||||
nswindow.Send(objc.RegisterName("setDelegate:"), delegate)
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) skipTaskbar() error {
|
||||
return nil
|
||||
}
|
||||
|
@ -229,3 +229,7 @@ func initializeWindowAfterCreation(w *glfw.Window) {
|
||||
// Apparently the window state is inconsistent just after the window is created, but we are not sure.
|
||||
// For more details, see the discussion in #1829.
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) skipTaskbar() error {
|
||||
return nil
|
||||
}
|
||||
|
@ -185,3 +185,24 @@ func (u *userInterfaceImpl) setWindowResizingModeForOS(mode WindowResizingMode)
|
||||
|
||||
func initializeWindowAfterCreation(w *glfw.Window) {
|
||||
}
|
||||
|
||||
func (u *userInterfaceImpl) skipTaskbar() error {
|
||||
if err := windows.CoInitializeEx(0, windows.COINIT_MULTITHREADED); err != nil {
|
||||
return err
|
||||
}
|
||||
defer windows.CoUninitialize()
|
||||
|
||||
ptr, err := _CoCreateInstance(&_CLSID_TaskbarList, nil, _CLSCTX_SERVER, &_IID_ITaskbarList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := (*_ITaskbarList)(ptr)
|
||||
defer t.Release()
|
||||
|
||||
if err := t.DeleteTab(windows.HWND(u.window.GetWin32Window())); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
11
run.go
11
run.go
@ -236,17 +236,23 @@ type RunGameOptions struct {
|
||||
// The default (zero) value is GraphicsLibraryAuto, which lets Ebitengine choose the graphics library.
|
||||
GraphicsLibrary GraphicsLibrary
|
||||
|
||||
// InitUnfocused represents whether the window is unfocused or not on launching.
|
||||
// InitUnfocused indicates whether the window is unfocused or not on launching.
|
||||
// InitUnfocused is valid on desktops and browsers.
|
||||
//
|
||||
// The default (zero) value is false, which means that the window is focused.
|
||||
InitUnfocused bool
|
||||
|
||||
// ScreenTransparent represents whether the window is transparent or not.
|
||||
// ScreenTransparent indicates whether the window is transparent or not.
|
||||
// ScreenTransparent is valid on desktops and browsers.
|
||||
//
|
||||
// The default (zero) value is false, which means that the window is not transparent.
|
||||
ScreenTransparent bool
|
||||
|
||||
// SkipTaskbar indicates whether an application icon is shown on a taskbar or not.
|
||||
// SkipTaskbar is valid only on Windows.
|
||||
//
|
||||
// The default (zero) value is false, which means that an icon is shown on a taskbar.
|
||||
SkipTaskbar bool
|
||||
}
|
||||
|
||||
// RunGameWithOptions starts the main loop and runs the game with the specified options.
|
||||
@ -656,5 +662,6 @@ func toUIRunOptions(options *RunGameOptions) *ui.RunOptions {
|
||||
GraphicsLibrary: ui.GraphicsLibrary(options.GraphicsLibrary),
|
||||
InitUnfocused: options.InitUnfocused,
|
||||
ScreenTransparent: options.ScreenTransparent,
|
||||
SkipTaskbar: options.SkipTaskbar,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user