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

HiDPI support? #68

Closed
kybos opened this issue Oct 7, 2019 · 43 comments
Closed

HiDPI support? #68

kybos opened this issue Oct 7, 2019 · 43 comments

Comments

@kybos
Copy link

kybos commented Oct 7, 2019

Hi,
I am trying to use Yoshimi on Ubuntu Studio 19.10 (with my HiDPI monitor), but the UI is so tiny that it's practically unusable (version 1.5.9).
Is there any parameter or setting to scale the UI?
I see in the code the the FLTK framework is used. I looked in the FLTK docu, there seems to be HiDPI support available in the current version.
I tried the modify/export the relevant FLTK_SCALE_FACTOR setting before starting Yoshimi, but there was no change.
Thanks,
kybos

@abrolag
Copy link
Member

abrolag commented Oct 9, 2019

At the moment, the only way round this I can think of is to set a lower desktop resolution (if your monitor supports that). This is far from ideal, and we are trying to work out the best way to make the GUI more up-to-date.
One way we might be able to do that is to change to a toolkit that that has proper native scaling support - whatever route we decide on will involve a lot of work!

@kybos
Copy link
Author

kybos commented Oct 12, 2019

I now have a working version of yoshimi on HiDPI (scale factor = 2):

image

As I wrote above, the current FLTK git version (1.4, not yet released) has scaling already implemented, and it seems to be pretty good (see https://www.fltk.org/doc-1.4/drawing.html for details). The automatic dpi recognition does not work (yet?), but it can be enforced by setting/exporting FLTK_SCALING_FACTOR=2 (or whatever value, even non-integer possible).

So I had to compile fltk from git and compile yoshimi against it. I had to remove the cairo-lib references from the code (because they do not scale and partly even cause syntax errors).
Cairo is mainly used in yoshimi to draw the fancy knobs/dials - this does not work, the plain Fl_Dial has to be used instead.
There were also some smaller sizing issues with the mixer, system effect sends etc.

I forked the repo and applied my changes there, in case anybody is interested: https://github.com/kybos/yoshimi

@abrolag
Copy link
Member

abrolag commented Oct 14, 2019

I'm impressed with what you have done here, and have fowarded the demo to our email list in case anyone there is interested.

Unfortunately FLTK 4 doesn't have any visibility in the main distros yet and as we try to maintain compatibility for as long as practical, it would be a long time before we cound consider anything like this.

It seems we have two routes - develop our own toolkit to be complied with Yoshimi, or use one of the established (somewhat bloated) ones :(

@kybos
Copy link
Author

kybos commented Oct 16, 2019

Yes, I know that this is no way for the standard delivery of yoshimi. There is not even a target date for the release of FLTK 1.4 yet, AFAIK.

I just wanted to record my experiences here, as a proof of concept, and perhaps to help people who are desperately wanting to use yoshimi on their HiDPI screens (as I was), and who are able and willing to compile themselves.

I am not sure moving to GTK3 or QT would be a good idea, thinking of all the permanently crashing plugins that use them... The yoshimi LV2 plugin is one of the few soft synths that run stable for me with all DAWs...
This discussion could be relevant in this context: http://lists.lv2plug.in/pipermail/devel-lv2plug.in/2016-March/001593.html

@zenvoid
Copy link

zenvoid commented Dec 7, 2019

I'll probably move to high resolution too, and I would deffinitely want to continue using Yoshimi, I'll try the workaround of FLTK 1.4 but I wonder if it could be possible to use Zyn-Fusion toolkit now that it is licensed under LGPL, while maintaining the classic Yoshimi interface (drawing controls using the new toolkit, but not necessarily cloning the single-window user interface of Zyn-Fusion): https://github.com/mruby-zest/mruby-zest-build

@abrolag
Copy link
Member

abrolag commented Dec 7, 2019

I have been watching this development myself. Two downsides for me personally, are that it is programmed in Ruby (which I've never even seen) and it communicates via OSC (which I also have no experience of). That is not necessarily a show stopper, and I'll discuss the idea with one of the other devs who I know is interested in GUI redesign. Meanwhile if you can work with FLTK 1.4 that would be great.

@zenvoid
Copy link

zenvoid commented Dec 7, 2019

Other option that comes to mind is the toolkit used by Geonkick. It is a cpp library, looks nice and it is made for audio GUI specifically: https://gitlab.com/geontime/redkite

I can't comment on technical details because I've only used it as an end user on Geonkick, it may have it's own drawbacks as well...

@abrolag
Copy link
Member

abrolag commented Dec 22, 2019

This is quite interesting. Especially as Iurie has contributed to Yoshimi in the past.

@iurienistor
Copy link
Contributor

@abrolag I have sent you my answer to your email regarding Redkite GUI toolkit, I don't know If you've got it.

It would be nice to see Redkite be used by Yoshimi, but I'd like to emphasize some positive and negative points about Redkite:

Positive:

  • it is done in pure C++
  • can be easy complied statically, and is designed to be used for GUI plugins
  • is very close to Qt interface, so if you know Qt than you can use Redkite
  • have some widgets developed, even an RkLineEdit
  • has a timer class which is very useful like QTimer
  • can be easly compiled statically and installed
  • has some examples how to use it, but since it close to Qt, the main ideas are similar
  • has RkPainter that can draw on RkWidgets and RkImage, it uses Cairo backend. It similar with QPainter
  • has actions support that is close to Qt signals
  • has a similar idea like in Qt connect /signal / slot

Negative:

  • it is still not cross-platform, only for GNU/Linux
  • don't have a file dialog widget, and RkLineEdit needs to be improved, even if is close to the standard ones (I developed a file dialog for Geonkick that use Redkite and have plans to move it to Redkite and improve it)
  • still don't have a popup a widget. this is needed when considering to develop things like combo box or menus
  • the connection between objects is not very beautiful like Qt connect(), it is close, but needs to be improved
  • is not supporting Unicode yet
  • don't have layout classes can permits dynamic layout
  • uses some features from C++17 (but this can be removed without affecting the toolkit)

If you pan to develop your own toolkit I think first is to make a list of widgets types that would be used in Yoshimi and that are one of those standards and important:

  • Dialogs / modal?
  • Popups?
  • Combo box?
  • Popup menu?
  • File Browser? - you'll not be able to use the native one as other toolkit can use. So, a lot of things to develop here, list files, browse, filter file extention, create directory etc
  • Line edit? - seems from the beginning simple, but there is a need some effort to develop to be close to the standard one, cut, paste, home, begin, etc... support the standard control keys
  • List view / tree view with scrool area, select items, delete, add? Needs some effort to develop
  • Buttons, radio buttons and check boxes are easy to develop

Of course, the GUI design can be made in a way that many of these widgets can be avoided.

@abrolag
Copy link
Member

abrolag commented Dec 29, 2019

{rolls up sleeves}

OK, I've been looking through various options, and done a lot of reading - had to keep taking breaks to give my eyes a rest :(

1/ Zest
This would require not only a lot of work, but also learning a completely new language and communication system.

2/ Pugl
Would need a huge amount of work.

3/ RedKite
A lot of work and currently not platform agnostic.

4/ Python (and derivatives)
Probably the heaviest workload of the lot!

5/ FLTK-4
Would need to not only static link but build the FLTK code into Yoshimi.
Would also need to devise runtime rescaling.

My conclusion is that emedding FLTK-4 although not trivial would be the simplest route.
It has a compatible license and would result in very little development work on Yoshimi itself. Also, according to the docs, Cairo is supported if the appropriate flags are set. It should be possible to reinstate our nice round knobs, so our users would see little (if any) difference.

Also, I've had some discussion with Robin Gareus with regards to potential issues with Yoshimi as a plugin. He is happy for me to pass his comments on, so if anyone is interested contact me (email address in my profile) and I'll send it (I'm not comfortable with the idea of posting it here on a public forum).

@kramlie
Copy link
Contributor

kramlie commented Dec 29, 2019

I fully agree with @abrolag here. The workload to do any of the others is just too big, they're essentially complete rewrites of the UI. I also think it's best to stay clear of the non cross-platform toolkits, as well as those that are very young and/or incomplete. Whatever toolkit is chosen will be with us for a long time, so we need to know they will be maintained. The static linking is annoying, but this problem will eventually go away when FLTK 1.4 is released, so I'm not very worried about it.

FWIW, I probably would not have chosen FLTK if I was starting from scratch, or if we really wanted to radically change the UI (as ZynAddSubFX has done), but I don't think that's what we're talking about here; this is more of an upgrade in my eyes.

Interesting that no one has mentioned JUCE. This one is used by many commercial audio products, but is fully open source (they dual license with commercial licenses).

@iurienistor
Copy link
Contributor

I agree too.

@kramlie "The static linking is annoying, but this problem will eventually go away when FLTK 1.4 is released"... do you mean that they are going to provide a solution to this?

@kramlie
Copy link
Contributor

kramlie commented Dec 29, 2019

I mean that once FLTK 1.4 is released and picked up by distros, it will be a system library, so we won't need to statically link anymore, we can just link to the system library. This is what we do today with the existing FLTK library.

@iurienistor
Copy link
Contributor

Maybe I couldn't understand your thought. The idea was due to this - http://lists.lv2plug.in/pipermail/devel-lv2plug.in/2016-March/001593.html

@dbtx
Copy link
Contributor

dbtx commented Dec 29, 2019

Just popped in to mention: Cross-platform GUI Toolkit Trainwreck, 2016 Edition

On the side, I'm in the very early stages of designing a thing on top of pugl, similar to AVTK but with some different assumptions and goals. And, nobody needs to care (yet) ;)

On the other side, does FLTK 1.4 have the same plugin-hostile requirements for thread handling that we already ignore in 1.3?

@kramlie
Copy link
Contributor

kramlie commented Dec 29, 2019

Maybe I couldn't understand your thought. The idea was due to this - http://lists.lv2plug.in/pipermail/devel-lv2plug.in/2016-March/001593.html

Oh, I thought it was because it was not released yet. Hmm, it might be possible to leverage static linking also to get around the "incompatible toolkits problem" in plugins, but this would need testing first. Beyond that I'm afraid I don't have enough experience with toolkit collisions to comment much on this aspect. But at least the remaining arguments for FLTK are sound.

@abrolag
Copy link
Member

abrolag commented Dec 29, 2019

Well, seeing as Robin has said he's OK with it, here is the email I got from him.

Hi Will,

On 12/27/19 3:52 PM, Will Godfrey wrote:
> Hi Robin,
> 
> While discussing revision of Yoshimi's GUI, the suggestion was made to use
> FLTK V 1.4, not only statically linked, but also embed the FLTK code in Yoshimi
> (personally I have no idea how to do that... yet!).  

If that's possible that'd be great.

The plugin UI would be exposed as X11UI, CocoaUI or WindowsUI (native
UI, toolkit independent).

> This would give as a relatively painless way of at least getting re-scalable
> windows, and the possibility to tweak the code without months of redesign.
> 
> However somebody else then referred me to your comment on [LV2] plea to plugin
> UI devs (Wed Mar 16 12:21:28 PDT 2016).  

The root problem discussed there is that different plugins can use
different, incompatible, system-wide libs. That results in plugins
becoming exclusive to each other: loading one prevents loading another.

But if you manage to statically link the GUI (and hide symbols) so that
the plugin is self-contained and does not depend on external libs
(except libc, libX11), that'll be fine.

On Windows and for MacOS this already requirement already. It's only
GNU/Linux where most devs just use system-wide libs and cause
compatibility trouble.

I do not know if FLTk can be statically linked. With GTK it is
impossible and with QT it is hard, but Rui succeeded lately.

-=-

Anyway, as long as Yoshimi's DSP isn't realtime safe, I'd not bother
working on a LV2 plugin to begin with.

Also, you should first come up with a single-window layout. Multiple
windows is a no-go for plugins. If a plugin can have more than one
window, there'll be all kind of issues, both technical (event-loops,
signals), as well as user-experience (A host cannot restore them, nor
keep track of transient/on-top: windows vanish behind the main window..)

I wish I had better news, but I don't see how yoshimi could become a
plugin without undergoing a re-design similar to zynaddzubfx 2.x ->
zyn-fusion 3.0.

However, what I would like is a simple 'headless' plugin that only has
presets for musicians!

Use yoshimi, the JACK app, to design sounds. Then later while composing,
recording, or during production only have means to load and use presets.
Don't get distracted with sound-design (it's over the head of most
musicians anyway).

Then again, a simple, yet powerful GUI with a good preset-selector as
well as means to share presets, is a lot of work, too.

What do you think?
robin

First off, It seems he wasn't aware FLTK could be compiled statically - well neither did I till fairly recently :)
Second, he didn't know that we are now RT safe (hopefully).
Thirdly, and for later consideration, his idea of a separate 'lite' version of Yoshimi specifically for plugin use seems quite interesting. Also, Yoshimi does work as a plugin and seems pretty stable, although our LV2 implementation is pretty basic.

So overall I regard the situation as "apply caution, but we should be OK"

The link Rob posted was a very interesting and informative read. I was surprised that the guy didn't mention FLTK at all, but from my own reading it does in fact mainly provide wrappers for native OS GUIs ... and I've done a lot of reading over the last few weeks :(

@abrolag
Copy link
Member

abrolag commented Dec 29, 2019

I've just been informed that in FLTK 1.4 you can rescale individual windows with [CTRL} + and [CTRL} -
If this is correct, it's a game changer!

kybos, can you check this out as you already have a working version?

@kybos
Copy link
Author

kybos commented Dec 30, 2019 via email

@kybos
Copy link
Author

kybos commented Jan 7, 2020

Confirmed.

GUI can be scaled with Ctrl+/Ctrl- between 50% and 300% (the current value is even displayed on screen as a kind of quick info). My "fixed" scaling factor for HiDPI is 2, as I already mentioned above.

Still: Why is the dynamic scaling at runtime so important? Normally it should be sufficient to set the scale factor system or program wide (by means of the env var FLTK_SCALE_FACTOR) or in the program code itself (this is also how GTK and Qt do it, at least I am not aware of any dynamic scaling possibilities there).

@abrolag
Copy link
Member

abrolag commented Jan 7, 2020 via email

@kybos
Copy link
Author

kybos commented Jan 8, 2020

OK, I understand.
Then FLTK 1.4 seems to be a perfect solution indeed.

@dbtx
Copy link
Contributor

dbtx commented Jan 8, 2020

It isn't perfect.

FLTK uses a locking mechanism that wants to be activated from within a program's initial thread, namely the one that starts and ends with main(), and LV2 plugins have no way to do anything there. This is what I called "plugin-hostile requirements". I looked, and the 1.4 docs are identical to the 1.3 docs, so the answer to my question is "yes, it's still wrong".

Plugin-hostile means FLTK's design assumes you have access to main() or something directly under main() in the call graph, and I'd never expect that any kind of plugin would or even should. AFAICT, LV2 plugins do not; LV2 apparently doesn't specify a way for hosts to run arbitrary convenience callbacks which plugins can register, and why would they? This is a corner case.

You can ignore that, but then you may or may not get the weird symptom of random garbage leaking through stdout (or stderr, or something) onto a console, before the main window appears. This has happened randomly in the past with standalone Yoshimi, and happens right now upon loading the plugin in Qtractor. IMO it is a Real Problem™ no matter how harmless it also is. I'm not sure whether you call it undefined behavior or unspecified behavior. I don't know if FLTK actually chooses to jettison ill-timed inter-thread messages in exactly this way. I just know it isn't supposed to happen.

Someone could rework FLTK's thread system and then 1) convince the FLTK project to accept your change, and/or 2) bundle your modified FLTK in Yoshimi. If you were going to bundle and statically link 1.4.x anyway, this would be one more reason to do that. Getting upstream to understand the problem and then produce or adopt a fix before 1.4.0 is released, and then using that, would be the closest thing to perfect with the least overhead, if/f you can stand to wait for it... IMHO.

@dbtx
Copy link
Contributor

dbtx commented Jan 8, 2020

It may be that their documentation assumes something their code doesn't actually require, and I may have found a dirty workaround.

@abrolag
Copy link
Member

abrolag commented Jan 9, 2020 via email

@abrolag
Copy link
Member

abrolag commented Jan 11, 2020

One thing that puzzles me is why there is a need for LV2 to know anything about an application's native GUI - apart from opening and closing the main window - momemtarily disregarding the FLTK lock mentioned above.

Certainly in the case of Yoshimi, all child windows are managed by the master one with proper constructors and destructors. None of the controls we expose to the host directly access the GUI at all but are managed by the engine itself, with buffered updates each way.

@abrolag
Copy link
Member

abrolag commented Jan 16, 2020

Did a bit more investigating. The corruption when running yoshimi as an lv2 is not due to the GUI, it appears as soon as a yoshimi file is loaded in to the hosts (it also applies to Ardour and Muse). It is there as far back as V1.5.10, but I can't go back further as with all the GCC and MXML changes I can no longer compile them. However, I shoehorned an already compiled V 1.4.1 in and the corruption was significantly worse - although that might be due to some incompatibility related to its age.

Another oddity is that in LV2 we lock FLTK, then immediately unlock it again! Yet it seems to work quite correctly. I tried the same with standalone, and that seemed OK at first, but it locked up when trying to enable a new kit item while a MIDI file was running.

@dbtx
Copy link
Contributor

dbtx commented Jan 17, 2020

not due to the GUI

If you mean the same thing, and unless you stumbled on some other bug, it is due to something trying to do anything to/with/about the GUI when the FLTK lock hadn't been intialized at all (which is said to be done by the first call to Fl::lock()), which goes hand in hand with some GUI data structure(s) not existing yet, because we are doing it wrong.

Another oddity is that in LV2 we lock FLTK, then immediately unlock it again!

The if (bInit) suggests that this was for the sake of initializing the lock, but in that case, unlocking it seems to be incorrect. I don't know. I commented out Fl::unlock() and the world didn't explode, but that doesn't mean much.

That dirty workaround is to simply call Fl::lock() "somewhere" that you can convince yourself will always run earlier than anyone else first tries to touch a non-existent GUI (or its thread message buffer, not quite sure). When I added it at the top of YoshimiLV2Plugin::instantiate(), that stopped the junk, and it appeared to not instantly break everything. Then both the lock and unlock calls in YoshimiLV2Plugin::show() seem to be removable. It still isn't kosher.

@abrolag
Copy link
Member

abrolag commented Jan 19, 2020

Thanks. Followed elsewhere :)

@dbtx
Copy link
Contributor

dbtx commented Jan 19, 2020

Just to finish my earlier thoughts--

I don't know if FLTK actually chooses to jettison ill-timed inter-thread messages in exactly this way.

Well, it's not intentional, but this is sort of what happens. Our messages are incidentally written to stdin until the destination is correctly set, and stdin is also the terminal. As long as we didn't already bring up the CLI (and we didn't), there was no problem but the cosmetic one.

It may be that their documentation assumes something their code doesn't actually require, and I may have found a dirty workaround.

Good news: That already-linked documentation isn't very specific about different requirements for different platforms. IIUC Windows always wants main()'s thread to do GUI things, but that doesn't matter to us. So it isn't dirty as I expected (or feared)-- stuff can still be done safely and FLTK 1.4.x can be the right tool.

@abrolag
Copy link
Member

abrolag commented Jan 21, 2020

If we are all agreed on on this, would someone like to take the project on?
To recap, build the latest FLTK 1.4 into yoshimi itself (presumably as a sort of sub-build similar to the way LV2 was done).
If anyone does, please say so here. I don't want us to end up with either of the two extremes.
1/ Everyone thinks someone else is doing it so backs off.
2/ Several people get started on it, then get put off because someone else is doing it too.

In a perfect world I'd be delighted if this could be done in time for LAC in May. I'll be going there on the 10 regardless of whether I've got a workshop slot.

@abrolag
Copy link
Member

abrolag commented Feb 27, 2020

Anyone able to do this? I've had a look myself, and it's too much for me I'm afraid :(

@steevithak
Copy link

I've just tried Yoshimi for the first time on Fedora 32 and noticed the size problem. I use a 4k monitor due to my photography and video work, so I can't easily switch to a lower resolution desktop. The Yoshimi window is about 2 inches wide by 2.5 inches tall on my 27in monitor! It's barely big enough to make out the text and the controls are small enough that it's very difficult to accurately position the mouse pointer over them in a way that allows me to use them. Is there a way it could query the Gnome desktop to get the screen DPI and scale up accordingly?

IMG_20200507_162358_2 (1)

@abrolag
Copy link
Member

abrolag commented May 8, 2020 via email

@abrolag
Copy link
Member

abrolag commented May 9, 2020

@kybos when you compiled fltk1.4 did you have to also remove V1.3.5?

I've tried working with the current fltk master, which itself seems to compile and install without issues into /usr/local/include but when I try to compile your fork of Yoshimi I get a mass of 'undefined' errors :(

I'm reluctant to disturb the fltk 1.3.5.

This is on devuan beowulf

@kybos
Copy link
Author

kybos commented May 9, 2020

Yes, I uninstalled fltk 1.3.

@abrolag
Copy link
Member

abrolag commented May 11, 2020

Hmm I tried that and still couldn't get it to compile. I can't do much more now, as I need to have V 1.3.5 running for normal development, and removing it also meant I had to rebuild a surprising number of other programs afterwards.

I really don't know where we go from here :(

@kybos
Copy link
Author

kybos commented May 16, 2020

Strange.
I repeated the whole thing just to make sure. I got current FLTK 1.4 from master, compiled and installed it, and recompiled yoshimi. No issues here.

@abrolag
Copy link
Member

abrolag commented Sep 21, 2020

Don't hold your breath, but it is just possible we've found a way to independently change window sizes while keeping everything in proportion. This should eventually include text sizes and positions. It would then also be possible to save this setting along with the existing position info.

@abrolag
Copy link
Member

abrolag commented Sep 22, 2020

There is a new development branch 'resize'.
The simplest window of all (right click on 'Controllers') is now fully and independently resizable, and maintains the size relationship between knobs and their associated labels.
Currently this status is not saved, but that's not difficult to achieve.
For shits and giggles try the full screen icon - just how big do you want it? :)

Some of the other windows will present 'interesting' challenges - menus, packs, scrolls.

@abrolag
Copy link
Member

abrolag commented Oct 31, 2020

Just an update:
Work on the resize branch is progressing very well at the moment. There are a few windows not yet done, and there may be some issues with those that are complete. "dev_notes/resize.txt" gives details. It could do with a good shake-out on different systems.

@abrolag
Copy link
Member

abrolag commented Jan 7, 2021

The current master now has fully independent resizing of all windows. Last seen position is stored, and on reopening is sanity checked, to ensure widows start out visible, even if when saved they were at a hi res position that would put them outside a current lower res screen size.

Tooltips should also resize, but that hasn't been confirmed. It may depend on the FLTK version.

Finally, some internal icons in widgets (such as spin boxes) are hard coded so we may need to find way to override these.

@abrolag
Copy link
Member

abrolag commented Feb 2, 2021

As this is effectively complete now, I'll close this

@abrolag abrolag closed this as completed Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants