Giter Site home page Giter Site logo

Rendering broken - follow up about linvst HOT 13 CLOSED

osxmidi avatar osxmidi commented on August 23, 2024
Rendering broken - follow up

from linvst.

Comments (13)

osxmidi avatar osxmidi commented on August 23, 2024

Basically for the embedded LinVst version, Reaper (or the host) sends a call to the vst asking it's window size and LinVst passes that on to the vst and then sends the vst window size back to Reaper.

Then Reaper opens a plugin window corresponding to that size and LinVst reparents the vst's (Wine) window into it.

So, LinVst isn't involved that much and if there is a system problem due to more than one monitor or something that a particular window manager might be doing then it might result in something being displayed wrongly and LinVst can't do much about it.

Maybe the host can do something about it (multiple monitor compatibility etc) because it controls the windows that LinVst reparents the Wine window into but the system itself might need to be configured and/or the system might even have incompatibilities ie drivers/window managers/ X11/Gtk etc and how they interact and are setup.

The LinVst standalone version puts up it's own window that doesn't depend on Reaper or the host.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

So, LinVst isn't involved that much

I don't think that's the case - LinVst attempts to move the child window to +0+0, but that gets overridden when openGUI gets called, which, if I'm reading the source correctly, causes ShowWindow to be called on the server side. At this point, whatever happens is some Wine/Windows magic that positions the window.

LinVst needs to make sure that the child is at +0+0. As I've said, moving the window after the call to openGUI works. But again, I don't think that's the correct way to do it.

a system problem due to more than one monitor

I wouldn't say that this is a system problem. Rather, it's just how Wine works (I think).

something that a particular window manager might be doing

I guess that a WM could be doing some funny positioning even after the window has been reparented, although I don't think that it does so in my case. But I'll try a couple of different WMs, just to be sure.

Maybe the host can do something about it

Probably not - it just gives the VST a window, it doesn't (and shouldn't) care that you're reparenting a different window into it with weird coordinates.

The LinVst standalone version puts up it's own window that doesn't depend on Reaper or the host.

Yes, and that works fine.

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

The Wine window gets moved to 0,0 relative to the Reaper/Host vst window.

Reaper provides a window and LinVst reparents the Wine window with 0,0 coords into it and it becomes the child window of Reapers provided window.

The 0,0 is the offset that the Wine window will have from the provided Reaper vst window (which is the parent window), so if 0,0 was changed to 10,10 then it would produce an offset and the Wine window wouldn't look right when it was reparented into Reapers (parent) window.

Like, for the Tracktion version I needed to have a window manager title bar offset (because of the way they do things) and the Wine window is moved to an offset that is the same as the window manager's title bar height and width.

That's from what I remember about the GUI code, which was a while back.

I havn't had anyone report any embedded window problems and some users are using Arch, and I can't reproduce any problems but I'm using only one monitor.

I've had various window managers with various distros and I can't reproduce any GUI problems, so to me it could be a system problem of some sort, maybe a library, maybe something about Wine on the system, multiple monitors could cause some trouble, hard to tell.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

The Wine window gets moved to 0,0 relative to the Reaper/Host vst window.

Reaper provides a window and LinVst reparents the Wine window with 0,0 coords into it and it becomes the child window of Reapers provided window.

The 0,0 is the offset that the Wine window will have from the provided Reaper vst window (which is the parent window), so if 0,0 was changed to 10,10 then it would produce an offset and the Wine window wouldn't look right when it was reparented into Reapers (parent) window.

I understand all of that. However, that's not actually what happens. I put a few XGetGeometry calls into the client's effEditOpen handler to see how the position of the child window changes over time and this is the result:

There's two questions to ask here:

  • Why does the child window start at +1280+0?
  • Why does its position revert to +1280+0 when openGUI (which, AFAICT, calls ShowWindow and UpdateWindow) get called?

I guess that the answer to the second question is easy - wine, for some reason, keeps its own window positions independent from X11. And when ShowWindow gets called, it moves the window to this position, just to be sure.

The first question is not that easy. But my best guess is that wine follows the way screen coordinates work on Windows. I found this document, which clearly states:

The primary monitor contains the origin (0,0). This is for compatibility with existing applications that expect a monitor with an origin. However, the primary monitor does not have to be in the upper left of the virtual screen.

It also provides this handy picture:

https://docs.microsoft.com/en-us/windows/desktop/gdi/images/multimon-1.png

This means that when you create a window with CreateWindow(Ex), the coordinates have to be translated between Windows-style coordinates and X11-style coordinates (ie. origin being in the top left corner of the entire area). In my case, that means adding +1280+0 to the position and so the window ends up at +1280+0.

What's the solution to this? I don't know. As I've tested, moving the window to +0+0 with XMoveWindow after openGUI is called seems to work, but after tracing how the position changes, I wouldn't really trust it to keep working at all times.

Maybe creating the window with WS_CHILD could help?

Finally, I think that you could query the X11 position of the window right after creating it with CreateWindowEx and then subtract that from its Window position. Ie. create the window at +0+0, query the X coordinates +1280+0 and then move the window to -1280+0 to compensate.

Although that sounds a bit hacky.

I'll try something out when I get some time and see how it goes.

Like, for the Tracktion version I needed to have a window manager title bar offset (because of the way they do things) and the Wine window is moved to an offset that is the same as the window manager's title bar height and width.

Yeah, I noticed that. In my case the window would end up at +1280+0 + whatever the title bar offset is and so it wouldn't look right.

I havn't had anyone report any embedded window problems and some users are using Arch, and I can't reproduce any problems but I'm using only one monitor.

Well, not only do you need multiple screens, you also need the primary to not have its top left corner at +0+0. And I'm pretty sure that the most common multi monitor setup is two 1920x1080 screens side by side, with the left one being the primary one, which wouldn't have this problem.

I've had various window managers with various distros and I can't reproduce any GUI problems

Just to be sure, I tried Xfwm4, Openbox, awesome and i3 and had exactly the same issue with all of them.

to me it could be a system problem of some sort, maybe a library, maybe something about Wine on the system, multiple monitors could cause some trouble, hard to tell.

Well, after seeing the results above, I'm convinced that my guess is very close to the actual issue. I'll let you know when I have more information.

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

The Wine window is a X11 window on the Linux side which is the linvst.so side.
linvst.so deals with the Wine X11 window and it's position and the position is tracked via XTranslateCoordinates in ConfigureNotify via the window manager and LinVst needs the Allow the window manager to control the windows option enabled in winecfg (which is the default).

On the Wine side which is the lin-vst-server.exe side, the Wine window is dealt with by windows calls ie SetWindowPos, ShowWindow, UpdateWindow etc and these need to be called by the Linux linvst.so side via showgui opengui hidegui etc so that the Linux side and Wine side are in sync.

If the window position is altered or offset from 0,0 on the Wine side via SetWindowPos then it will have an effect on the Linux side and the Linux vst plugin display will be at whatever the offset is, so setting an offset of 10, 10 via SetWindowPos will result in a 10,10 offset from the vst plugin window (Linux parent window) origin.

So, LinVst only deals with the Linux vst plugin window (the Linux DAW's vst plugin X11 window) and offsets within that window by reparenting the Wine X11 window into it and the offset position is set by SetWindowPos 0, 0 which means no offset relative to the reparenting of the Linux DAW's vst plugin X11 window and the Wine X11 window.

The Wine SetWindowPos 0, 0 is positioning the Linux Wine X11 window at 0, 0.

After the reparenting the Linux Wine X11 window is tracked by the window manager and is done by XTranslateCoordinates in ConfigureNotify and this is needed for mouse/window position sync.

If the (Wine) X11 window was at 0, 0 and then reparented into a window at say 500, 500 then the (now child) X11 window isn't at 0, 0 anymore it's at 500, 500 but it's still at 0, 0 relative to the parent window and wherever the parent window moves to the child moves to and that's done by the window manager tracking XTranslateCoordinates in ConfigureNotify.

If the (Wine) X11 window was at 10, 10 and then reparented into a window at say 500, 500 then the (now child) X11 window isn't at 0, 0 anymore it's at 510, 510 and is offset by 10, 10 in the parent window (the Linux DAW's vst X11 window).

What Wine may be doing with multiple monitor setups I don't know, because it might involve X11 multi monitor setups ie xorg.conf.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

If the window position is altered or offset from 0,0 on the Wine side via SetWindowPos then it will have an effect on the Linux side and the Linux vst plugin display will be at whatever the offset is, so setting an offset of 10, 10 via SetWindowPos will result in a 10,10 offset from the vst plugin window (Linux parent window) origin.

The Wine SetWindowPos 0, 0 is positioning the Linux Wine X11 window at 0, 0.

No, it's not.

I had to look this up in the Wine source code. The X11 driver uses these two functions to translate back and forth between Windows-style virtual screen coordinates (ie. +0+0 being at the top left of the primary screen) and X11-style root window coordinates (ie. +0+0 being the top left of the entire display area, possibly offscreen). These are used in multiple places in the driver code, one example being the sync_window_position function, which is apparently used to "Synchronize the X window position with the Windows one".

So whenever you set window coordinates through Windows function (eg. CreateWindowEx, MoveWindow, SetWindowPos etc.) to +0+0, the X11 position doesn't get set to +0+0 - it gets set to +0+0 + the position of the primary screen relative to the root window. In many cases that's still +0+0, but not always. In my case, it's +1280+0.

Wine doesn't expect the window to be a child of an already existing X11 window, and so it treats it as if it were a top-level window and translates the coordinates accordingly.

And this is the root of the problem - the coordinate systems differ between X11 and Windows (wine) and the translation between them causes issues in this case.

I previously thought that creating the child window with the WS_CHILD flag could maybe fix this, but I'm not seeing that in the code - maybe WS_CHILD windows are not actual X11 windows? I don't know yet, I'll have to look deeper into it.

What Wine may be doing with multiple monitor setups I don't know, because it might involve X11 multi monitor setups ie xorg.conf.

It's not really a multimonitor issues, I'm pretty sure you could setup X11 so that your root window was bigger than your screen and your screen was not positioned at +0+0 and it would cause the same issues.

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

That post was for a single display/monitor.

As I said, I havn't done any testing with multiple monitors.

So, I tried setting up multiple monitors with Ubuntu Studio 17.10 and a Radeon HD 6670/7670 on an i7 with Wine Staging 3.13.

This is the main monitor

https://drive.google.com/uc?export=download&id=1ykuNa5zoPOHdDDVVLBNQhOyN6M-dy9Ag

and this is the extended monitor

https://drive.google.com/uc?export=download&id=1kHTVzAcLaF8znOCN7UBw7-_y_mMUxqS0

and as far as I can tell the embedded vst wine window positions are ok and also the mouse/menu positions are ok in the main monitor/display and the extended monitor/display.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

That post was for a single display/monitor.

Oh, sorry, I didn't catch that.

Anyway, thank you for trying it out with multiple monitors.

How have you got them set up? Side by side? Did you set up the right one as the primary one?

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

The monitor with Reaper (and the Ubuntu Studio menu bar at the top) in it was the primary.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

That doesn't matter. What matters is if the primary screen is positioned somewhere else other than +0+0 of the root window. If you've got the screens side by side, the easiest way to achieve that is by setting the right one to be primary.

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

I made the other one the primary and there is a problem probably due to the offset.

I can get around it by making the other one the primary, so it's not impossible to get working but if someone has whatever primary setup for some reason then they might run into problems.

I'll look into it when I can get around to it.

from linvst.

osxmidi avatar osxmidi commented on August 23, 2024

I've made some changes to the code, it seems to work with multiple monitors.

from linvst.

zdenek-biberle avatar zdenek-biberle commented on August 23, 2024

I can get around it by making the other one the primary, so it's not impossible to get working but if someone has whatever primary setup for some reason then they might run into problems.

Well yeah, that's what I've been saying the whole time.

I've made some changes to the code, it seems to work with multiple monitors.

Thank you. Using GetSystemMetrics is much more elegant than whatever hacky solution I was thinking about. I'll try it out when I get home.

Just one minor detail: is it really necessary to have the if(GetSystemMetrics(SM_CMONITORS) > 1) condition there? Because, as I've already stated, this issue may not necessarily come up only when you use multiple monitors. I would just remove the condition and the else branch and just keep the new calls to SetWindowPos.

from linvst.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.