Introduse the ability to postpone a downloaded update #4263#6355
Conversation
|
I wonder, is there still desire to leave this open? I initially found this a quite interesting idea and the code was already there for the most part. cc @feerrenrut |
|
Yes, I think so. I will review it shortly. Unless it has been obsoleted by some other change? |
feerrenrut
left a comment
There was a problem hiding this comment.
Sorry it's taken a while for this to be looked at. I think I will need to go over this again, but hopefully we can start by agreeing on the UX for this change.
| message = _("NVDA version {version} is available.").format(**updateInfo) | ||
| if isPendingUpdate() and state["pendingUpdateVersion"] == updateInfo["version"]: | ||
| # Translators: A message indicating that an updated version of NVDA is already pending to be installed. | ||
| message = _("The latest update is already pending to be installed.") |
There was a problem hiding this comment.
I think the wording of this could be better, first I want to double check I understand correctly that this message will be shown after NVDA has confirmed that the pending installation is in fact the latest available update? If so, I think the # Translators: comment could be clearer also, perhaps A message indicating that the latest version of NVDA has been downloaded and is waiting to be installed
Since we specify the version when we specify that the availability of the update, I think we should do this here also, so perhaps something like NVDA version {version} is pending installation or NVDA version {version} is ready to be installed
| message=_("You can install it now, or install it later from the NVDA menu or the exit dialog, if enabled.\n") | ||
| mainSizer.Add(wx.StaticText(self, label= | ||
| # Translators: A message indicating that an updated version of NVDA is ready to be installed. | ||
| _("Update is ready to install.\n")+message+ |
There was a problem hiding this comment.
This building up of messages has a risk that it won't make sense once translated. I also think these labels could be simplified. I think it is adequate to simply set the label as "Update is ready to install" and rely on the presence of the buttons to indicate what options are available.
| except: | ||
| gui.messageBox( | ||
| # Translators: The message when a downloaded update file could not be preserved. | ||
| _("The downloaded file could not be postponed properly."), |
There was a problem hiding this comment.
I would word this "Unable to postpone update"
| gui.messageBox( | ||
| # Translators: The message when a downloaded update file could not be preserved. | ||
| _("The downloaded file could not be postponed properly."), | ||
| _("Error"), wx.OK | wx.ICON_ERROR) |
There was a problem hiding this comment.
This is missing a translator comment. I think there is an automated test that would catch this, you can run this with scons checkPot
|
It seems that when I reviewed this code earlier and made it ready for a pr, I missed some major things that really need to be fixed before this even works. The major downside with this code is that it is very difficult to test, at least when running from source. @feerrenrut, I've addressed your review comments although not yet pushed. However, let me do some additional testing before I ask you to come back to this again. |
|
I've been able to test this to some extend, however as pointed out, it requires some ugly hacking as NVDA only allows itself to be updated in official snapshot or release cases. I'd also like to incorporate support for portable copy updating while at it. |
|
Ok, please request a review again when you are ready for me to take another look at it. |
| try: | ||
| self.sysTrayIcon.menu.RemoveItem(self.sysTrayIcon.runPendingUpdateMenuItem) | ||
| except: | ||
| pass |
There was a problem hiding this comment.
I think it's worth logging something here at debug level.
| except: | ||
| pass | ||
| if updateCheck and updateCheck.isPendingUpdate(): | ||
| self.sysTrayIcon.menu.InsertItem(self.sysTrayIcon.menu.GetMenuItemCount()-2,self.sysTrayIcon.runPendingUpdateMenuItem) |
There was a problem hiding this comment.
What's with the -2. Is this the position. Might be clearer to put this in a pendingUpdateMenuItemPosition variable. Is it important for it to be second from the bottom? I am concerned that because this positioning is separated from the rest of that menu filing that the order might change, and this code wont be considered. The index of the position for this item could be saved at the point where the rest of the menu is populated.
| if not os.path.isdir(curDestDir): | ||
| os.makedirs(curDestDir) | ||
| for f in files: | ||
| if f.endswith(".exe"): |
There was a problem hiding this comment.
perhaps a comment to say why exe files should be skipped?
| state["removeFile"] = destPath | ||
| saveState() | ||
| if config.isInstalledCopy(): | ||
| exeCuteParams = u"--install -m" |
There was a problem hiding this comment.
this looks like a bug, here exeCuteParams has a capital C, and where it is passed to ShellExecute it does not.
| saveState() | ||
| self.Close() | ||
|
|
||
| class UpdateAskInstallDialog(wx.Dialog): |
There was a problem hiding this comment.
I have a feeling that this dialog wont have the visual spacing expected between labels and buttons. What is the easiest way to test this, so I can inspect it?
There was a problem hiding this comment.
I added some guiHelper stuff to it now. Here is a code snippet to make it show up:
import versionInfo, gui
versionInfo.updateVersionType="snapshot:next"
import updateCheck
updateCheck.initialize()
updateCheck.UpdateAskInstallDialog(gui.mainFrame, "dummy_path", "2018.3")
There was a problem hiding this comment.
Thanks for the snippet. It looks ok to me.
| wx.OK | wx.ICON_ERROR) | ||
|
|
||
| def _downloadSuccess(self): | ||
| # global storeUpdatesDir |
There was a problem hiding this comment.
Looks like this can be removed?
| wx.OK | wx.ICON_ERROR) | ||
|
|
||
| def _downloadSuccess(self): | ||
| # global storeUpdatesDir |
There was a problem hiding this comment.
Should this be uncommented / removed?
There was a problem hiding this comment.
This has already been removed. Probably legacy code from the initial author, but storeUpdatesDir doesn't have to be changed inside this function.
There was a problem hiding this comment.
Oh sorry I must have misread this line.
| ] | ||
| if updateCheck and updateCheck.isPendingUpdate(): | ||
| # Translators: An option in the combo box to choose exit action. | ||
| self.actions.append(_("Run pending update")) |
There was a problem hiding this comment.
Elsewhere we say "Install update" rather than "run update", I think "Install pending update" would be more consistent.
| sHelper = guiHelper.BoxSizerHelper(self, orientation=wx.VERTICAL) | ||
|
|
||
| # Translators: A message indicating that an updated version of NVDA is ready to be installed. | ||
| sHelper.addItem(wx.StaticText(self, label=_("Update is ready to install.\n"))) |
There was a problem hiding this comment.
Do you think this dialog should tell you the updates version information? To be consistent with the other download update dialog?
| ==== Show exit options when exiting NVDA ====[GeneralSettingsShowExitOptions] | ||
| This option is a checkbox that allows you to choose whether or not a dialog appears when you exit NVDA that asks what action you want to perform. | ||
| When checked, a dialog will appear when you attempt to exit NVDA asking whether you want to exit, restart or restart with add-ons disabled. | ||
| When checked, a dialog will appear when you attempt to exit NVDA asking whether you want to exit, restart, restart with addons disabled or Run pending updates (if any). |
There was a problem hiding this comment.
There are a few places here that still refer to "run pending updates"
|
|
||
| ==== Notify for pending updates on startup ====[GeneralSettingsNotifyPendingUpdates] | ||
| If this is enabled, NVDA will inform you when there is a pending update on startup, offering you the possibility to install it. | ||
| You can also manually run the pending update from the Exit NVDA dialog (if enabled), from the NVDA menu, or when you perform a new check from the Hel pmenu. |
There was a problem hiding this comment.
also refers to "run the pending update"
There is also a typo, a space needs to move one character over in Hel pmenu
|
Note that with my most recent change, the behavior of the "Notify for pending update on startup" option has changed a little. As this functionality now resides in the AutoUpdateChecker, a pending update will be ignored if there is a version available that is newer than the pending update. I think this behavior is desirable, it does not make sense to install a pending update and notice afterwards that it wasn't the most recent update available. As a side effect, the pending update notification won't show up if the update check fails due to no internet connection available. People will still be able to install the postponed update from the menu or using the exit dialog, though. |
|
The latest next installed as portable OK this time, though the dialogue did
not gain focus on its own, I had to alt tab to it.
Not tried defer update yet.
Brian
|
| mainSizer.Fit(self) | ||
| self.Center(wx.BOTH | wx.CENTER_ON_SCREEN) | ||
| self.Show() | ||
| gui.mainFrame.prePopup() |
There was a problem hiding this comment.
If you call this, I think you also need to call postPopup().
There was a problem hiding this comment.
Yes, you'd think so. The use of prePopup and postPopup inside updateCheck really puzzles me.
- prePopup is only used in the UpdateDownloader, not for the other dialogs. It was called for the old update installation message box, so that's why I belief it should be called in the UpdateAskInstallDialog as well.
- postPopup is even more confusing given it is being called in a wx.CallLater with a not very descriptive comment. A git blame points at @jcsteh, so may be he knows more?
- In several places in the gui module, you see the following code:
mainFrame.prePopup()
dialog.Show()
mainFrame.postPopup()
However, this doesn't seem to make much sense, as Show doesn't block the caller. For ShowModal, it does make sense as ShowModal blocks the caller until the dialog is dismissed.
There was a problem hiding this comment.
Perhaps its better to use def runScriptModalDialog in source/gui/__init__
There was a problem hiding this comment.
TL;DR: The general rule is that if you're popping up a window (as opposed to a window which appears as a result of some action performed while our GUI was already visible), you must call prePopup. If you call prePopup, there must be a corresponding call to postPopup. Ideally, this postPopup call would occur once the window is dismissed, but for windows that aren't modal, it's enough in most cases to just call it after Show.
prePopup and postPopup have two major functions:
- To force Windows to bring us to the foreground (
prePopup) and to return to the previous foreground (postPopup). The way foreground stuff works in Windows is really obscure.prePopupmostly makes sense; we ask Windows to bring us to the foreground. However, we were seeing cases where the user would just be stuck in limbo when our pop-ups were dismissed. I still don't really understand why this is the case, but the show/hide inpostPopupseemed to fix it. (Obviously, that doesn't actually get applied at the right tie for dialogs that aren't modal, but it seems to behave regardless.) This code is very old, wx has been updated and Windows XP is no longer a factor, so you could consider re-assessing to see whether we can get rid of this ugliness. However, note that installed versus portable is still a factor, since uiAccess gives the app special privileges regarding the foreground window. - These methods also set things up so that NVDA is aware of what the focus was before the pop-up. This is important for input gestures, for example, so it knows which object to get gestures for.
postPopupdoes the necessary teardown of this state. The fact that it gets called immediately afterShowis fine in this case because the dialog should already have done what it needs to do with this state.
|
The prePopup should fix the issue reported by Brian about this dialog not getting properly focused. I'm still not very sure about when to use prePopup and postPopup.
… Op 9 feb. 2018 om 07:35 heeft Reef Turner ***@***.***> het volgende geschreven:
@feerrenrut commented on this pull request.
In source/updateCheck.py:
> @@ -352,7 +354,8 @@ def __init__(self, parent, destPath, version):
self.Sizer = mainSizer
mainSizer.Fit(self)
self.Center(wx.BOTH | wx.CENTER_ON_SCREEN)
- self.Show()
+ gui.mainFrame.prePopup()
what's this about?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
|
@feerrenrut: IN 20407fb I started to use scriptRunModalDialog |
|
Ok, looks good. I will incubate this again. |
…t do this, a user will never be reminded about a postponed update automatically at all
|
@feerrenrut: Three cheers for broken code. Just tried to fix another small bug, namely that postponing an update does not clear the don't remind version. This means that the don't remind version and the pending version are equal, in which case the AutoUpdateChecker would never pop up a reminder. |
|
just ran the portable version of next and had to prompt it to tell me a new
version was ready, but once downloaded, this time it did show me the install
and postpone box automatically which did not happen before.
Brian
|
|
@feerrenrut: Could you please review 4a4f7c4? |
feerrenrut
left a comment
There was a problem hiding this comment.
The latest commit makes sense. I think it would be handy to have a manual test plan for this feature. Outline all the possible paths that one can take, and what is expected to happen. It might help to highlight some case that has not yet been explored.
Closes #4263
closes #6281
closes #4020
First of all, many thanks to @zahyur who actually did the major work for this.
This pull request introduces the possibility to postpone a downloaded update. Comment and discussion in #4263 has been processed in this request. Also, I decided to make installing postponed updates from the menu possible regardless of showing the exit dialog has been disabled.
This code still needs testing in real live, which is quite hard from source, without real updatable builds.
Changelog entry