Changeset 2023

Show
Ignore:
Timestamp:
05/07/08 09:04:04 (8 months ago)
Author:
jteh
Message:

Merging guiFixes branch.
This fixes #65 (Freeze when launching NVDA dialogs).
I'm also hoping it will fix #41 (NVDA menu sometimes does not correctly obtain focus), but I can't reproduce this issue on my system, so I can't test it.

In addition, this fixes the issue wherein the tray menu would not appear when the right mouse button was clicked on the tray icon.

Aside from this, there is quite a bit of code cleanup and simplification.

Location:
trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk

    • Property bzr:revision-id:v3-list-QlpoOTFBWSZTWbrL2vUAAB1VgAAQABCAQDrrnqAgAFCgaaGRkxBoTIJ6mmaNRwhndFAoNhZjh_YY4a01fOg1ulgNNC2UrzPdXXEnDpX8XckU4UJC6y9r1A..
      •  

        old new  
        87871813 jamie@jantrid.net-20080502122842-u2xfo1in3euux4ci 
        88881825 jamie@jantrid.net-20080506061049-3qk3r33c6a8dc4jo 
         891828 jamie@jantrid.net-20080507090220-y1fjk3t08rbcx18z 
    • Property bzr:revision-info
      •  

        old new  
        1 timestamp: 2008-05-06 16:10:49.217000008 +1000 
         1timestamp: 2008-05-07 19:02:20.607000113 +1000 
        22committer: James Teh <jamie@jantrid.net> 
        33properties:  
    • Property bzr:ancestry:v3-list-QlpoOTFBWSZTWbrL2vUAAB1VgAAQABCAQDrrnqAgAFCgaaGRkxBoTIJ6mmaNRwhndFAoNhZjh_YY4a01fOg1ulgNNC2UrzPdXXEnDpX8XckU4UJC6y9r1A..
      •  

        old new  
        33jamie@jantrid.net-20080212104116-78n366kl7diwve24 
        44jamie@jantrid.net-20080229050825-20q1xhb2t4c0zcza 
         5jamie@jantrid.net-20080507074841-cxoldzwvz389fete 
  • trunk/source/gui/__init__.py

    r1958 r2023  
    2020import languageHandler 
    2121import logViewer 
     22import winUser 
    2223 
    2324### Constants 
     
    2930id_showGuiCommand=wx.NewId() 
    3031id_abortCommand=wx.NewId() 
    31 evt_externalExecute = wx.NewEventType() 
     32evtid_externalExecute = wx.NewEventType() 
     33evt_externalExecute = wx.PyEventBinder(evtid_externalExecute, 1) 
    3234 
    3335### Globals 
    3436mainFrame = None 
    3537#: A list of top level windows excluding L{mainFrame} which are currently instantiated and which should be destroyed on exit. 
    36 #: @type: list 
    37 topLevelWindows = [] 
    3838 
    3939class ExternalExecuteEvent(wx.PyCommandEvent): 
    4040        def __init__(self, func, args, kwargs, callback): 
    41                 super(ExternalExecuteEvent, self).__init__(evt_externalExecute, wx.ID_ANY) 
     41                super(ExternalExecuteEvent, self).__init__(evtid_externalExecute, wx.ID_ANY) 
    4242                self._func = func 
    4343                self._args = args 
     
    9797        def __init__(self): 
    9898                style = wx.DEFAULT_FRAME_STYLE ^ wx.MAXIMIZE_BOX ^ wx.MINIMIZE_BOX | wx.FRAME_NO_TASKBAR 
    99                 super(MainFrame, self).__init__(None, wx.ID_ANY, appTitle, size=(500,500), style=style) 
     99                super(MainFrame, self).__init__(None, wx.ID_ANY, appTitle, size=(1,1), style=style) 
    100100                self.Bind(evt_externalCommand, self.onAbortCommand, id=id_abortCommand) 
    101101                self.Bind(evt_externalCommand, self.onExitCommand, id=wx.ID_EXIT) 
    102102                self.Bind(evt_externalCommand, self.onShowGuiCommand, id=id_showGuiCommand) 
    103                 wx.EVT_COMMAND(self,wx.ID_ANY,evt_externalExecute,lambda evt: evt.run()) 
     103                self.Bind(evt_externalExecute,lambda evt: evt.run()) 
    104104                self.sysTrayIcon = SysTrayIcon(self) 
    105                 self.Show(True) 
    106                 self.Show(False) 
     105                # This makes Windows return to the previous foreground window and also seems to allow NVDA to be brought to the foreground. 
     106                self.Show() 
     107                self.Hide() 
    107108 
    108109        def Destroy(self): 
    109                 global topLevelWindows 
    110110                self.sysTrayIcon.Destroy() 
    111                 for window in list(topLevelWindows): 
    112                         window.Destroy() 
    113111                super(MainFrame, self).Destroy() 
     112 
     113        def prePopup(self): 
     114                """Prepare for a popup. 
     115                This should be called before any dialog or menu which should pop up for the user. 
     116                L{postPopup} should be called after the dialog or menu has been shown. 
     117                @postcondition: A dialog or menu may be shown. 
     118                """ 
     119                if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != os.getpid(): 
     120                        # This process is not the foreground process, so bring it to the foreground. 
     121                        self.Raise() 
     122 
     123        def postPopup(self): 
     124                """Clean up after a popup dialog or menu. 
     125                This should be called after a dialog or menu was popped up for the user. 
     126                """ 
     127                if not winUser.isWindowVisible(winUser.getForegroundWindow()): 
     128                        # The current foreground window is invisible, so we want to return to the previous foreground window. 
     129                        # Showing and hiding our main window seems to achieve this. 
     130                        self.Show() 
     131                        self.Hide() 
    114132 
    115133        def onAbortCommand(self,evt): 
     
    129147                        speech.speakMessage(_("Could not save configuration - probably read only file system"),wait=True) 
    130148 
     149        def _popupSettingsDialog(self, dialog, *args, **kwargs): 
     150                self.prePopup() 
     151                dialog(self, *args, **kwargs).Show() 
     152                self.postPopup() 
     153 
    131154        def onDefaultDictionaryCommand(self,evt): 
    132                 d=DictionaryDialog(None,_("Default dictionary"),speechDictHandler.dictionaries["default"]) 
    133                 d.Show(True) 
     155                self._popupSettingsDialog(DictionaryDialog,_("Default dictionary"),speechDictHandler.dictionaries["default"]) 
    134156 
    135157        def onVoiceDictionaryCommand(self,evt): 
    136                 d=DictionaryDialog(None,_("Voice dictionary (%s)")%speechDictHandler.dictionaries["voice"].fileName,speechDictHandler.dictionaries["voice"]) 
    137                 d.Show(True) 
     158                self._popupSettingsDialog(DictionaryDialog,_("Voice dictionary (%s)")%speechDictHandler.dictionaries["voice"].fileName,speechDictHandler.dictionaries["voice"]) 
    138159 
    139160        def onTemporaryDictionaryCommand(self,evt): 
    140                 d=DictionaryDialog(None,_("Temporary dictionary"),speechDictHandler.dictionaries["temp"]) 
    141                 d.Show(True) 
     161                self._popupSettingsDialog(DictionaryDialog,_("Temporary dictionary"),speechDictHandler.dictionaries["temp"]) 
    142162 
    143163        def onExitCommand(self, evt): 
    144164                canExit=False 
    145165                if config.conf["general"]["askToExit"]: 
    146                         d = wx.MessageDialog(None, _("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES|wx.NO|wx.ICON_WARNING) 
     166                        self.prePopup() 
     167                        d = wx.MessageDialog(self, _("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES|wx.NO|wx.ICON_WARNING) 
    147168                        if d.ShowModal() == wx.ID_YES: 
    148169                                canExit=True 
     170                        self.postPopup() 
    149171                else: 
    150172                        canExit=True 
     
    158180 
    159181        def onGeneralSettingsCommand(self,evt): 
    160                 d=GeneralSettingsDialog(None) 
    161                 d.Show(True) 
     182                self._popupSettingsDialog(GeneralSettingsDialog) 
    162183 
    163184        def onSynthesizerCommand(self,evt): 
    164                 d=SynthesizerDialog(None) 
    165                 d.Show(True) 
     185                self._popupSettingsDialog(SynthesizerDialog) 
    166186 
    167187        def onVoiceCommand(self,evt): 
    168                 d=VoiceSettingsDialog(None) 
    169                 d.Show(True) 
     188                self._popupSettingsDialog(VoiceSettingsDialog) 
    170189 
    171190        def onKeyboardSettingsCommand(self,evt): 
    172                 d=KeyboardSettingsDialog(None) 
    173                 d.Show(True) 
     191                self._popupSettingsDialog(KeyboardSettingsDialog) 
    174192 
    175193        def onMouseSettingsCommand(self,evt): 
    176                 d=MouseSettingsDialog(None) 
    177                 d.Show(True) 
     194                self._popupSettingsDialog(MouseSettingsDialog) 
    178195 
    179196        def onObjectPresentationCommand(self,evt): 
    180                 d=ObjectPresentationDialog(None) 
    181                 d.Show(True) 
     197                self._popupSettingsDialog(ObjectPresentationDialog) 
    182198 
    183199        def onVirtualBuffersCommand(self,evt): 
    184                 d=VirtualBuffersDialog(None) 
    185                 d.Show(True) 
     200                self._popupSettingsDialog(VirtualBuffersDialog) 
    186201 
    187202        def onDocumentFormattingCommand(self,evt): 
    188                 d=DocumentFormattingDialog(None) 
    189                 d.Show(True) 
     203                self._popupSettingsDialog(DocumentFormattingDialog) 
    190204 
    191205        def onAboutCommand(self,evt): 
     
    195209%s: %s 
    196210%s: %s"""%(versionInfo.longName,_("version"),versionInfo.version,_("url"),versionInfo.url,_("copyright"),versionInfo.copyrightInfo) 
    197                         d = wx.MessageDialog(None, aboutInfo, _("About NVDA"), wx.OK) 
     211                        self.prePopup() 
     212                        d = wx.MessageDialog(self, aboutInfo, _("About NVDA"), wx.OK) 
    198213                        d.ShowModal() 
     214                        self.postPopup() 
    199215                except: 
    200216                        globalVars.log.error("gui.mainFrame.onAbout", exc_info=True) 
    201217 
    202218        def onViewLogCommand(self, evt): 
    203                 logViewer.LogViewer().Show() 
     219                logViewer.activate() 
    204220 
    205221        def onPythonConsoleCommand(self, evt): 
     
    280296                self.Bind(wx.EVT_MENU, frame.onExitCommand, item) 
    281297 
    282                 self.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.onActivate) 
     298                self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.onActivate) 
    283299 
    284300        def Destroy(self): 
     
    287303 
    288304        def onActivate(self, evt): 
     305                mainFrame.prePopup() 
    289306                self.PopupMenu(self.menu) 
    290                 # Showing and hiding our main frame seems to cause Windows to switch to the previous foreground window. 
    291                 # If we don't do this and no dialog was displayed, the user will be dumped in the invisible system tray window, which is bad. 
    292                 # It is even worse than expected because the user can close the system tray window, breaking the system tray icon. 
    293                 # Even if a dialog is displayed, this does no harm. 
    294                 mainFrame.Show() 
    295                 mainFrame.Hide() 
     307                mainFrame.postPopup() 
    296308 
    297309def initialize(app): 
  • trunk/source/gui/logViewer.py

    r1962 r2023  
    77import gui 
    88 
     9#: The singleton instance of the log viewer UI. 
     10logViewer = None 
     11 
    912class LogViewer(wx.Frame): 
    1013        """The NVDA log viewer GUI. 
    1114        """ 
    1215 
    13         def __init__(self): 
    14                 super(LogViewer, self).__init__(None, wx.ID_ANY, _("NVDA Log Viewer")) 
    15                 gui.topLevelWindows.append(self) 
     16        def __init__(self, parent): 
     17                super(LogViewer, self).__init__(parent, wx.ID_ANY, _("NVDA Log Viewer")) 
    1618                self.Bind(wx.EVT_ACTIVATE, self.onActivate) 
    1719                self.Bind(wx.EVT_CLOSE, self.onClose) 
     
    4749 
    4850        def onActivate(self, evt): 
    49                 self.refresh() 
     51                if evt.GetActive(): 
     52                        self.refresh() 
    5053                evt.Skip() 
    5154 
     
    6467                        wx.MessageBox(_("Error saving log: %s") % e.strerror, _("Error"), style=wx.OK | wx.ICON_ERROR) 
    6568 
    66         def Destroy(self): 
    67                 gui.topLevelWindows.remove(self) 
    68                 super(LogViewer, self).Destroy() 
     69def activate(): 
     70        """Activate the log viewer. 
     71        If the log viewer has not already been created and opened, this will create and open it. 
     72        Otherwise, it will be brought to the foreground if possible. 
     73        """ 
     74        global logViewer 
     75        if not logViewer: 
     76                logViewer = LogViewer(gui.mainFrame) 
     77        logViewer.Raise() 
     78        logViewer.Show() 
  • trunk/source/gui/scriptUI.py

    r1935 r2023  
    3636 
    3737        def _run_gui(self): 
     38                gui.mainFrame.prePopup() 
    3839                dialog = self.dialog = self.makeDialog() 
    39                 dialog.Raise() 
    4040                ret = self.getResponse(dialog.ShowModal()) 
     41                gui.mainFrame.postPopup() 
    4142                dialog.Destroy() 
    4243                return ret 
     
    5152 
    5253        def __init__(self, message, title = _("NVDA"), style=wx.OK, callback=None): 
    53                 self.makeDialog = lambda: wx.MessageDialog(None, message, title, style) 
     54                self.makeDialog = lambda: wx.MessageDialog(gui.mainFrame, message, title, style) 
    5455                super(MessageDialog, self).__init__(callback) 
    5556 
     
    6061 
    6162        def __init__(self, message, title=_("NVDA"), default="", style=wx.OK | wx.CANCEL, callback=None): 
    62                 self.makeDialog = lambda: wx.TextEntryDialog(None, message, title, defaultValue=default, style=style) 
     63                self.makeDialog = lambda: wx.TextEntryDialog(gui.mainFrame, message, title, defaultValue=default, style=style) 
    6364                super(TextEntryDialog, self).__init__(callback) 
    6465 
     
    7374        def __init__(self, message, title=_("NVDA"), choices=(), default=0, style=wx.OK|wx.CANCEL, callback=None): 
    7475                def makeDialog(): 
    75                         dialog = wx.Dialog(None, wx.ID_ANY, title) 
     76                        dialog = wx.Dialog(gui.mainFrame, wx.ID_ANY, title) 
    7677                        mainSizer = wx.BoxSizer(wx.VERTICAL) 
    7778                        mainSizer.Add(wx.StaticText(dialogD_ANY, label=message)) 
     
    106107        def __init__(self, choices, default=0, callback=None): 
    107108                def makeDialog(): 
    108                         dialog = wx.Dialog(None, wx.ID_ANY, _("Links List")) 
     109                        dialog = wx.Dialog(gui.mainFrame, wx.ID_ANY, _("Links List")) 
    109110                        mainSizer = wx.BoxSizer(wx.VERTICAL) 
    110111                        self.list = wx.ListView(dialog, wx.ID_ANY, style=wx.LC_LIST | wx.LC_SINGLE_SEL) 
  • trunk/source/pythonConsole.py

    r1958 r2023  
    5858        """ 
    5959 
    60         def __init__(self): 
    61                 super(ConsoleUI, self).__init__(None, wx.ID_ANY, _("NVDA Python Console")) 
     60        def __init__(self, parent): 
     61                super(ConsoleUI, self).__init__(parent, wx.ID_ANY, _("NVDA Python Console")) 
    6262                self.Bind(wx.EVT_ACTIVATE, self.onActivate) 
    6363                self.Bind(wx.EVT_CLOSE, self.onClose) 
     
    160160        """ 
    161161        global consoleUI 
    162         consoleUI = ConsoleUI() 
    163         gui.topLevelWindows.append(consoleUI) 
     162        consoleUI = ConsoleUI(gui.mainFrame) 
    164163 
    165164def activate():