AsherGlick / Burrito

An overlay tool for Guild Wars 2 that works on linux
GNU General Public License v2.0
79 stars 18 forks source link

Burrito launches in incorrect position #8

Open AsherGlick opened 3 years ago

AsherGlick commented 3 years ago

On Linux (Ubuntu 20.04) the overlay does not get rendered in the correct position on launch. This has been observed on a 3-monitor setup where the overlay spawns on a different window entirely, and on a 2-monitor setup the overlay spawn on the correct monitor but offset by the top task bar.

This may be a difficult to solve issue but it is important to the overall "feel" of the program.

Currently this can be worked-around by pressing the Super key and click+dragging the window to the correct position. Once it is positioned correctly it will stay in place and function properly until its next launch.

coderedart commented 3 years ago

The question is, should burrito support people playing in window mode. I usually keep gw2 on left side of monitor and watch ayinmaiden or gw2 efficiency or some snowcrows rotation video or just some twitch stream on right side of the monitor. Will burrito automatically resize to gw2 window?

AsherGlick commented 3 years ago

I think that would be a useful feature to have for people who want to play in windowed mode. I have multiple monitors and have always just left gw2 in windowed full screen with whatever video I was watching on another screen. I have not tried to look into grabbing the gw2 window position or size as you suggested in another issue.

We can get a process id from the mumble link api but I have not looked into how to get more data out of that process id or if it is a windows id or a linux id when running gw2 in wine.

coderedart commented 3 years ago

It's a windows PID in mumble link. One way is to get the windows dimensions from burritolink

AsherGlick commented 3 years ago

Getting the info in burrito_link and sending it over to burrito seems like the right solution here.

AsherGlick commented 3 years ago

Now that we have the X11 window ID via 7667d9fc174c793f37d59a955c8cdefa6457fb95 I wonder if the right call is to do this in the burrito link still.

If we get it inside burrito_link then it would make the lives easier for anyone who wants to try and get burrito working on windows, but then we have an added layer of possibly instability with getting that info from wine and hoping the values are the same in x11.

coderedart commented 3 years ago

burrito_link is done imo. we can get gw2 process id from from xid, so there's no reason to bother with link at this point. i think link should be updated very rarely, and most changes should be in the overlay itself. if there's some issue with the correctness of window position/size, it is much easier to put a workaround for a specific wm in the overlay itself , compared to link which doesn't know what wm we are running under. as for windows, easier to just integrate it into burrito with gdnative or something.

AsherGlick commented 3 years ago

After giving it some thought I now agree with you that we should grab this info as natively as possible. If windows is ever supported a separate native call can be used to get the data there.

GuilleW commented 1 year ago

Same here, Burrito launch each time on my right screen, while I play on left screen. Very annoying to move the overlay every launch. Can we Just add static offset ? Like fixed Width and Height? Less work, more play :smile:

Masgalor commented 8 months ago

I recently looked into this to get a better understanding on why it seems impossible to place one window dependent on another one. So I'd like to talk about it a little.

There is some code with early tests to manage the window-position in Spatial.gd. https://github.com/AsherGlick/Burrito/blob/a344bdfcfa738ca764ffe677c5f7ba10217b15db/Spatial.gd#L145-L147 I can say that OS.set_window_position(Vector2(1920,0)) works just fine for me. Note: I built burrito with Godot v3.4.5 (the last version we are compatible with) not with v3.3.2, I haven't tested if that makes a difference.

Anyway, it is possible to move the window if you know the coordinates of your target-position. So the real problem here is to get the coordinates of the gw2 window, because the window geometry doesn't deliver useful coordinates. https://github.com/AsherGlick/Burrito/blob/a344bdfcfa738ca764ffe677c5f7ba10217b15db/burrito-fg/src/lib.rs#L62-L67 There is a stackoverflow post which explains why this is the case and how to better solve this problem. But the version of breadx we use (v2.0.0) doesn't support the needed method translate_coordinates, the latest version (v3.1.0) would support it.

So in conclusion this looks to me like a problem that could be solved by upgrading our dependencies, like mentioned in #130 and #166.

I would like to work on this so I would like to know:

coderedart commented 8 months ago

FWIW, its been two years, so i kinda changed my position on this subject. (Also, i still haven't released Jokolay since 2 years wtf??).

In jokolay, at first , i used X11 to get gw2 pos/size. But unfortunately that is not enough to know where to place the jokolay icon.

The top left gw2 menu's position is affected by three things

  1. the pos of top left corner of gw2 window
  2. dpi of gw2 window (lutris sets this separately from your window manager. So, you can't get this from X11)
  3. whether dpi scaling is enabled in gw2 settings (stored in gw2's config file in %APPDATA%, which is easier to access from wine)
  4. uisz of MumbleLink. (small, normal, large, larger). obviously, you can get this from mumblelink, ez.

So, i decided to instead get all of these info from jokolink dll (wine). Jokolink will just write MumbleLink + pos + size + dpi + dpi scaling enabled every frame to /dev/shm/MumbleLink, and will regularly (every 5 seconds) check if any of the above changed using win32 apis and start writing fresh values from next frame.

It is absolutely possible to use X11 and get window size at regular intervals, if that is the approach Burrito wants to take. https://github.com/coderedart/jokolay/blob/3ed8b969af3960c8f8ed6c1acab3df9233c53367/crates/jokolink/src/linux.rs#L172 shows how to do it with X11rb crate which is actively maintained. breadx developers also abandoned breadx and instead maintain X11rb now.

Or burrito_link can copy what Jokolink did with win32 apis https://github.com/coderedart/jokolay/blob/master/crates/jokolink/src/win/mod.rs#L680 . There's three different ways of getting window pos/size :)

AsherGlick commented 8 months ago

@coderedart Have you run into problems with window decoration sizes? One thing I ran into a while ago was that it was difficult to tell how tall a window decoration was, and all of the x/y/w/h values I had easy access to at the time were the whole window, decorations and all. Glad to see Jokolay is still in development.

@Masgalor Upgrading to a newer version of godot is pretty tricky right now because we have no testing tooling and the vast majority of bugs/issues I receive other then the xml_converter branch stuff is compatibility with "whateverwm" or "whateverdistro". Because of that it is hard to tell what will break from the upgrade beyond what I have access to myself. I have some plans to mitigate this using virtual machines and dummy link data but that probably wont happen this quarter. So any version upgrades would just require a lot of manual testing, doable for sure but tedious.

As far as breadx or any modern replacements for it, I am thinking about just replacing that whole gdnative module with native C API calls. Rust is a fantastic language but it quite overkill for being a bridge between gdscript and x11. All of these libraries just make the C style API calls under the hood so instead of relying on their maintainers to not abandon it I'll just make the calls directly myself and not worry about other devs abandoning their middleware. For now though if you want to upgrade breadx to a newer version go ahead. That work is not yet 100% planned and the plans wont be finished until after the testing environment features are in place, probably not before Q4 at the earliest, but it is hard to estimate timelines that far out.

coderedart commented 8 months ago

@AsherGlick

it was difficult to tell how tall a window decoration was,

Yes. Windows has three different ways of getting pos/size.

NOTE: There was a whole circus about dpi awareness at process level and how windows automatically virtualizes the coords for you. Fortunately, GW2 is always "high-dpi aware" in win32 terms and by extension our dll, which is part of the same process. If it was a separately launched executable like the old burrito_link, then it would require a manifest to declare itself high-dpi aware.

I only use GetClientArea + ClientToScreen to get pos + size of the surface without any decorations, but i still do log the values from both the other functions (as well as dpi awareness of process + dpi of window) to help with debugging in case something changes in the future.

On X11, you just call GetGeometry, and then TranslateCoordinates to convert the top-left corner from local to global space. Geometry doesn't include borders by default as far as i can remember. but if you wanted to explicitly get borders, you can query for _NET_FRAME_EXTENTS property for the sizes of the "decoration frame" including titlebar.

But like i said, X11 will only get you pos/size of the window. But dpi/scaling affects positions of top-left menu of gw2 (on hidpi monitors). you can always go the taco way, and put the burrito icon below the top left menu, and avoid this mess. But if you wanted to do it like BlishHUD, and add burrito icon as the rightmost icon on top-left menu, then, you will need to get dpi/dpi-scaling too from gw2 (wine). or ask people to set it manually in a config file.