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

[Linux] Impossible to move window relatively to current position with multi-monitor-setup #4003

Open
rainu opened this issue Jan 12, 2025 · 4 comments
Labels
awaiting feedback More information is required from the requestor Enhancement New feature or request

Comments

@rainu
Copy link

rainu commented Jan 12, 2025

Description

Imagine you have multiple monitors. With these screen-setup (for example)
Bildschirmfoto_2025-01-12_14-38-11

If you set the application to Position 0,0: WindowSetPosition(0,0) the window will be set correctly to the current screen's left-top-corner. But if the current screen is (in my case) the HDMI-1 the function WindowGetPosition() will not return 0, 0 but 1920, 0.

So i am unable to move the application relatively to their current position:

func (a *App) MoveRight() {
	x, y := runtime.WindowGetPosition(a.ctx)
	runtime.WindowSetPosition(a.ctx, x + 16, y)
}

This code will only work correctly if the application will spawn on primary screen (in my case eDP-1) - because the WindowGetPosition() then return 0, 0.

To Reproduce

  1. Connect a second screen to you computer
  2. Move the second screen right to the primary screen (as seen in the screenshot above)
  3. build/start a wails application on linux
    a. wails init -n myproject
    b. change app.go a little bit:
package main

import (
  "context"
  "fmt"
  "github.com/wailsapp/wails/v2/pkg/runtime"
)

// App struct
type App struct {
  ctx context.Context
}

// NewApp creates a new App application struct
func NewApp() *App {
  return &App{}
}

// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
  a.ctx = ctx
  runtime.WindowSetPosition(ctx, 0, 0)
}

// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
  x, y := runtime.WindowGetPosition(a.ctx)
  runtime.WindowSetPosition(a.ctx, x+10, y)

  return fmt.Sprintf("Hello %s, It's show time!", name)
}
  1. start wails application on second screen
  2. write something in input field
  3. click button "Greet"
  4. you should not see any movement
  5. start wails application on primary screen
  6. write something in input field
  7. click button "Greet"
  8. you should see any movement to right

Expected behaviour

I would expect that that code will work properly:

x, y := runtime.WindowGetPosition(a.ctx)
runtime.WindowSetPosition(a.ctx, x + 16, y)

Screenshots

No response

Attempted Fixes

I think the problem is, that in the function SetPosition window.c#226 the monitor-dimension will be added.

I could "correct" the position while subtracting the screens dimensions before. But with the information wails can gave me, i am not able to determine where the current screen is placed. So i could do that (for example):

x, y := runtime.WindowGetPosition(a.ctx)
screens, _ := runtime.ScreenGetAll(a.ctx)
for _, s := range screens {
	if s.IsPrimary {
		x = x - s.Size.Width
		break
	}
}
runtime.WindowSetPosition(a.ctx, x+16, y)

But this will only work in my special monitor setup. If for example the secondary monitor (HDMI-1) is on the left side, this code will not work.

I think the "correct" solution would be, that "WindowGetPosition" will also return the position on the current screen instead of the position in combined-screen-setup. But this change could be break some applications...

Another solution could be providing some functions to get more information about screen positioning.

System Details

# Wails
Version         | v2.9.2                                  
Revision        | d07743b2fd23ad2a26e72606a23ce25487e1ff87
Modified        | true                                    
Package Manager | pacman                                  

# System
┌───────────────────────────────────────────────────────────────────────────────────────┐
| OS           | Manjaro Linux                                                          |
| Version      | Unknown                                                                |
| ID           | manjaro                                                                |
| Go Version   | go1.23.3                                                               |
| Platform     | linux                                                                  |
| Architecture | amd64                                                                  |
| CPU          | 12th Gen Intel(R) Core(TM) i7-1260P                                    |
| GPU 1        | Alder Lake-P GT2 [Iris Xe Graphics] (Intel Corporation) - Driver: i915 |
| GPU 2        | TU117GLM [T550 Laptop GPU] (NVIDIA Corporation) - Driver: nvidia       |
| Memory       | 31GB                                                                   |
└───────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌─────────────────────────────────────────────────────────────────────┐
| Dependency | Package Name | Status    | Version                     |
| *docker    | docker       | Installed | 1:27.3.1-1                  |
| gcc        | gcc          | Installed | 14.2.1+r134+gab884fffe3fc-1 |
| libgtk-3   | gtk3         | Installed | 1:3.24.43-4                 |
| libwebkit  | webkit2gtk   | Installed | 2.46.4-1                    |
| npm        | npm          | Installed | 10.9.2-1                    |
| pkg-config | pkgconf      | Installed | 2.3.0-1                     |
└────────────────────── * - Optional Dependency ──────────────────────┘

# Diagnosis
 SUCCESS  Your system is ready for Wails development!

Additional context

No response

@rainu rainu added the Bug Something isn't working label Jan 12, 2025
@leaanthony
Copy link
Member

Thanks for taking the time to open this. Perhaps a GetScreenForWindow call would suffice? This would return the monitor details for the screen that the window is on?

@leaanthony leaanthony added Enhancement New feature or request awaiting feedback More information is required from the requestor and removed Bug Something isn't working labels Jan 13, 2025
@rainu
Copy link
Author

rainu commented Jan 15, 2025

I don't think that's enough. I would already have access to the information of the current screen (ScreenGetAll()) - but they give me only the sizes and not the positions. I might need the positions of the screens.

I can imagine two ways to fix that:

  1. A function "WindowGetScreenPosition" which gives me the position on the current screen. Because than I can use this coordinates for the existing function WindowSetPosition (as the WindowSetPosition is designed to set the position to the current screen)
  2. A function "WindowSetAbsolutPosition" without additional calculation such in WindowSetPosition

@leaanthony
Copy link
Member

@mmghv did some work in this area. Perhaps he has a good take on it.

@mmghv
Copy link
Contributor

mmghv commented Jan 17, 2025

There seems to be a discrepancy between WindowSetPosition and WindowGetPosition where the former is relative to the screen the window is on, while the later isn't, instead it retrieves the absolute position of the window.

I think this is an unexpected behavior, calling WindowSetPosition on the return of WindowGetPosition should NOT result in any movement to the window, the correct solution here as you mentioned is to make WindowGetPosition use the current screen to get the relative position, this is also what the docs implies.

P.S. I tested this on Windows, it's the same behavior you described on Linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting feedback More information is required from the requestor Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants