darlinghq / darling

Darwin/macOS emulation layer for Linux
http://www.darlinghq.org
GNU General Public License v3.0
11.39k stars 440 forks source link

Simple GUI consumes 100% and not showing anything. #783

Open HinTak opened 4 years ago

HinTak commented 4 years ago

I tried this - it is just a very thin wrapper which sets a bunch of options for an underlying command-line tool (I wrote that tool - the GUI was contributed by somebody else, and I have no experience with Mac GUI app) - the GUI is mostly a lot of toggle buttons: https://github.com/HinTak/Font-Validator/blob/master/MacUI/build/FontValidator0.1-7.zip

It outputs these on the console:

Darling [/Volumes/SystemRoot/tmp]$ FontValidator.app/Contents/MacOS/FontValidator
2020-05-10 22:57:48.150 FontValidator[188:3e8] NSScanner: nil string argument
2020-05-10 22:57:48.151 FontValidator[188:3e8] -[NSButton setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSView
.m at 1947
2020-05-10 22:57:48.152 FontValidator[188:3e8] NSFont decoding done
2020-05-10 22:57:48.447 FontValidator[188:3e8] NSTextField initWithCoder
2020-05-10 22:57:48.448 FontValidator[188:3e8] -[NSTextField setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSV
iew.m at 1947
2020-05-10 22:57:48.449 FontValidator[188:3e8] -[NSButton setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSView
.m at 1947
2020-05-10 22:57:48.449 FontValidator[188:3e8] NSFont decoding done
2020-05-10 22:57:48.449 FontValidator[188:3e8] NSTextField initWithCoder
2020-05-10 22:57:48.449 FontValidator[188:3e8] -[NSTextField setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSV
iew.m at 1947
2020-05-10 22:57:48.449 FontValidator[188:3e8] missing color for labelColor
2020-05-10 22:57:48.450 FontValidator[188:3e8] -[NSView setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSView.m
 at 1947
2020-05-10 22:57:48.450 FontValidator[188:3e8] -[NSView setCanDrawConcurrently:] unimplemented in /home/Hin-Tak/git-others/darling/src/external/cocotron/AppKit/NSView.m
 at 1947

Then just eats CPU without showing anything. The source code is in the directory above.

bugaevc commented 4 years ago

Well, the good news is that it didn't encounter any errors.

As far as I can see from the source code, this is a "document-based" app. On macOS, these apps usually don't open a window by default when you launch them directly. But they install their menu to the global menu bar up on top, and you can open a file from there.

This doesn't work so well on Darling because we don't (yet) support global menus even on those desktop environments that use a global menu. So you don't get any windows and you don't get a menu. Maybe we should work around this by making document-based apps always open a new, untitled document. But for now, you can workaround this by using the NSOpen default to tell the app to open a file. The simplest way is to set it in the command line like this:

Darling [~]$ /Applications/MyAwesome.app/Contents/MacOS/MyAwesome -NSOpen Downloads/file.ma
schriftgestalt commented 4 years ago

In macOS, each app has one main menu. If you are plan to improve support macOS apps, it would be good to support a global menu and don’t put the menu into each window. I think I have seem some Linux screenshots that had a global menu, so that should be doable.

bjorn3 commented 4 years ago

Only some Linux desktops, like Unity, have global menus. Most don't have support them in any way. There is simply no place to show them.

schriftgestalt commented 4 years ago

(I don’t know anything about Linux, so that might be stupid)

To "simulate" a global menu, make a window that only contains the menu and pin it to the top of the screen. And make sure that all regular windows can’t be moved under/over it.

bugaevc commented 4 years ago

We plan to support both global and in-app menus (automatically, depending on what your DE prefers/supports). But at the moment only in-app menus are supported.

If anyone here wants to work on global menu support, feel free to ask me for tips & pointers 🙂

bugaevc commented 4 years ago

To "simulate" a global menu, make a window that only contains the menu and pin it to the top of the screen. And make sure that all regular windows can’t be moved under/over it.

No, that is absolutely not how it should be done. It's not an app's job to create/simulate parts of the system/DE UI. (By the way, this is what GNUstep does by default 😆)

The right way to do this is to ask the DE, over D-Bus, to show your menu. DBusKit already comes with sample code showing how you would do this (for GNUstep).

schriftgestalt commented 4 years ago

No, that is absolutely not how it should be done. It's not an app's job to create/simulate parts of the system/DE UI.

Why? In this case it is not a system UI, just moves the menu out of the window.

It is kind of like the old Window document app model where you had a main window (with a menu) and the doc windows where inside that window. Make that "frame" window fullscreen and the background transparent and you have a fully in app main menu.

schriftgestalt commented 4 years ago

What do you mean by "global" vs "in-app" menus?

bugaevc commented 4 years ago

Why? In this case it is not a system UI, just moves the menu out of the window.

Because your app is not running on a bare X screen; there's a whole Desktop Environment around it. Perhaps it already includes a panel at the top; perhaps other apps already put their menus there. Perhaps it doesn't, and the customary way to display menus on that DE is to do it in-app. In any of those case, just making a separate X window with your menu and sticking it at the top is wrong. In GNUstep case, it's not as bad because they wanted to emulate NeXTSTEP app menus, which indeed were drawn in a separate (movable) window by the app.

What do you mean by "global" vs "in-app" menus?

Here's an in-app menu:

image

Here's a global menu:

image

schriftgestalt commented 4 years ago

I would not call it like that. I would call it "in-window". The window is not the app, the app can have many different windows. And "global" sounds like that several apps are using/controlling it. If you look from the mac side, that is different. In MacOS, the main menu IS the app. Everything else are just some windows.

I understand that the system works differently on Linux and that a good translation has to be found. But to get started, I would suggest to follow the internal object structure as close as possible. And that means there is one instance of the main menu. Because a lot code might rely on it.

(I’m nitpicking on the terms a bit to make sure that it is clear how certain things work.)

bugaevc commented 4 years ago

And "global" sounds like that several apps are using/controlling it.

Yes, it is a single (global) menu panel that displays the menu on behalf of the currently focused app/window.

But to get started, I would suggest to follow the internal object structure as close as possible. And that means there is one instance of the main menu. Because a lot code might rely on it.

The internal API is the same in any case: you create an NSMenu instance and assign it to NSApp.mainMenu. If an in-app/in-window display style is chosen (which is the only one we/Cocotron can currently support), then each non-panel window gets an instance of NSMainMenuView added to its NSThemeFrame. Otherwise (to be implemented), the menu is sent to the DE to be displayed in the global panel over D-Bus.

Do you actually want to work on this?..

schriftgestalt commented 4 years ago

If my apps update id finished, I think I can have a look at this. But I don’t know anything about Linux APIs so I don’t know how useful I am.

HinTak commented 4 years ago

@schriftgestalt - on a different issue: I have noticed in that past when I was running the GUI in proper mac os x under a VM, the CPU consumption get pegged at 100% (ties up 1 core entirely) - it did not bother me then, because it runs okay, and I thought it might be a VM issue anyway. But it is happening under darling too - is the GUI supposed to be very busy polling for mouse clicks, for example?

HinTak commented 4 years ago

On the whole I am okay with the darling folks doing what they think is appropriate, and in their own time/schedule. I filed this because I think since it is a simple GUI, it is probably useful as a test case.

Thanks @bugaevc for the NSopen tips. I'll give it a try soon. Mostly I am more interested in #782 - Apple's own font tool under darling. This #783 is more since I have got the binary and it is supposed to be simple and we have the source code, just give it a try and see.

bugaevc commented 4 years ago

No, 100% CPU consumption is definitely not intentional, and we're not busy-waiting for X events. Maybe you could find which thread is it that keeps running, and what it is doing?

HinTak commented 4 years ago

As I mentioned, it was 100% under genuine mac os x in qemu/kvm too, so probably an issue with the app itself. It just did not bother me there, as I launch the GUI, gives it an input file, and it is supposed to do that once the underlying command line kicks in anyway. Here it is obviously not processing any input file.

LubosD commented 4 years ago

It just crashes for me, because we don't have NSLayoutConstraint implemented yet.

2020-05-12 09:28:39.201 FontValidator[1366:3e8] Stub called: initWithCoder: in NSLayoutConstraint
schriftgestalt commented 4 years ago

The app behaves totally normal for me. What VM and version of macOS did you use?

HinTak commented 4 years ago

It was OS X 10.9 under qemu/kvm . Could be a linux display issue though.

schriftgestalt commented 4 years ago

It should not consume more (or less) CPU than TextEdit.