godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Allow hiding the main project window temporarily #9032

Open Sooshiko opened 7 months ago

Sooshiko commented 7 months ago

Describe the project you are working on

I am working on a custom crash handler that launches a program and only appears when the program crashes (AKA the window "shows" when OS.execute returns != 0)

Describe the problem or limitation you are having in your project

Describe the feature / enhancement and how it helps to overcome the problem or limitation

When you set the main window's visibility to false you get an error "Can't change visibility of main window". Is there a way to change that so you can?

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Setting the visibility through script like $"/root".visible = false

If this enhancement will not be used often, can it be worked around with a few lines of script?

Is there a reason why this should be core and not an add-on in the asset library?

If someone can make a GDExtension to fix this. I'd like to see them try.

Sooshiko commented 7 months ago

This is very similar to https://github.com/godotengine/godot-proposals/issues/6829 but I thought I'd make it more specifically about Godot 4.x since that's where the error happens. Sorry for the inconvenience.

AThousandShips commented 7 months ago

This would in my opinion be error prone, making it harder to deal with situations where you accidentally hide it and can't restore it, also this would require some new special processing because hidden windows are completely deleted, which could cause other problems I suspect

I'm not even sure the game would still have a system bar entry once the window is deleted, making it hard to kill the process

I'm not sure there's a wide need for this

Calinou commented 7 months ago

Regarding GUI crash handlers, consider what was proposed in https://github.com/godotengine/godot/pull/61906#issuecomment-1923271234. You can have a crash handler run another Godot instance that only needs to run for as long as the crash dialog needs to show up. This prevents having a second Godot instance in the background that uses up CPU and memory for no good reason.

Sooshiko commented 7 months ago

I seriously doubt that people would "accidentally" hide the main window and be unable to retrieve it.

Also the crash handler shouldn't use CPU at all since I launch the game's executable in a thread blocking way. and the RAM it uses would be very negligeable.

AThousandShips commented 7 months ago

So the app vanishing from the task bar won't cause any problems? Or confusion over users having to force stop the program as that'd be the only way to close it if it doesn't have a window?

Then no worries, but don't underestimate how people can mess up and end up in unrecoverable states, and we shouldn't make that easier IMO 🦶🏻 🛑 🔫 (this should have been obvious but explaining, this means "let's not allow people to shoot themselves in the foot", in the future just ask...)

Sooshiko commented 7 months ago

The app not appearing on the task bar while no window is visible is good and I want it to work like that. I've never had any problem in any other engine before. Nor have I ever heard of people being confused by background tasks. I don't know why you are being so confrontational about such a common feature.

AThousandShips commented 7 months ago

I'm not being confrontational

I'm just trying to help and give feedback, but if you're not able to respond to that feedback in a professional manner I'll see myself out, but please reconsider why you take feedback as someone being confrontational

Can I please get some mediation: @godotengine/code-of-conduct

Sooshiko commented 7 months ago

No you can't turn this on me lol. You end your "feedback" with gun emojis and stop signs. Claim people are too dumb to be trusted with closing a window. Also I love how you call me unprofessional when I'm a hobbyist. You are the one representing godot here.

But enough about that, I tried Calinou's solution (Assuming you meant running a headless program that runs the game in a blocking manner and starts a different executable if a crash is detected) way back in 3.x. It did work as I wanted but whether or not I could send the correct error message to the "Error Window" was inconsistent at best. I don't know if it depends on how the game crashed (I.E. out of memory, crashed in a seperate thread, shader compilation failure) but It often sent me incomplete logs. Was that fix or should I try it again in 4.x and open a seperate proposal if I find a problem?

Other than that my only problem is shipping 3 Executables with my game.

Jonathan-Stevens commented 6 months ago

This functionality would be very useful for an XR platform tool I'm working on. This tool would render exclusively through the user's XR headset unless the user elects to enable an onscreen preview/mirroring setting, in which case Godot's main window would appear onscreen.

Since the tool is intended to be used exclusively with an XR headset and 6DOF motion controller, there is no need to waste system resources rendering a main window on the user's monitor. I would rather make my XR platform tool only appear in the system tray and hide the main window to minimize my tool's burden on system resources.

I briefly experimented with running my app in headless mode, but my understanding is that this is intended more for game servers, and I ran into graphics API errors when I gave it a try (presumably because it "disables all rendering" in headless mode, per https://docs.godotengine.org/en/stable/classes/class_displayserver.html).

Something along the lines of this proposed functionality would enable my XR tray application to work as intended while maximizing performance. Alternatively, an option to dynamically enable/disable rendering in headless mode may also solve my issue.

Calinou commented 6 months ago

@Jonathan-Stevens It sounds like your use case would be better covered by off-screen rendering. If you hide the main window, Godot wouldn't be able to render anything until off-screen rendering is implemented.

I briefly experimented with running my app in headless mode, but my understanding is that this is intended more for game servers, and I ran into graphics API errors when I gave it a try (presumably because it "disables all rendering" in headless mode, per docs.godotengine.org/en/stable/classes/class_displayserver.html).

Indeed, it's not possible to use XR and headless at the same time because the headless DisplayServer skips all rendering calls.

Alternatively, an option to dynamically enable/disable rendering in headless mode may also solve my issue.

This would need https://github.com/godotengine/godot-proposals/issues/6423 but for DisplayServer.

Jonathan-Stevens commented 6 months ago

Thanks @Calinou, off-screen rendering does seem like it would cover my use case.

I notice that the proposed way to enable off-screen rendering is with an --offscreen CLI argument passed in at launch. To enable my application to conditionally present an onscreen preview, would I need to do something awkward like calling OS.set_restart_on_exit() to restart my app with revised CLI arguments? Or would a child window suffice, assuming child windows are not also considered virtual in off-screen mode?

Calinou commented 6 months ago

To enable my application to conditionally present an onscreen preview, would I need to do something awkward like calling OS.set_restart_on_exit() to restart my app with revised CLI arguments? Or would a child window suffice, assuming child windows are not also considered virtual in off-screen mode?

I don't know if off-screen rendering would make it possible to spawn additional visible windows. I guess it is technically possible, but I can't guarantee an eventual implementation of this feature will support this.

Neuroburst commented 2 weeks ago

One workaround is to enable the window's unfocusable flag, which hides it from the taskbar, and then minimize it; effectively making it invisible. Although this isn't perfect as when it requests focus for any reason, it unhides from the taskbar. It also can be janky at times, where it sometimes just doesn't hide from the taskbar. This can be combined with a tray icon to make the program "run in the background". I tested this on Windows 11 and it seems to work well enough for now...