Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ebiten: DeviceScaleFactor before RunGame can return a wrong value when SetWindowPosition is called #1575

Closed
hajimehoshi opened this issue Apr 17, 2021 · 11 comments

Comments

@hajimehoshi
Copy link
Owner

When SetWindowPosition is called and the position is in another monitor, DeviceScaleFactor should be affected.

@hajimehoshi hajimehoshi modified the milestone: v2.1.0 Apr 17, 2021
hajimehoshi added a commit that referenced this issue Apr 17, 2021
hajimehoshi added a commit that referenced this issue Apr 17, 2021
@hajimehoshi hajimehoshi added this to the v2.2.0 milestone Apr 18, 2021
@hajimehoshi
Copy link
Owner Author

hajimehoshi commented Sep 19, 2021

DeviceScaleFactor should not be called before RunGame, due to Android?

@hajimehoshi
Copy link
Owner Author

Probably we have to keep a temporary window created at init and detect the monitor correctly. This is not an easy task.

@hajimehoshi hajimehoshi modified the milestones: v2.2.0, v2.3.0 Sep 19, 2021
@aprchen
Copy link

aprchen commented Dec 27, 2021

Is there any plan for this issue?

@hajimehoshi
Copy link
Owner Author

No so far, but is this an urgent issue for you?

@aprchen
Copy link

aprchen commented Dec 27, 2021

No so far, but is this an urgent issue for you?

Yes, I made a function of dragging the window. When using DeviceScaleFactor, the window will shake when it moves, and it will be normal without using DeviceScaleFactor.

@hajimehoshi
Copy link
Owner Author

I don't understand what you are doing. Could you show a (pseudo) code?

@aprchen
Copy link

aprchen commented Dec 27, 2021

the demo like this

package main

import (
	"fmt"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/inpututil"
)

type Test struct {
	isHighDPI bool
	c         WindowDragCoordinator
}

func (t *Test) Update() error {
	t.c.Update()
	return nil
}

func (t *Test) Draw(screen *ebiten.Image) {
	return
}

func (t *Test) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
	if t.isHighDPI {
		s := ebiten.DeviceScaleFactor()
		return int(s) * outsideWidth, int(s) * outsideHeight
	}
	return outsideWidth, outsideHeight
}

func NewTest() *Test {
	return &Test{}
}

func main() {
	g := NewTest()
	g.isHighDPI = true
	ebiten.SetWindowSize(200, 200)
	err := ebiten.RunGame(g)
	if err != nil {
		panic(err)
	}
}

type Point struct {
	x, y int
}

type mouse struct {
	current, init Point
}

func (m mouse) String() string {
	return fmt.Sprintf("x %d y %d  fx %d fy %d", m.current.x, m.current.y, m.init.x, m.init.y)
}

func (m mouse) Diff() (dx, dy int) {
	return m.current.x - m.init.x, m.current.y - m.init.y
}

func (m *mouse) SetInitPosition() {
	m.init.x, m.init.y = ebiten.CursorPosition()
}

func (m *mouse) RefreshCurrentPosition() {
	m.current.x, m.current.y = ebiten.CursorPosition()
}

type window struct {
	current, init Point
}

func (w *window) RefreshCurrentPosition() {
	w.current.x, w.current.y = ebiten.WindowPosition()
}

func (w *window) GetSize() (width, height int) {
	return ebiten.WindowSize()
}

func (w *window) SetInitPosition() {
	w.init.x, w.init.y = ebiten.WindowPosition()
}

func (w *window) GetMax() (x, y int) {
	wWidth, wHeight := w.GetSize()
	mx, my := ebiten.ScreenSizeInFullscreen()
	return mx - wWidth, my - wHeight
}

func (w *window) MoveBy(dx, dy int) {
	w.current.x += dx
	w.current.y += dy
	maxX, maxy := w.GetMax()
	if w.current.x < 0 {
		w.current.x = 0
	}
	if w.current.x > maxX {
		w.current.x = maxX
	}
	if w.current.y < 0 {
		w.current.y = 0
	}
	if w.current.y > maxy {
		w.current.y = maxy
	}
	ebiten.SetWindowPosition(w.current.x, w.current.y)
}

type WindowDragCoordinator struct {
	mouse  mouse
	window window
	isHold bool
}

func (c *WindowDragCoordinator) Update() {
	if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
		c.mouse.SetInitPosition()
		c.window.SetInitPosition()
		c.isHold = true
		return
	}
	if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) {
		c.isHold = false
		return
	}
	if !c.isHold {
		return
	}
	c.mouse.RefreshCurrentPosition()
	fmt.Println(c.mouse)
	c.window.RefreshCurrentPosition()
	c.window.MoveBy(c.mouse.Diff())
}


@hajimehoshi
Copy link
Owner Author

Thanks, but is this related to this issue? This issue focuses on DeviceScaleFactor before RunGame.

@aprchen
Copy link

aprchen commented Dec 27, 2021

Thanks, but is this related to this issue? This issue focuses on DeviceScaleFactor before RunGame.

sorry, I followed the method comment
this should be another issue

hajimehoshi added a commit that referenced this issue Feb 8, 2022
@hajimehoshi
Copy link
Owner Author

How about not enabling to specify a monitor by SetWindowPosition? Then we can assume DeviceScaleFactor always returns the scale of the default monitor.

@hajimehoshi
Copy link
Owner Author

Solved this issue by not letting users change the initial monitor.

hajimehoshi added a commit that referenced this issue Sep 24, 2023
Now Ebitengine allows to specify the initial monitor, having an
initial monitor is no longer a hack.

Updates #1575
Updates #1835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants