I believe that a document-based GNOME application should do these things, even I start two instances from the panel’s Applications menu rather than starting the second instance from the application’s File menu. (For now, let’s ignore single-instance tabbed applications such as gedit.)
- File/Quit should close both instances.
- It should list the open instances in a Documents menu.
- It should warn me if I open a file that is already open in another instance, offering to just bring it to the front.
Single-process, single-instance
Firefox does this. Gnumeric and Abiword don’t, though it works for a second instance that I open via File/New. They probably start extra File/New instances in the same process and keep track of them via static data.
They could solve the problem by enforcing a single-instance via libunique, so the one process knows about all “instances”. Yesterday I easily added libunique support in my experimental gtkmm document/view framework, Bakery, because I want to fix this problem in Glom.
Many processes, single-instance?
However, having all application instances in one process gets annoying fast. Applications do hang or crash sometimes and it’s nice if that does not affect every open instance of the application. People probably don’t notice this because they rarely use File/New or File/Open. They probably do notice that File/Quit and the Documents menu don’t work as they’d expect.
So I guess we need some RPC to allow each application instance’s process to talk to all the others, maybe using a D-Bus interface. But that would quickly get complex and buggy and would provide multiple opportunities for code duplication and inconsistent behavior. I guess some shared API is needed. Has anyone else thought about this or even solved the problem already? Is there even one application that does it properly already?
Maybe it would be simplest for application instances to register themselves with a desktop-wide D-Bus service which could also be asked for a list of open documents.
What do other platforms do?
Back when I used Apple MacOS (versions 5 through 8) this was normal and worked, probably partly because the Finder maintained a list of open documents and didn’t even try to open second instances of already-open documents. The MacOS toolbox API was incredibly primitive back then so I guess that applications solved this individually. But it was a simpler time.
I wonder if MacOS X has actual API to help applications solve this problem.
The requirements listed are really the basics for document-centric applications. Applications using that model should by definition behave like this, otherwise they are not finished yet.
And, a document-centric application doesn’t ask if a document is opened “a second time”, it should simply be brought forward. Asking should only be done when there is no obvious solution — for example detecting that the open version is out of sync with the on-disk version.
OS X absolutely has an API to solve this, I haven’t looked at it for a long time, but there are basic application and documents controller objects in Cocoa that you would override.
Document-centric interface should not feature a File→Quit menu item, but only a File→Close menu item that closes (only) the current document.
Nothing against a single-instance model, but please don’t use a single-process model for this. With Firefox it’s really evil how one bad site can crash all open Firefox windows. With Gedits single-process model it’s at least annoying that you have to close all Gedit windows to reload a plugin – if it used multiple processes, I could restart one (testing) Gedit window and leave the other windows open (now I have the weird situation of writing Gedit plugins in Kate).
Gnome-terminal apparently switched to a single-process model as well recently, and I still wait for the day where one crashing terminal closes all other terminals on my desktop (no problems so far, but the threat is there).
Essentially, I think it’s important to ensure that such change does not lead to worse behavior in other places.
OS X does it all in the same process, and there are things in the toolkit to help you do it. It’s based around an app having windows for documents, but being able to run without any windows visible or documents open.
I rather like that model myself, although in a GNOMEish environment having the application quit when the last document closes is a more logical solution, since there’s nowhere for a running app to live if it has no windows, and keeping it in the background with no UI indication of it running is just going to lead to people wondering why their swap is full.
A multi-process model would be nice though, for reducing the impact of crashes. I’m not aware of anybody who actually does it like that. The closest thing I can think of right now is Google Chrome and Internet Explorer 8, which run their tab contents as separate process for stability isolation – but there’s still one process that’s in control of the actual UI for that, so it’s not a peer-to-peer arrangement.
Easy to envisage some sort of D-Bus interface where you listen on org.gnome.gedit for things like ‘is there an instance open with this file’ or ‘I have opened this URI’ but I’m not sure how well that would work in practice. Each new one would need to get a complete list of all other open instances, so there’d need to be a way to request that. It might get a bit messy. Could well be worth doing though, and it could be done in such a way that apps could use the same process or different processes at will and nobody else would have to care.
oliver +1
Oliver, some applications do have a legitimate reason to open the same document in two windows. For instance, you might want to see the file as it is on disk, though you already have it open with unsaved changes. You might also want to view a file in different ways, at different zoom levels for instance. But, I agree that that feature should not be in the way.
Murray:
* File/Quit should close both instances.
Nope. The should only be File→Close. Why would I ever need to close all the windows of a single app if the app is not broken? If it is broken, why would I work around it instead of fixing it in the first place? :)
* It should list the open instances in a Documents menu.
Nope. People don’t see a picture (eog) and a PDF (evince) as two separate kinds of objects. If you implemented the Documents menu in such way you’d need to put all the windows of all running apps there.
* It should warn me if I open a file that is already open in another instance, offering to just bring it to the front.
I’d say it should just open it and display a clue bar telling you the file is already opened elsewhere (and make it read only until you close the bar). It does not introduce new windows and requires less actions to be taken by the user in both cases (need 2 copies vs. oops, I only needed 1).
Action at a distance – ie. File->Quit closing other documents – is inherently bad. I agree with the various people above that if you’re truly going for document-centric, references to the application (ie. Quit) make no sense.
I guess optimal is:
– single process, single instance – not document-centric application (newsreaders, mail readers etc.)
– single process, multiply instances – none
– multiply process, single instance – great for aplications exposed to outside world in sandboxes. But I guess none is also applicable
– multiply process, multiply instances – nearly all applications – document-centric (eog, evince etc.) and multi-window non-document centric (web browsers etc.)
I agree that in case of document that’s already opened the window should be bring to the front.
Patryk, Andrew, I agree that File/Quit is not that useful, but a) it’s specified in our HIG, b) it’s familiar from other platforms such as Windows and MacOS, and c) I can guess that there are _some_ applications where I care about it, though I can’t honestly think of an answer. I suspect that many more people than we would like do think in terms of applications rather than documents. For instance, plenty of people rename files via file chooser dialogs. They aren’t geniuses but they are real.
I wouldn’t be against removing it (and the Documents/Windows menu) from all apps if we agreed on that properly and changed the HIG for it. It would make application development simpler.
Hopefully we agree that already-open documents should be brought to the front, possibly with a warning or question. Maybe Nautilus could catch many of those cases even if the application has no special support for it.
For the HIG link, see “Closing Operations” here, though that table-of-contents link doesn’t work. (bug filed)
http://library.gnome.org/devel/hig-book/stable/menus-standard.html.en#the-file-menu
Calum Benson found the open bug about changing the HIG to discourage use of Quit for document-base applications, though there’s been no progress since 2005:
http://bugzilla.gnome.org/show_bug.cgi?id=137227
In my opinion File->Quit should only close the window in which it is used. That is the path of least surprise for the user. Usability, you know.
If I click my terminal icon on the panel three times, it is because I do actually want 3 separate terminal windows, preferably in separate processes, so that crash in one of them would not bring the other two down.
If the application that we are calling has the document already open, it should just bring it to foreground. Possibly with a notification that the file was already opened.
Aigars, the terminal does not open documents.
Some form of standard MDI is needed; before anyone claims that it is broken, please note that everything uses tabs, which is some form of MDI.
As to the file->quit issue, it does feel vaguely like if an application did that it is guessing what to do rather than doing what it was told to do.
I find apps without File→Quit highly annoying. Of course GNOME doesn’t have the concept of an application running without windows open like OS X has, at least not without resorting to stupid notification area tricks, so it isn’t as necessary per se… but honestly, every time I for some reason open Epiphany, I end up wishing it had the Quit menu item so I could close all the windows when I’m done with it. I get vaguely uneasy when there’s no Quit item, I have to hunt through my workspaces to make sure it’s really gone. And killing unused processes is a real issue on systems with limited memory.
As to document centric apps having one window per document, as Murray said, what about viewing different parts of the document or something? How do I view two different pages with Evince? Ok, now I see it’s actually possible, there’s the “Open a Copy” (real descriptive, that) entry in the file menu. So after the program has frustrated me by popping up the same old window after I’ve double clicked on the file on my desktop for the second time, I have to look if the program authors have implemented extra functionality to circumvent the limitations they have imposed on the user.
I know there’s good reasons for the whole document centric model, but I’m just saying it’s not blindingly obvious it’s the always the right thing and there’s a need for some DWIM logic here to avoid frustrating the users. To stick to the Evince example, I think that the menu item should be called “Open another window showing this document” or something like that, and in case the user is shown the same window because they tried to open a previously opened document, it might be helpful if the window displayed a transient notification (you know, something that pops up next to a border and goes away in five secs or something) saying that if you were trying to open up a different view, use menu or click here.) And no, I’m no HCI expert.
Trying to shoehorn webpages into a document-centric model is obviously never going to work. You can’t navigate documents the way people expect webpages to work.
The problem with models like the document-centric model is that they do not fit everything people want to do with their computer. It is important that the application stick to the model so they look reasonably consistent, but not when it doesn’t make any sense or gets in the users’ way. So do provide a Quit menu item. While in reality it is useful to be able to close programs completely, in the document-centric model there isn’t. Just another instance of the model not matching reality; ignore the model.
Using multiple processes per application is not a solution for applications that crash. Applications that do not crash are the solution for applications that crash. If you can’t write applications that do not crash, either start learning or stop programming. The only reason to use multiple processes is if you need to run code that you need to trust not to crash, but that cannot be trusted not to crash. The problem with this approach should be obvious. Remember that any trusted plugin crash, just like an application crash, is a possible security compromise.
“Using multiple processes per application is not a solution for applications that crash. Applications that do not crash are the solution for applications that crash. If you can’t write applications that do not crash, either start learning or stop programming. The only reason to use multiple processes is if you need to run code that you need to trust not to crash, but that cannot be trusted not to crash. The problem with this approach should be obvious. Remember that any trusted plugin crash, just like an application crash, is a possible security compromise.”
It is not a solution but a safeguard. Applications crash – like it or not but any not-trivial program have bugs (or rather – likely have bugs). From similar (not exactly) reasons there is memory protection. In ideal world there would be no null-dereferntiation. In ideal world program would write only on it’s own memory.
But it is not an ideal world. Application crashes. There are library which has bugs. But it is better if one window crashes instead of every.
“If you can’t write applications that do not crash, either start learning or stop programming.”
AFAIU the GNOME 2.(2n+1).x programmers should start learning or stop programming? ;)
It’s not just that applications crash, so it’s nice to use the kernel’s memory protection for processes, but it’s also nice for the user (and makes life easier for the programmer) if separate document windows can use the kernel’s multitasking for processes without the unnecessary difficulty of dealing with multiple threads.
There’s probably some security advantages in there too.
I think I’m finally understanding where you want to go with this blog post murrayc, and the proposition is very interesting. Btw OS X most likely has none of this in Framework or so since all GUI applications are always single-instance.
But to create a coherent user experience with document-centric multiprocess applications, you would need some framework to make it easier for application developers. Perhaps libunique can be adapted to this, even though it’s purpose is the opposite? After all, it provides IPC.
ulrik, yes, I’m thinking of something vaguely like libunique, though I think libunique serves a different purpose.
The API would have to
– Tell me if the document is already open in this application. That would have to ping the other instance to check that it’s really really open.
– Let me bring that document to the front before exiting the new instance.
First we’d need to get agreement about what the HIG should suggest.
Juri wrote:
> get vaguely uneasy when there’s no Quit item, I have to hunt through my workspaces to make sure it’s really gone.
I think that’s just because you are used to having to do that with MacOS. Now that I think about it, I always found those orphaned applications annoying in MacOS. I never realised that was a side-effect of the top menu bar, which I otherwise remember fondly.
Just having Close (even calling it Quit) in GNOME to close the current instance is starting to make lots of sense to me.
‘it’s also nice for the user (and makes life easier for the programmer) if separate document windows can use the kernel’s multitasking for processes without the unnecessary difficulty of dealing with multiple threads.’
So to make life easier for the programmer, it’s OK if one document hangs, because the programmer didn’t use threads when he should have, but it’s not when multiple similar documents do? You could argue for such a statement because users may understand that the application looks hung up because it is doing something that the user requested, but in my opinion the only right way is for no document to hang at all.
Unfortunately not all hangs can be prevented with current programming models (such as those due to memory shortages), however putting each document in its own process doesn’t help there, because first you are using more memory than you would have if it was all in one process, and second the other process probably needs memory too, so it’ll hang too.
The only security advantage that you get from multiple processes is the possibility of OS-level sandboxing when running code that’s intended to work on data in different domains, like Google Chrome does. Realistically, just about the only use-case for that is web browsers and even then it’s just an admission of failure of the user-level sandbox. It also hardly works on common operating systems besides Windows, because you need root access to create an OS-level sandbox, the only way to make it work is through non-portable extensions like Linux’s capabilities.
‘Orphaned applications’ are not just a side-effect of the top menu bar that is still available when the application has no windows, it is also connected to the fact that the dock allows an application to have a representation even when it has no windows. So in the OSX (or NextStep) mindset, they’re not really orphaned. I agree that it would be nice to automatically close applications when they haven’t been used in a while, however according to the Apple rules it shouldn’t really matter as they shouldn’t use resources while they have no documents open.
When a document hangs, the window becomes grayed out, I click the X button and it says me that the application is not responding, so I say to end it. That’s how a user is handling an application hang (or just a longrunning non-treaded process without a progress bar). If the user kills one document, other documents need to keep working. That means that they need to be in separate processes.
> I think that?s just because you are used to having to do that with MacOS.
It might have an effect, but I don’t think it’s really it. While I share my time between OS X and GNOME these days, I have a much longer history with GNOME and pre-GNOME X desktop, and I didn’t really like the only-Close approach before starting to use Mac, either.
But I admit it might just be my personal hangup and maybe isn’t something user interface decisions should be based on :-)