beeware / podium

A Markdown-based native presentation tool
BSD 3-Clause "New" or "Revised" License
182 stars 28 forks source link

Running podium on Linux platform #29

Closed andreysmelter closed 4 years ago

andreysmelter commented 5 years ago

Hi @freakboy3742, @danyeaw

I was working one day at PyCon sprints on trying to make podium run on Linux platforms. The issue was that application exits immediately after starting it without launching application window and with no errors.

>>> from podium.app import Podium
>>> papp = Podium()
>>> papp.main_loop() # print statements before and after self.loop.run_forever(application=self.native)
self.loop:    <GtkEventLoop running=False closed=False debug=True>
self.loop:    <GtkEventLoop running=False closed=False debug=True>

When we execute papp.main_loop() method we should see only the first print statement and podium app window should pop up.

Instead no window pops up and self.loop.run_forever() exits out.

I think I found the reason - the podium app is not setting the interface correctly. For example:

As a result when self.interface.startup() method gets called it only calls the podium.app.Podium.startup() method which only sets the Podium application commands and does not call the higher level interface startup() method which supposed to create and launch main window application.

Can you comment if this is correct?

Thanks!

freakboy3742 commented 5 years ago

@andreysmelter I don't think that's right. podium.app.Podium is a subclass of DocumentApp, so the interface that papp._impl is correct, AFAICT.

The problem (as I understand it, anyway), is in the nature of a DocumentApp itself. In a base App, starting an app creates a Window. However, in a DocumentApp, The App starts, but only creates a Window when it opens a Document. It might do that because the App was opened with a double click on a document icon; but if the app was opened without a reference to a document, it still needs to start, and direct the user to an "open file" dialog.

However, because the application is being created without a window, the startup logic isn't being invoked correctly. I don't know enough about GTK to comment on why that is, but "starting an application without a window" is somewhat counterintuitive behavior, so it's not entirely surprising.

bittner commented 5 years ago

The issue was that application exits immediately after starting it without launching application window and with no errors.

This seems to describe the behavior mentioned in https://github.com/beeware/podium/issues/11#issuecomment-515740679.

bittner commented 5 years ago

The Hello World tutorial app has a show() call in its startup code, which I can't spot in podium.app:

class HelloWorld(toga.App):

    def startup(self):
        self.main_window = toga.MainWindow(title=self.name)
        self.main_window.content = toga.Box()
        self.main_window.show()

GNOME's GTK4 docs suggest that there must be a window shown for a GTK application to be launched. Maybe the app's main loop is tied to that logic?

Should we investigate whether it's possible to launch a GTK app without a window? Or abort with an error or something?

freakboy3742 commented 5 years ago

@bittner The underlying issue here is that Podium is a "document based" app - that is, the windows in the app relate to open documents, rather than "the app" itself. A word processor is the classic "document-based app" - there's no idea of opening the word processor app without opening at least an empty document.

A "simple" app (like HelloWorld) has a main window, and thus a "show" call to display that window. It can also have other windows, if it wants them; but it's up to the app to manage them.

A document-based app doesn't have a main window - it has a collection of documents, each of which has one (or more) windows.

That explains why there's no show() call in the Podium - the app doesn't need to show anything. But each document that the app opens does - and if you follow the breadcrumbs down the Document definition for a slide deck, you'll see that opening a single SlideDeck Document results in 2 windows being created, both of which are shown as a part of opening the document.

Toga has an API for document-based apps, but that API has only been implemented (so far) for macOS. That's one of the two big pieces that is missing before Podium will work (the other is implementing the full-screen API).

On macOS, there's no requirement that an app have a window. However, if an app starts and there's no document specified, the app will automatically open a file dialog. I'd suggest that the GTK approach would be to emulate this sort of behavior. If you start the app and a document is provided (e.g., by double clicking on a document, or as a command line argument), then that document is opened; however, if there's no document specified, then the application will open a file dialog. If the user closes an open document, and ever ends up in a "no documents open" state, then it reverts to displaying the file open dialog. That way there will always be an open window - even if that window is just a dialog.

(That said - I will also state that I'm not a Linux native user, so I'm not necessarily 100% familiar with Linux desktop idiom. The fundamental aim of all Toga APIs is to generate behaviors that result in an app that feels completely native, not "macOS behaviors crammed into a Linux shell". The concept of an app that operates on a document is universal; the behaviors around that aren't necessarily universal. So - no matter what I've said here - the actual behavior we should be aiming for is "whatever a truly Linux native app would do". So - what happens when you start OpenOffice? Do that)

hawkowl commented 5 years ago

Fixes for toga: https://github.com/beeware/toga/pull/714 Fixes for podium: #31

danyeaw commented 4 years ago

Closed by #31.