rust-windowing / winit

Window handling library in pure Rust
https://docs.rs/winit/
Apache License 2.0
4.76k stars 893 forks source link

What would be the preferred method to put some text in a window? #566

Closed vermaseren closed 6 years ago

vermaseren commented 6 years ago

I know that winit does not write in the window, but OpenGL etc are way overkill for what I have in mind. I am porting a text editor (number n+1) because its GUI is so old fashioned that it will probably not survive one or two more years of updates. Winit looks like the nicest option, but I do not need all the machinery that video games use. I want things to be as portable as possible. And I do not want to have to learn the whole of X11 or gtk. Also overkill in my eyes. Any suggestions?

francesca64 commented 6 years ago

I want things to be as portable as possible. And I do not want to have to learn the whole of X11 or gtk. Also overkill in my eyes.

Well, you've painted yourself in a corner. If you don't want to use OpenGL, you have to use platform-specific software rendering APIs. Making a library that abstracts over those in a cross-platform fashion would be a complex and time consuming endeavor.

My recommendation is to use gfx and gfx_glyph. Both are well-supported and maintained, and you'll get results that are both performant and cross-platform. gfx_glyph doesn't even require you to write any shaders, so you could probably get away with using an extremely small subset of the gfx API.

If that doesn't sound appealing to you, imgui should be quite a bit more simple than GTK. That uses either glium or gfx as a rendering backend, and while you don't have to handle any of that yourself, you'll still be susceptible to the same driver bugs and other considerations.

vermaseren commented 6 years ago

Thanks for your suggestions. I will study them and see what can be used, both under linux and MacOS. I had some pretty bad experiences trying to install various systems. I will report once I get things going to satisfaction.

vermaseren commented 6 years ago

Well, that was failure number n+2. gfx does not install on my MacOS. It misses too many things, some of which I can find after all and some parts got running (I even got some window) but by the time I wanted to set up the whole thing it started complaining about x11 and I did not manage to pass that. Hence: try imgui. That went much better (at first). I got it installed under MacOS and the examples worked according to the 'manual'. Hence on to the linux computers: Note that I am a user there without sudo rights. The thing installed, but when running the examples I get the error message: libGL error: unable to load driver: swrast_dri.so libGL error: failed to load driver: swrast Some searching later, it becomes clear that swrast does not exist on this computer (and a few others). I even doubt that they have a video card. They do run winit however and pass the window on to my laptop, even via a tunnel. Some parts of gtk seem to function though.

Is there really no simple way to draw text in a winit window, without the need for complicated graphics systems? Or just a simple display postscript (that I am still rather good at)?

francesca64 commented 6 years ago

Is there really no simple way to draw text in a winit window

Keep in mind that a winit window isn't anything special. Any C library you can find that puts stuff in a window would be usable (provided it doesn't insist on doings its own windowing). Of course, a library of any language would work, but would possibly be more fiddly to integrate / justify calling Rust code from that runtime instead of vice versa. WindowExt methods, which are platform-specific and live under the os module, provide you with ways to get the XWindow ID, the NSWindow pointer, etc.

The Rust GUI ecosystem (which itself is immature), as you've seen, is focused on using the GPU. It sounds like you require things to work with no fuss and no GPU. From a cursory look through, minifb uses software rendering, but it does its own windowing, which is likely buggy... however, you can then use something like rusttype to rasterize text to that framebuffer, but you'd still have to handle positioning, text flow, etc. yourself.

If you really want to avoid GTK (and aren't aware of any other libraries you can try in other languages), then you might want to consider using the platform APIs. NSText doesn't look so bad (Cocoa APIs are generally pleasant), and while X11 isn't known for being intuitive to modern developers, you can always ask me questions about it. I know I made it sound like abstracting over these was involved, but provided you're doing so for a specialized usage with a narrow scope, it's probably manageable.

I know none of this sounds good, but I must emphasize that using Rust for graphical applications is still something that often requires you to write a great deal of your own code to replace what's missing in the ecosystem. For instance, if you needed right-click menus, you'd end up having to sink at least a week of your life into drawing those from scratch on X11, and they'd still visually clash with those of other applications (X11 has no concept of native widgets, but GTK and Qt are de facto native). I can't recommend using Rust for this if you're not eager to do considerable extra work, especially since software rendering isn't a priority for most of the ecosystem.

vermaseren commented 6 years ago

I appreciate very much the information you are giving and googling around I also noticed that there is no complete GUI system yet for rust. Quite a few under construction, but how many will be finished within a reasonable timespan?

Over the past few days I have been trying several 'systems'. In the end I got only two to work: gtk and cursive (on both MacOS and a battery of linux servers, hence satisfying my portability criteria). For the linux I needed intervention from a sysadmin, because ncurses was not installed. Both I have running from rust. And I have winit running. Actually I like the look of winit most, but gtk and cursive seem to have their own windows. Can one run either in combination with winit? Are there any example files of how this is done? Or do I have to abandon the idea of using winit? What I know of X11 is that I still have some very fat manuals from the 80's and 90's that I never managed to get very far in. I presume that nowadays there must be many examples that bring the threshold down, but still.... In the worst case I will have to study gtk although it seems much overkill. Probably the simplest would be if curses (=cursive) can be used inside winit, but again, I have not seen any examples (or good manuals).

rukai commented 6 years ago

Just use gtk, its fine.

francesca64 commented 6 years ago

how many will be finished within a reasonable timespan?

If you exclude ones built on top of web technologies, then probably 0. Things could go much faster if some corporate interest decides to throw money at the problem, but I don't see that as likely. We still haven't really figured out how to architecture a GUI framework in idiomatic Rust, and after that, it's still a massive amount of work.

That said, it's something hotly demanded by the community, so as Rust grows and we converge on a solution, I'm sure something great will emerge eventually.

Can one run either in combination with winit?

That's definitely impossible with GTK. It would take an extreme amount of restructuring in GTK's internals to enable that kind of decoupling.

Cursive looks like it just renders to the terminal, so using that with winit wouldn't make much sense (you'd have to make your own terminal emulator), and it's preferable to just run that sort of thing with the user's terminal of choice, I imagine.

I presume that nowadays there must be many examples that bring the threshold down

There aren't. Almost nobody in the past 20 years has written anything about X11, and the Xlib documentation is quite spartan, only being comprehensible to people who already understand the design. X11's drawing API is especially esoteric, since the source code of projects like SDL/GLFW/winit/etc. is no longer applicable for research, which means that very few people will have ever even touched it.

In your specific case, I think it wouldn't be too much of an issue, but I'd still consider it a last resort.

Itanq commented 5 years ago

My recommendation is to use gfx and gfx_glyph. Both are well-supported and maintained, and you'll get results that are both performant and cross-platform. gfx_glyph doesn't even require you to write any shaders, so you could probably get away with using an extremely small subset of the gfx API.

Sorry, I can't run successfully with gfx_glyph in winit, Is there a example about use gfx_glyph in winit?

Osspial commented 5 years ago

@Itanq gfx_glyph's provided examples all use Glutin, which is essentially Winit with OpenGL context creation functions glued on top.