After opening the "Preferences" dialog, the mouse cursor is not visible in the main area anymore, even if you move it around. It is visible when hovering other areas such as the thumbnailer or the "Preferences" dialog, though. After closing the "Preferences" dialog, everything works as usual. Strangely enough, this does not happen with other dialogs such as the "Library" dialog or the "Enhance image" dialog.
I first thought that this has something to do with the
_PreferencesDialogbeing modal (gtk.DIALOG_MODAL). However, the_EditArchiveDialogis modal as well but it does not have this issue.Besides this, I wonder why the "Preferences" dialog is modal anyway, considering that changes made in the "Preferences" will be applied immediately.
After further investigation, it seems that the
_EditArchiveDialogis actually affected as well. (Sometimes it looks as if everything's fine, though.) Also, removing thegtk.DIALOG_MODALflag seems to fix this issue. Therefore, I would like to remove this flag from both dialogs.However, the content of the
_EditArchiveDialogshould be consistent, i.e. the archive this window refers to should be the archive that is currently opened. Possible solutions that came to my mind:gtk.DIALOG_MODALflag for the_EditArchiveDialogand enable/disable the "auto hide" feature by notifying theCursorHandlerwhenever we close/open a modal dialog. This approach has similar issues as the one just mentioned but to a lesser extent.I think the last approach is the most reasonable one. I'm thinking of using a counter which starts at zero, is incremented whenever a modal dialog is opened, and is decremented whenever a modal dialog is closed. The "auto hide" feature is enabled iff the counter is equal to zero.
Does anybody know a better way to fix this or do I miss any important PyGTK features here?
I remember looking into it: I tried to find a way to know whether the main window is able to receive events or not (because a modal dialog has focus). And gave up...
Another approach could be to disable/enable cursor auto hiding on dialog open/close, like this:
Maybe factorize the code a little too...
Last edit: Benoit Pierre 2015-02-10
(Sorry, but I cannot apply the diff properly.
svn patchruns without errors but the result does not. So I'm just guessing here.)Thank you for the patch. I have thought of something similar, but as you have already mentioned, some refactoring might be a good idea. For example, the
_edit_dialog.pyfile provides similar functions likeopen_dialogand_close_dialog, just aspreferences_dialog.pydoes. Maybe they can be merged.Furthermore, I still think that we need a counter here. I see at least two major flaws in the current approach without a counter:
(By the way: There are at least two other modal dialogs, the "Library watch list" and the currently unnamed "Enter password to continue" window.)
Actually, I don't fully understand the purpose of the
dialog_handler.pybut it might be a good idea to merge the aforementionedopen_dialogand_close_dialogfunctions into it. As a result, the remaining GUI code might not need to worry about this cursor issue (or similar issues we are not currently aware of). Instead, every time we want to open or close a window, we just call the functions there, like "open the Preferences window", and thedialog_handler.pyknows exactly what to do (like disabling the autohide feature, or using the currently opened dialog instead of opening a new one, etc.).What do you think?
By the way: Is there a reason why both
BaseArchiveandUnrarDllprovide virtually identical implementations of_password_required?I can reproduce the bug with the edit archive dialog too.
Anyway, let's look at the list of all possible dialogs:
I think all dialogs linked to the current archive (archive properties, edit archive, enhance image, view comments) should be modal: to prevent an inconsistent state if switching to another archive/image while the dialog is open.
The message dialog should stay modal. I don't think there is a reason for the preferences dialog to be modal.
The bug does not happen when the dialog is not modal. So we only need to fix it for modal dialogs.
Two solutions:
I think solution 2 makes the UI more consistent.
As for how it can be implemented, I found one way do it with very minimal changes:
What do you think?
Regarding
BaseArchive/UnrarDlland the_password_requiredcallback:UnrarDllused to not derive from theBaseArchiveclass, hence the duplication. I pushed a commit to get rid of it.Awesome! This patch is really awesome! It solves the whole thing in a simple and highly sophisticated way. Well done! Please commit it. Thanks for the removal of the redundant code as well.
Concerning the modal issue in general: Thank you for the table and especially for the elaboration as it helps me thinking about this issue.
You are right when you say that the GUI should be consistent, and thus, for example, the "Enhance image" dialog should be modal. However, I think that there is an even better way, at least from a user's perspective. The issue here is: What if you want to check your "Enhance image" settings with several images? If the dialog were modal, you would be forced to close and re-open it every single time you want to switch to another image. This would be annoying.
Therefore, I think we should use four groups:
The following table shows how I think the dialogs should be classified:
Note that I have added a "save as" row in this table which is not present in the one you posted above. Also, I think that "message" covers dialogs such as "Delete image" or "Enter password" so I classified it as "write". (Please correct me if I am wrong here.) I think I have never seen the "view comments" dialog in action so "write" is merely a guess.
The "edit bookmarks" entry might be classified as "none", at least for the current version. However, I think it would be more fitting to add two buttons to this dialog instead: "Go to bookmark", which takes the user to the book and page identified by the currently selected bookmark, and "Add current page", which does the same as "Bookmark" → "Add Bookmark". The latter button would effectively turn this dialog into a "read page" dependent.
What do you think?
FYI: The "Go to bookmark" action mentioned above is actually the same as double-clicking a bookmark in the dialog.
I pushed the fix.
Regarding the dialogs: what is important is whether access to the current book/page is needed during a dialog execution (and not just during construction). Which would make it modal.
So to recap:
(1): initial access
(2): access after construction
(3): those could be improved to update on book/page change
(4): the edit commands dialog 'preview' field already gets updated automatically on book/page change
So the first step would be to switch "preferences" to non-modal.
And then look at updating the dialogs marked with (3).
Thank you for the table and for the small code cleanup. Are you currently working on these two steps?
Yes, but it might take a while... I'm wondering about cleaning up the file/image handler first:
Anyway, you can see a WIP cleanup (with a properties dialog that handle book/page changes) here: https://github.com/benoit-pierre/mcomix/tree/dialogs-rework
Thank you very much for implementing this.
Actually, this update issue reminds me of what I called a
Readerin a ticket I created a long time ago. See "Basic actions" in this post: https://sourceforge.net/p/mcomix/bugs/63/#c311 (You might want to read the whole ticket but it's both a bit long and dated.) Note that some of the things described there have been implemented already. For example, what I called aScrollback then is now implemented inscrolling.pyasScrolling.I attached a draft of a
Reader. However, it only contains stubs at most and uses the abstraction of aBookwhich does not yet exist so it is not very useful right now. However, it might illustrate the overall purpose of aReader.It's not like I am going to change everything right now only to incorporate this
Readerthing. I only want to inform you that I already thought of something like this so maybe you find some interesting ideas here and there.By the way, do you subscribe to all events for the project? Have you seen this [patches:#40] I posted?
Also, maybe a cleanup of the tracker is in order? I see a number of tickets that could be closed (I don't have rights to change a issue status, including my owns...):
And I'll stop there for now.
Personal rant:
Related
Bugs:
#35Bugs:
#49Bugs:
#53Bugs:
#62Feature Requests:
#48Feature Requests:
#5Feature Requests: #56
Feature Requests:
#83Patches:
#17Patches:
#25Patches:
#35Patches:
#40Ah, I see that you're currently doing just that: cleaning up the tracker :)
Regarding https://sourceforge.net/p/mcomix/bugs/63/#c311: I had already seen it. Unfortunately, both a rewrite, and cleaning up the current code is a lot of work... A progressive clean-up might be longer in the end, but may be the only practical approach.
Thank you for the ticket list. I was cleaning up there right when you posted this. However, I didn't fully understand all of them or couldn't decide what to do with them so I didn't close all of the ones you listed.
Yes, I think I subscribed to all relevant events, I also get a notification whenever you push any changes, and yes, I'm aware of [patches:#40]. Actually, I already sent oddegamra a message the other day but he didn't reply yet.
By the way, thank you very much for coding while I am "only" managing and testing things here. I hope it's okay for you. About your rant: I think I know what you mean and I am sorry this but there are various reasons why this isn't going to be changed any time soon.
Concerning [#63]: You are right, a progressive clean-up seems to be the only practical approach.
By the way, I am aiming for a bug fix release right now and I want this to be released in a few days or so. The reason for this are the more or less severe bugs we have found and fixed since 1.01, and at least from my perspective as a user, crashes and similar issues just spoil the whole experience. However, haste makes waste so don't change your pace. Instead, we should just try to keep things stable so we can release whenever we want, so to speak. (In other words, thank you for keeping the changes you're writing right now out of the SVN repository here. I know that this wouldn't be that much of an issue with a Git repository. I'm sorry.)
Related
Bugs:
#63Patches:
#40If you want to do a bug fix release, I found another issue with the edit archive dialog, and I have a patch that fix the problem:
I did not commit it yet because, well, the thumbnail code is pretty hairy as you know, but it seems to be working fine. Could you maybe test on your end?
Also 2 minor changes I'd like to push, regarding text contrast in some dialogs (I use a white on black GTK theme):
On the subject of a new release, do you have a Windows machine to generate a new binary version? I tried using "
setup.py dist_py2exe" with Wine while testing [patches:#40] — I wanted to see ifczipfilewas correctly included — but the resulting directory was missing all the DLLs.Related
Patches:
#40Last edit: Benoit Pierre 2015-02-14
Thank you for the patches, they are all bug fixes from my point of view. About the two "minor changes": Could you please add a constant for this
#ddbcolor inconstants.py(similar toconstants.GTK_GDK_COLOR_BLACK) and use the constants there instead? Something like this:This might prevent cluttering the code.
I went with another method: change the
borderboxto use agtk.Frame. And set the box state togtk.STATE_ACTIVE. This way we get a box that uses valid theme colors, does not clash, has usable text contrast, while still being distinctive.I just reviewed your changes. Looks good. Using
gtk.STATE_ACTIVEandgtk.SHADOW_ETCHED_INis a brilliant idea.A minor thing that I just have noticed: You get an exception if you open the Properties dialog within an empty archive. Could you please disable the menu entry in this case? (It already gets disabled if you do not open anything, not even an empty archive.)
About releasing for Windows: oddegamra might lend a helping hand here, at least that's what he told me once.
Okay, it turns out that virtually everything you can interact with is prone to exceptions if you have opened an empty archive. I'm going to create a new ticket for this issue.
Yeah, that's what I mentioned a few comments above: an archive with no images is trouble...
I see. Sorry, it had escaped my notice, I think.
Are you currently working on the "modal" issue? I think it's okay if we just fix the
gtk.DIALOG_MODALusages here even if we leave some dialogs "unreactive" (that is, they do not update their contents properly). This way, we wouldn't fix as many bugs as we have discussed here but I doubt that it is possible to do so in a few days anyway.Not actively, no.
I don't understand what you mean by:
The only easy change I can think of — but still maybe too dangerous if you want to do a bug fix release soon — is to switch the
preferencesdialog to non-modal. I just tested it, and it seems to work okay. Other modal dialogs should remain so. And then we can progressively update the non-modal dialogs to update on book/page change.Sorry, the sentence wasn't clear. I just wanted to say that, maybe, we can just turn
gtk.DIALOG_MODALon or off for all the respective windows (according to the table above), ignoring that some of the then non-modal dialogs might need an appropriate update mechanism. This way, the "modal" property of the windows would be correct but the content of the windows might be out of date.However, as you have already pointed out, this might be too dangerous.
A non-modal Preferences dialog should be okay, I think that, too. I just pushed a fix for that.
OK, so I have updated my Github branch. The interesting changes are:
I would appreciate some feedback/testing.
Something came up so I didn't (and still don't) have that much time for MComix right now. Sorry to keep you waiting.
Thank you very much for your work. Here you are, some comments and suggestions on the commits. Please overlook that I might sound a bit brusquely here and there, I just need to be brief.
a059a193b69de16a2930a31acd59601cf7bb74ad
ee678717a0942f16d089e4a0c222eb4a6c5d7b12
cafe4e8f20d95ae7c719f418be0b73e6cb168ebf
zipfileinstead? Something likemcomix --force-import=zipfilewould be nice. Same goes forsubprocess32, e.g.mcomix --force-import=zipfile,subprocess. This way, users can fall back on the "old" implementations without changing the Python environment.dede6956ddd210b010a03f4954a591a268b32ad0
318af22f35e9a7941cc2582f8ad9671388fe1b4d (and other commits)
453a3c309be59c9168019d63fd8737bad21f73bd
if-elsecode for 1 or 2 pages instead of a more generalized approach for n pages everywhere, but that's another issue.)03bf6a90f43e7071a03d647ed1128e6773e5974a
ab7b4e318f5aee714d9fb689059c56e3e855703e
AssertionErrorwhen I try to go forward/back 10 pages but there are not enough pages to do so.main.pyeven more powerful but seems to simplify the code.a222c8f0bd22faec5fb57f2a773aa26c36f852ef (and other commits)
212c3c4bfebb46345ceec5a7f184db294b2dcbca
All in all, I like it. Thanks again.