You can subscribe to this list here.
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(357) |
Jul
(585) |
Aug
(677) |
Sep
(480) |
Oct
(476) |
Nov
(533) |
Dec
(368) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2014 |
Jan
(542) |
Feb
(591) |
Mar
(392) |
Apr
(512) |
May
(442) |
Jun
(583) |
Jul
(799) |
Aug
(619) |
Sep
(674) |
Oct
(620) |
Nov
(468) |
Dec
(848) |
2015 |
Jan
(877) |
Feb
(568) |
Mar
(366) |
Apr
(538) |
May
(349) |
Jun
(478) |
Jul
(444) |
Aug
(399) |
Sep
(424) |
Oct
(413) |
Nov
(227) |
Dec
(101) |
2016 |
Jan
(73) |
Feb
(39) |
Mar
(60) |
Apr
(47) |
May
(58) |
Jun
(54) |
Jul
(148) |
Aug
(122) |
Sep
(67) |
Oct
(60) |
Nov
(31) |
Dec
(36) |
2017 |
Jan
(76) |
Feb
(37) |
Mar
(50) |
Apr
(42) |
May
(68) |
Jun
(58) |
Jul
(72) |
Aug
(106) |
Sep
(48) |
Oct
(79) |
Nov
(57) |
Dec
(59) |
2018 |
Jan
(50) |
Feb
(41) |
Mar
(73) |
Apr
(62) |
May
(66) |
Jun
(97) |
Jul
(47) |
Aug
(33) |
Sep
(49) |
Oct
(19) |
Nov
(40) |
Dec
(40) |
2019 |
Jan
(39) |
Feb
(29) |
Mar
(34) |
Apr
(41) |
May
(75) |
Jun
(55) |
Jul
(44) |
Aug
(39) |
Sep
(103) |
Oct
(65) |
Nov
(72) |
Dec
(41) |
2020 |
Jan
(40) |
Feb
(44) |
Mar
(49) |
Apr
(57) |
May
(34) |
Jun
(58) |
Jul
(72) |
Aug
(24) |
Sep
(61) |
Oct
(36) |
Nov
(36) |
Dec
(31) |
2021 |
Jan
(35) |
Feb
(17) |
Mar
(50) |
Apr
(47) |
May
(71) |
Jun
(41) |
Jul
(66) |
Aug
(32) |
Sep
(44) |
Oct
(57) |
Nov
(32) |
Dec
(27) |
2022 |
Jan
(26) |
Feb
(46) |
Mar
(74) |
Apr
(32) |
May
(32) |
Jun
(48) |
Jul
(50) |
Aug
(69) |
Sep
(52) |
Oct
(61) |
Nov
(38) |
Dec
(36) |
2023 |
Jan
(45) |
Feb
(42) |
Mar
(49) |
Apr
(35) |
May
(11) |
Jun
(56) |
Jul
(60) |
Aug
(52) |
Sep
(109) |
Oct
(83) |
Nov
(55) |
Dec
(59) |
2024 |
Jan
(71) |
Feb
(66) |
Mar
(50) |
Apr
(35) |
May
(86) |
Jun
(55) |
Jul
(81) |
Aug
(13) |
Sep
|
Oct
|
Nov
|
Dec
|
The branch t3825 has been updated From 99d5c9a to cd3bc57 New revisions: - Log ----------------------------------------------------------------- commit cd3bc578f4e8d20be9a93aef75c82c2bfc362b03 Author: James Teh <ja...@nv...> Date: Tue Feb 4 12:58:20 2014 +1000 cancellableSendMessageTimeout: Rather than continually cancelling individual calls with an auto reset event, just set it once when cancellation starts and reset it when the core is alive. Previously, it was possible that the first message after the core recovered would be cancelled if there wasn't a message after the last recovery attempt. Also, this way, we don't bother to send any messages at all once cancellation begins, which is more efficient. commit 7c383bf320b9ee11874fc3a4f967f7a39d869a91 Merge: 99d5c9a a59e007 Author: James Teh <ja...@nv...> Date: Tue Feb 4 14:41:40 2014 +1000 Merge branch 't3801' into t3825 ----------------------------------------------------------------------- Summary of changes: nvdaHelper/local/nvdaHelperLocal.cpp | 14 ++--- nvdaHelper/local/nvdaHelperLocal.def | 2 +- nvdaHelper/local/nvdaHelperLocal.h | 1 - source/IAccessibleHandler.py | 25 ++++---- source/JABHandler.py | 2 + source/core.py | 61 +++++++++++++++++--- source/mouseHandler.py | 2 + source/pythonConsole.py | 4 ++ source/queueHandler.py | 5 ++ source/touchHandler.py | 33 ++++++----- source/touchTracker.py | 7 ++- source/watchdog.py | 105 ++++++++++++++++++++-------------- 12 files changed, 173 insertions(+), 88 deletions(-) diff --git a/nvdaHelper/local/nvdaHelperLocal.cpp b/nvdaHelper/local/nvdaHelperLocal.cpp index fba2d56..382ddb7 100644 --- a/nvdaHelper/local/nvdaHelperLocal.cpp +++ b/nvdaHelper/local/nvdaHelperLocal.cpp @@ -75,7 +75,7 @@ handle_t createRemoteBindingHandle(wchar_t* uuidString) { const UINT CANCELSENDMESSAGE_CHECK_INTERVAL = 1000; DWORD mainThreadId = 0; -HANDLE cancelSendMessageEvent = NULL; +HANDLE cancelCallEvent = NULL; void(__stdcall *_notifySendMessageCancelled)() = NULL; struct BgSendMessageData { HANDLE completeEvent; @@ -148,7 +148,7 @@ LRESULT cancellableSendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM return 0; } - if (WaitForSingleObject(cancelSendMessageEvent, 0) == WAIT_OBJECT_0) { + if (WaitForSingleObject(cancelCallEvent, 0) == WAIT_OBJECT_0) { // Already cancelled, so don't bother going any further. SetLastError(ERROR_CANCELLED); return 0; @@ -206,7 +206,7 @@ LRESULT cancellableSendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM SetEvent(bgSendMessageData->execEvent); } - HANDLE waitHandles[] = {bgSendMessageData->completeEvent, cancelSendMessageEvent}; + HANDLE waitHandles[] = {bgSendMessageData->completeEvent, cancelCallEvent}; DWORD waitIndex = 0; if (fuFlags & SMTO_BLOCK) { waitIndex = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE); @@ -239,10 +239,6 @@ LRESULT cancellableSendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM return 1; } -void cancelSendMessage() { - SetEvent(cancelSendMessageEvent); -} - LRESULT WINAPI fake_SendMessageW(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) { DWORD_PTR result = 0; cancellableSendMessageTimeout(hwnd, Msg, wParam, lParam, 0, 60000, &result); @@ -256,7 +252,7 @@ LRESULT WINAPI fake_SendMessageTimeoutW(HWND hwnd, UINT Msg, WPARAM wParam, LPAR void nvdaHelperLocal_initialize() { startServer(); mainThreadId = GetCurrentThreadId(); - cancelSendMessageEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + cancelCallEvent = CreateEvent(NULL, TRUE, FALSE, NULL); HMODULE oleacc = LoadLibraryA("oleacc.dll"); if (!oleacc) return; @@ -292,7 +288,7 @@ void nvdaHelperLocal_terminate() { bgSendMessageData->hwnd = NULL; SetEvent(bgSendMessageData->execEvent); } - CloseHandle(cancelSendMessageEvent); + CloseHandle(cancelCallEvent); stopServer(); } diff --git a/nvdaHelper/local/nvdaHelperLocal.def b/nvdaHelper/local/nvdaHelperLocal.def index d6f99a1..9c67f3a 100644 --- a/nvdaHelper/local/nvdaHelperLocal.def +++ b/nvdaHelper/local/nvdaHelperLocal.def @@ -1,7 +1,7 @@ EXPORTS createRemoteBindingHandle cancellableSendMessageTimeout - cancelSendMessage + cancelCallEvent _notifySendMessageCancelled nvdaHelperLocal_initialize nvdaHelperLocal_terminate diff --git a/nvdaHelper/local/nvdaHelperLocal.h b/nvdaHelper/local/nvdaHelperLocal.h index a9ee2fc..175135b 100755 --- a/nvdaHelper/local/nvdaHelperLocal.h +++ b/nvdaHelper/local/nvdaHelperLocal.h @@ -18,7 +18,6 @@ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html handle_t createRemoteBindingHandle(wchar_t* uuidString); LRESULT cancellableSendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult); -void cancelSendMessage(); void nvdaHelperLocal_initialize(); void nvdaHelperLocal_terminate(); diff --git a/source/IAccessibleHandler.py b/source/IAccessibleHandler.py index 200be58..21b391d 100644 --- a/source/IAccessibleHandler.py +++ b/source/IAccessibleHandler.py @@ -28,6 +28,7 @@ import appModuleHandler import mouseHandler import controlTypes import keyboardHandler +import core MAX_WINEVENTS=500 MAX_WINEVENTS_PER_THREAD=10 @@ -75,16 +76,18 @@ class OrderedWinEventLimiter(object): @type childID: integer @param threadID: the threadID of the winEvent @type threadID: integer + @return: C{True} if the event was added, C{False} if it was discarded. + @rtype: bool """ if eventID==winUser.EVENT_OBJECT_FOCUS: if objectID in (winUser.OBJID_SYSMENU,winUser.OBJID_MENU) and childID==0: # This is a focus event on a menu bar itself, which is just silly. Ignore it. - return + return False #We do not need a focus event on an object if we already got a foreground event for it if (winUser.EVENT_SYSTEM_FOREGROUND,window,objectID,childID,threadID) in self._focusEventCache: - return + return False self._focusEventCache[(eventID,window,objectID,childID,threadID)]=next(self._eventCounter) - return + return True elif eventID==winUser.EVENT_SYSTEM_FOREGROUND: self._focusEventCache.pop((winUser.EVENT_OBJECT_FOCUS,window,objectID,childID,threadID),None) self._focusEventCache[(eventID,window,objectID,childID,threadID)]=next(self._eventCounter) @@ -92,16 +95,17 @@ class OrderedWinEventLimiter(object): k=(winUser.EVENT_OBJECT_HIDE,window,objectID,childID,threadID) if k in self._genericEventCache: del self._genericEventCache[k] - return + return True elif eventID==winUser.EVENT_OBJECT_HIDE: k=(winUser.EVENT_OBJECT_SHOW,window,objectID,childID,threadID) if k in self._genericEventCache: del self._genericEventCache[k] - return + return True elif eventID in MENU_EVENTIDS: self._lastMenuEvent=(next(self._eventCounter),eventID,window,objectID,childID,threadID) - return + return True self._genericEventCache[(eventID,window,objectID,childID,threadID)]=next(self._eventCounter) + return True def flushEvents(self): """Returns a list of winEvents (tuples of eventID,window,objectID,childID) that have been added, though due to limiting, it will not necessarily be all the winEvents that were originally added. They are definitely garenteed to be in the correct order though. @@ -565,7 +569,8 @@ def winEventCallback(handle,eventID,window,objectID,childID,threadID,timestamp): # If we send a WM_NULL to this window at this point (which happens in accessibleObjectFromEvent), Messenger will silently exit (#677). # Therefore, completely ignore these events, which is useless to us anyway. return - winEventLimiter.addEvent(eventID,window,objectID,childID,threadID) + if winEventLimiter.addEvent(eventID,window,objectID,childID,threadID): + core.requestPump() except: log.error("winEventCallback", exc_info=True) @@ -690,8 +695,7 @@ def processDesktopSwitchWinEvent(window,objectID,childID): hDesk=windll.user32.OpenInputDesktop(0, False, 0) if hDesk!=0: windll.user32.CloseDesktop(hDesk) - import wx - wx.CallLater(200, _correctFocus) + core.callLater(200, _correctFocus) else: # Switching to a secure desktop. # We don't receive key up events for any keys down before switching to a secure desktop, @@ -790,8 +794,7 @@ def processFakeFocusWinEvent(eventID, window, objectID, childID): """ # A suitable event for faking the focus has been received with no focus event, so we probably need to find the focus and fake it. # However, it is possible that the focus event has simply been delayed, so wait a bit and only do it if the focus hasn't changed yet. - import wx - wx.CallLater(50, _fakeFocus, api.getFocusObject()) + core.callLater(50, _fakeFocus, api.getFocusObject()) def _fakeFocus(oldFocus): if oldFocus is not api.getFocusObject(): diff --git a/source/JABHandler.py b/source/JABHandler.py index a057d8e..1db108d 100644 --- a/source/JABHandler.py +++ b/source/JABHandler.py @@ -16,6 +16,7 @@ import api import eventHandler import controlTypes import NVDAObjects.JAB +import core #Some utility functions to help with function defines @@ -230,6 +231,7 @@ internalFunctionQueue.__name__="JABHandler.internalFunctionQueue" def internalQueueFunction(func,*args,**kwargs): internalFunctionQueue.put_nowait((func,args,kwargs)) + core.requestPump() class JABContext(object): diff --git a/source/core.py b/source/core.py index 6377487..d1a32f3 100644 --- a/source/core.py +++ b/source/core.py @@ -25,6 +25,11 @@ import globalVars from logHandler import log import addonHandler +PUMP_MAX_DELAY = 10 + +_pump = None +_isPumpPending = False + def doStartupDialogs(): import config import gui @@ -116,7 +121,7 @@ def _setInitialFocus(): def main(): """NVDA's core main loop. -This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI. Then it initialises the wx application object and installs the core pump timer, which checks the queues and executes functions every 1 ms. Finally, it starts the wx main loop. +This initializes all modules such as audio, IAccessible, keyboard, mouse, and GUI. Then it initialises the wx application object and sets up the core pump, which checks the queues and executes functions when requested. Finally, it starts the wx main loop. """ log.debug("Core starting") import config @@ -281,13 +286,19 @@ This initializes all modules such as audio, IAccessible, keyboard, mouse, and GU queueHandler.queueFunction(queueHandler.eventQueue, _setInitialFocus) import watchdog import baseObject + + # Doing this here is a bit ugly, but we don't want these modules imported + # at module level, including wx. + log.debug("Initializing core pump") class CorePump(wx.Timer): "Checks the queues and executes functions." - def __init__(self,*args,**kwargs): - log.debug("Core pump starting") - super(CorePump,self).__init__(*args,**kwargs) def Notify(self): + global _isPumpPending + _isPumpPending = False + watchdog.alive() try: + if touchHandler.handler: + touchHandler.handler.pump() JABHandler.pumpAll() IAccessibleHandler.pumpAll() queueHandler.pumpAll() @@ -296,10 +307,16 @@ This initializes all modules such as audio, IAccessible, keyboard, mouse, and GU except: log.exception("errors in this core pump cycle") baseObject.AutoPropertyObject.invalidateCaches() - watchdog.alive() - log.debug("starting core pump") - pump = CorePump() - pump.Start(1) + watchdog.asleep() + if _isPumpPending and not _pump.IsRunning(): + # #3803: A pump was requested, but the timer was ignored by a modal loop + # because timers aren't re-entrant. + # Therefore, schedule another pump. + _pump.Start(PUMP_MAX_DELAY, True) + global _pump + _pump = CorePump() + requestPump() + log.debug("Initializing watchdog") watchdog.initialize() try: @@ -368,3 +385,31 @@ def _terminate(module, name=None): except: log.exception("Error terminating %s" % name) +def requestPump(): + """Request a core pump. + This will perform any queued activity. + It is delayed slightly so that queues can implement rate limiting, + filter extraneous events, etc. + """ + global _isPumpPending + if not _pump or _isPumpPending: + return + _isPumpPending = True + _pump.Start(PUMP_MAX_DELAY, True) + +def callLater(delay, callable, *args, **kwargs): + """Call a callable once after the specified number of milliseconds. + This is currently a thin wrapper around C{wx.CallLater}, + but this should be used instead for calls which aren't just for UI, + as it notifies watchdog appropriately. + """ + import wx + return wx.CallLater(delay, _callLaterExec, callable, args, kwargs) + +def _callLaterExec(callable, args, kwargs): + import watchdog + watchdog.alive() + try: + return callable(*args, **kwargs) + finally: + watchdog.asleep() diff --git a/source/mouseHandler.py b/source/mouseHandler.py index b6c054c..b7668ac 100644 --- a/source/mouseHandler.py +++ b/source/mouseHandler.py @@ -17,6 +17,7 @@ import eventHandler from logHandler import log import config import winInputHook +import core WM_MOUSEMOVE=0x0200 WM_LBUTTONDOWN=0x0201 @@ -75,6 +76,7 @@ def internal_mouseEvent(msg,x,y,injected): curMousePos=(x,y) if msg==WM_MOUSEMOVE: mouseMoved=True + core.requestPump() elif msg in (WM_LBUTTONDOWN,WM_RBUTTONDOWN): queueHandler.queueFunction(queueHandler.eventQueue,speech.cancelSpeech) except: diff --git a/source/pythonConsole.py b/source/pythonConsole.py index 563a440..c66630b 100755 --- a/source/pythonConsole.py +++ b/source/pythonConsole.py @@ -4,6 +4,8 @@ #See the file COPYING for more details. #Copyright (C) 2008-2013 NV Access Limited +import watchdog + """Provides an interactive Python console which can be run from within NVDA. To use, call L{initialize} to create a singleton instance of the console GUI. This can then be accessed externally as L{consoleUI}. """ @@ -207,7 +209,9 @@ class ConsoleUI(wx.Frame): def execute(self): data = self.inputCtrl.GetValue() + watchdog.alive() self.console.push(data) + watchdog.asleep() if data: # Only add non-blank lines to history. if len(self.inputHistory) > 1 and self.inputHistory[-2] == data: diff --git a/source/queueHandler.py b/source/queueHandler.py index 0db66da..b0b6108 100644 --- a/source/queueHandler.py +++ b/source/queueHandler.py @@ -9,6 +9,7 @@ from Queue import Queue import globalVars from logHandler import log import watchdog +import core eventQueue=Queue() eventQueue.__name__="eventQueue" @@ -22,6 +23,7 @@ def registerGeneratorObject(generatorObj): lastGeneratorObjID+=1 log.debug("Adding generator %d"%lastGeneratorObjID) generators[lastGeneratorObjID]=generatorObj + core.requestPump() return lastGeneratorObjID def cancelGeneratorObject(generatorObjID): @@ -33,6 +35,7 @@ def cancelGeneratorObject(generatorObjID): def queueFunction(queue,func,*args,**kwargs): queue.put_nowait((func,args,kwargs)) + core.requestPump() def isRunningGenerators(): res=len(generators)>0 @@ -75,4 +78,6 @@ def pumpAll(): del generators[ID] # Lose our reference so Python can destroy the generator if appropriate. del gen + if generators: + core.requestPump() flushQueue(eventQueue) diff --git a/source/touchHandler.py b/source/touchHandler.py index 573c480..0abd66e 100644 --- a/source/touchHandler.py +++ b/source/touchHandler.py @@ -4,6 +4,7 @@ #See the file COPYING for more details. #Copyright (C) 2012 NV Access Limited +import wx import threading from ctypes import * from ctypes.wintypes import * @@ -15,12 +16,12 @@ import winUser import speech import api import ui -import queueHandler import inputCore import screenExplorer from logHandler import log import touchTracker import gui +import core availableTouchModes=['text','object'] @@ -181,6 +182,7 @@ inputCore.registerGestureSource("ts", TouchInputGesture) class TouchHandler(threading.Thread): def __init__(self): + self.pendingEmitsTimer=wx.PyTimer(core.requestPump) super(TouchHandler,self).__init__() self._curTouchMode='object' self.initializedEvent=threading.Event() @@ -193,6 +195,7 @@ class TouchHandler(threading.Thread): def terminate(self): windll.user32.PostThreadMessageW(self.ident,WM_QUIT,0,0) self.join() + self.pendingEmitsTimer.Stop() def run(self): try: @@ -206,8 +209,6 @@ class TouchHandler(threading.Thread): self.trackerManager=touchTracker.TrackerManager() self.screenExplorer=screenExplorer.ScreenExplorer() self.screenExplorer.updateReview=True - self.gesturePump=self.gesturePumpFunc() - queueHandler.registerGeneratorObject(self.gesturePump) except Exception as e: self.threadExc=e finally: @@ -216,7 +217,6 @@ class TouchHandler(threading.Thread): while windll.user32.GetMessageW(byref(msg),None,0,0): windll.user32.TranslateMessage(byref(msg)) windll.user32.DispatchMessageW(byref(msg)) - self.gesturePump.close() oledll.oleacc.AccSetRunningUtilityState(self._touchWindow,ANRUS_TOUCH_MODIFICATION_ACTIVE,0) windll.user32.UnregisterPointerInputTarget(self._touchWindow,PT_TOUCH) windll.user32.DestroyWindow(self._touchWindow) @@ -231,8 +231,10 @@ class TouchHandler(threading.Thread): ID=winUser.LOWORD(wParam) if touching: self.trackerManager.update(ID,x,y,False) + core.requestPump() elif not flags&POINTER_MESSAGE_FLAG_FIRSTBUTTON: self.trackerManager.update(ID,x,y,True) + core.requestPump() return 0 return windll.user32.DefWindowProcW(hwnd,msg,wParam,lParam) @@ -241,15 +243,20 @@ class TouchHandler(threading.Thread): raise ValueError("Unknown mode %s"%mode) self._curTouchMode=mode - def gesturePumpFunc(self): - while True: - for tracker in self.trackerManager.emitTrackers(): - gesture=TouchInputGesture(tracker,self._curTouchMode) - try: - inputCore.manager.executeGesture(gesture) - except inputCore.NoInputGestureAction: - pass - yield + def pump(self): + for tracker in self.trackerManager.emitTrackers(): + gesture=TouchInputGesture(tracker,self._curTouchMode) + try: + inputCore.manager.executeGesture(gesture) + except inputCore.NoInputGestureAction: + pass + interval=self.trackerManager.pendingEmitInterval + if interval and interval>0: + # Ensure we are pumpped again by the time more pending multiTouch trackers are ready + self.pendingEmitsTimer.Start(interval*1000,True) + else: + # Stop the timer in case we were pumpped due to something unrelated but just happened to be at the appropriate time to clear any remaining trackers + self.pendingEmitsTimer.Stop() def notifyInteraction(self, obj): """Notify the system that UI interaction is occurring via touch. diff --git a/source/touchTracker.py b/source/touchTracker.py index 0fcd302..3d8ccc0 100644 --- a/source/touchTracker.py +++ b/source/touchTracker.py @@ -197,12 +197,14 @@ class TrackerManager(object): if tracker.action!=action_hoverDown: self.multiTouchTrackers.append(tracker) + pendingEmitInterval=None #: If set: how long to wait before calling emitTrackers again as trackers are still in the queue def emitTrackers(self): """ Yields queued trackers that have existed in the queue for long enough to not be connected with other trackers. A part from a timeout, trackers are also not emitted if there are other fingers touching that still have an unknown action. If there are no queued trackers to yield but there is a hover tracker, a hover action is yielded instead. """ + self.pendingEmitInterval=None t=time.time() hasUnknownTrackers=False lastHoverTracker=None @@ -217,10 +219,13 @@ class TrackerManager(object): if not hasUnknownTrackers: for tracker in list(self.multiTouchTrackers): #All trackers can be emitted with no delay except for tap which must wait for the timeout (to detect plural taps) - if tracker.action!=action_tap or (tracker.startTime+multitouchTimeout)<=t: + trackerTimeout=(tracker.startTime+multitouchTimeout)-t if tracker.action==action_tap else 0 + if trackerTimeout<=0: self.multiTouchTrackers.remove(tracker) foundTrackers=True yield tracker + else: + self.pendingEmitInterval=min(self.pendingEmitInterval,trackerTimeout) if self.pendingEmitInterval else trackerTimeout #If no tracker could be emitted, at least emit the most recent hover tracker if there is one if not foundTrackers and lastHoverTracker: yield MultiTouchTracker(lastHoverTracker.action,lastHoverTracker.x,lastHoverTracker.y,lastHoverTracker.startTime,t,1,1,self.numHeldFingers-1) diff --git a/source/watchdog.py b/source/watchdog.py index ca19c70..17f891c 100644 --- a/source/watchdog.py +++ b/source/watchdog.py @@ -15,14 +15,16 @@ import comtypes import winUser import winKernel from logHandler import log +import NVDAHelper #settings #: How often to check whether the core is alive CHECK_INTERVAL=0.1 -#: How long to wait for the core to be alive under normal circumstances -NORMAL_CORE_ALIVE_TIMEOUT=10 -#: The minimum time to wait for the core to be alive +#: The minimum time to wait for the core to be alive. MIN_CORE_ALIVE_TIMEOUT=0.5 +#: How long to wait for the core to be alive under normal circumstances. +#: This must be a multiple of MIN_CORE_ALIVE_TIMEOUT. +NORMAL_CORE_ALIVE_TIMEOUT=10 #: How long to wait between recovery attempts RECOVER_ATTEMPT_INTERVAL = 0.05 #: The amount of time before the core should be considered severely frozen and a warning logged. @@ -37,8 +39,8 @@ safeWindowClassSet=set([ isRunning=False isAttemptingRecovery = False -_coreAliveEvent = threading.Event() -_resumeEvent = threading.Event() +_coreDeadTimer = windll.kernel32.CreateWaitableTimerW(None, True, None) +_suspended = False _coreThreadID=windll.kernel32.GetCurrentThreadId() _watcherThread=None @@ -49,49 +51,63 @@ class CallCancelled(Exception): def alive(): """Inform the watchdog that the core is alive. """ - global _coreAliveEvent - _coreAliveEvent.set() + # Stop cancelling calls. + windll.kernel32.ResetEvent(ctypes.wintypes.HANDLE.in_dll( + NVDAHelper.localLib, "cancelCallEvent")) + # Set the timer so the watcher will take action in MIN_CORE_ALIVE_TIMEOUT + # if this function or asleep() isn't called. + windll.kernel32.SetWaitableTimer(_coreDeadTimer, + ctypes.byref(ctypes.wintypes.LARGE_INTEGER(-int(10000000 * MIN_CORE_ALIVE_TIMEOUT))), + 0, None, None, False) + +def asleep(): + """Inform the watchdog that the core is going to sleep. + """ + windll.kernel32.CancelWaitableTimer(_coreDeadTimer) + +def _isAlive(): + return winKernel.waitForSingleObject(_coreDeadTimer, 0) != 0 def _watcher(): global isAttemptingRecovery - while isRunning: - # If the watchdog is suspended, wait until it is resumed. - _resumeEvent.wait() - - # Wait for the core to be alive. - # Wait a maximum of NORMAL_CORE_ALIVE_TIMEOUT, but shorten this to a minimum of MIN_CORE_ALIVE_TIMEOUT under special circumstances. - waited = 0 - while True: - # Wait MIN_CORE_ALIVE_TIMEOUT, unless there is less than that time remaining for NORMAL_CORE_ALIVE_TIMEOUT. - timeout = min(MIN_CORE_ALIVE_TIMEOUT, NORMAL_CORE_ALIVE_TIMEOUT - waited) - if timeout <= 0: - # Timeout elapsed. - break - _coreAliveEvent.wait(timeout) - waited += timeout - if _coreAliveEvent.isSet() or _shouldRecoverAfterMinTimeout(): + while True: + # Wait for the core to die. + winKernel.waitForSingleObject(_coreDeadTimer, winKernel.INFINITE) + if not isRunning: + return + # The core hasn't reported alive for MIN_CORE_ALIVE_TIMEOUT. + waited = MIN_CORE_ALIVE_TIMEOUT + while not _isAlive() and not _shouldRecoverAfterMinTimeout(): + # The core is still dead and fast recovery doesn't apply. + # Wait up to NORMAL_ALIVE_TIMEOUT. + time.sleep(MIN_CORE_ALIVE_TIMEOUT) + waited += MIN_CORE_ALIVE_TIMEOUT + if waited >= NORMAL_CORE_ALIVE_TIMEOUT: break - if log.isEnabledFor(log.DEBUGWARNING) and not _coreAliveEvent.isSet(): + if _isAlive(): + continue + if log.isEnabledFor(log.DEBUGWARNING): log.debugWarning("Trying to recover from freeze, core stack:\n%s"% "".join(traceback.format_stack(sys._current_frames()[_coreThreadID]))) lastTime=time.time() - while not _coreAliveEvent.isSet(): + isAttemptingRecovery = True + # Cancel calls until the core is alive. + # This event will be reset by alive(). + windll.kernel32.SetEvent(ctypes.wintypes.HANDLE.in_dll( + NVDAHelper.localLib, "cancelCallEvent")) + # Some calls have to be killed individually. + while True: curTime=time.time() if curTime-lastTime>FROZEN_WARNING_TIMEOUT: lastTime=curTime log.warning("Core frozen in stack:\n%s"% "".join(traceback.format_stack(sys._current_frames()[_coreThreadID]))) - # The core is dead, so attempt recovery. - isAttemptingRecovery = True _recoverAttempt() - _coreAliveEvent.wait(RECOVER_ATTEMPT_INTERVAL) + time.sleep(RECOVER_ATTEMPT_INTERVAL) + if _isAlive(): + break isAttemptingRecovery = False - # At this point, the core is alive. - _coreAliveEvent.clear() - # Wait a bit to avoid excessive resource consumption. - time.sleep(CHECK_INTERVAL) - def _shouldRecoverAfterMinTimeout(): info=winUser.getGUIThreadInfo(0) if not info.hwndFocus: @@ -116,8 +132,6 @@ def _recoverAttempt(): oledll.ole32.CoCancelCall(_coreThreadID,0) except: pass - import NVDAHelper - NVDAHelper.localLib.cancelSendMessage() @ctypes.WINFUNCTYPE(ctypes.wintypes.LONG, ctypes.c_void_p) def _crashHandler(exceptionInfo): @@ -158,13 +172,11 @@ def initialize(): windll.kernel32.SetUnhandledExceptionFilter(_crashHandler) oledll.ole32.CoEnableCallCancellation(None) # Handle cancelled SendMessage calls. - import NVDAHelper NVDAHelper._setDllFuncPointer(NVDAHelper.localLib, "_notifySendMessageCancelled", _notifySendMessageCancelled) # Monkey patch comtypes to specially handle cancelled COM calls. comtypes.COMError.__init__ = _COMError_init - _coreAliveEvent.set() - _resumeEvent.set() _watcherThread=threading.Thread(target=_watcher) + alive() _watcherThread.start() def terminate(): @@ -176,8 +188,10 @@ def terminate(): isRunning=False oledll.ole32.CoDisableCallCancellation(None) comtypes.COMError.__init__ = _orig_COMError_init - _resumeEvent.set() - _coreAliveEvent.set() + # Wake up the watcher so it knows to finish. + windll.kernel32.SetWaitableTimer(_coreDeadTimer, + ctypes.byref(ctypes.wintypes.LARGE_INTEGER(0)), + 0, None, None, False) _watcherThread.join() class Suspender(object): @@ -185,10 +199,14 @@ class Suspender(object): """ def __enter__(self): - _resumeEvent.clear() + global _suspended + _suspended = True + asleep() def __exit__(self,*args): - _resumeEvent.set() + global _suspended + _suspended = False + alive() class CancellableCallThread(threading.Thread): """A worker thread used to execute a call which must be made cancellable. @@ -262,7 +280,7 @@ def cancellableExecute(func, *args, **kwargs): """ global cancellableCallThread pumpMessages = kwargs.pop("ccPumpMessages", True) - if not isRunning or not _resumeEvent.isSet() or not isinstance(threading.currentThread(), threading._MainThread): + if not isRunning or _suspended or not isinstance(threading.currentThread(), threading._MainThread): # Watchdog is not running or this is a background thread, # so just execute the call. return func(*args, **kwargs) @@ -279,7 +297,6 @@ def cancellableSendMessage(hwnd, msg, wParam, lParam, flags=0, timeout=60000): The call will still be cancelled if appropriate even if the specified timeout has not yet been reached. @raise CallCancelled: If the call was cancelled. """ - import NVDAHelper result = ctypes.wintypes.DWORD() NVDAHelper.localLib.cancellableSendMessageTimeout(hwnd, msg, wParam, lParam, flags, timeout, ctypes.byref(result)) return result.value |
From: <nor...@nv...> - 2014-02-04 04:39:26
|
The branch t3801 has been updated From 925a4fd to a59e007 New revisions: - Log ----------------------------------------------------------------- commit a59e007b350c068c4763b69910e1e39ac1dd974a Author: James Teh <ja...@nv...> Date: Tue Feb 4 14:27:26 2014 +1000 Notify watchdog appropriately when executing a delayed IAccessibleHandler call to correct the focus. Previously, the watchdog didn't know about these calls, so they weren't subject to possible cancellation. This resulted in unrecovered freezes, for example, when alt+tabbing to an unresponsive process. core.callLater was introduced to facilitate this. It should be used instead of wx.CallLater for any delayed calls which aren't just for UI. ----------------------------------------------------------------------- Summary of changes: source/IAccessibleHandler.py | 6 ++---- source/core.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/source/IAccessibleHandler.py b/source/IAccessibleHandler.py index 395a398..21b391d 100644 --- a/source/IAccessibleHandler.py +++ b/source/IAccessibleHandler.py @@ -695,8 +695,7 @@ def processDesktopSwitchWinEvent(window,objectID,childID): hDesk=windll.user32.OpenInputDesktop(0, False, 0) if hDesk!=0: windll.user32.CloseDesktop(hDesk) - import wx - wx.CallLater(200, _correctFocus) + core.callLater(200, _correctFocus) else: # Switching to a secure desktop. # We don't receive key up events for any keys down before switching to a secure desktop, @@ -795,8 +794,7 @@ def processFakeFocusWinEvent(eventID, window, objectID, childID): """ # A suitable event for faking the focus has been received with no focus event, so we probably need to find the focus and fake it. # However, it is possible that the focus event has simply been delayed, so wait a bit and only do it if the focus hasn't changed yet. - import wx - wx.CallLater(50, _fakeFocus, api.getFocusObject()) + core.callLater(50, _fakeFocus, api.getFocusObject()) def _fakeFocus(oldFocus): if oldFocus is not api.getFocusObject(): diff --git a/source/core.py b/source/core.py index 2810aea..d1a32f3 100644 --- a/source/core.py +++ b/source/core.py @@ -396,3 +396,20 @@ def requestPump(): return _isPumpPending = True _pump.Start(PUMP_MAX_DELAY, True) + +def callLater(delay, callable, *args, **kwargs): + """Call a callable once after the specified number of milliseconds. + This is currently a thin wrapper around C{wx.CallLater}, + but this should be used instead for calls which aren't just for UI, + as it notifies watchdog appropriately. + """ + import wx + return wx.CallLater(delay, _callLaterExec, callable, args, kwargs) + +def _callLaterExec(callable, args, kwargs): + import watchdog + watchdog.alive() + try: + return callable(*args, **kwargs) + finally: + watchdog.asleep() |
From: <nor...@nv...> - 2014-02-04 02:05:11
|
The branch next has been updated From 9a684b1 to 097fdf6 New revisions: - Log ----------------------------------------------------------------- commit 097fdf677a78ad5b1637f1ccc17e669c3adb5dac Merge: 9a684b1 65ae5aa Author: Michael Curran <mi...@nv...> Date: Tue Feb 4 12:04:57 2014 +1000 Merge branch 'master' into next ----------------------------------------------------------------------- Summary of changes: sconstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sconstruct b/sconstruct index 1cd3b65..f082535 100755 --- a/sconstruct +++ b/sconstruct @@ -126,7 +126,7 @@ env.SConscript('source/comInterfaces_sconscript',exports=['env']) #Process nvdaHelper scons files env32.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env32,'clientInstallDir':clientDir.Dir('x86'),'libInstallDir':sourceLibDir},variant_dir='build/x86') -env64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env64,'clientInstallDir':clientDir.Dir('x86_64'),'libInstallDir':sourceLibDir64},variant_dir='build/x86_64') +env64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env64,'clientInstallDir':clientDir.Dir('x64'),'libInstallDir':sourceLibDir64},variant_dir='build/x86_64') #Allow all NVDA's gettext po files to be compiled in source/locale for po in env.Glob(sourceDir.path+'/locale/*/lc_messages/*.po'): |
From: NVDA T. <nor...@nv...> - 2014-02-04 02:04:34
|
#3796: "scons client" outputs x64 files to .../x86_64 -------------------------+------------------------------------------------- Reporter: jteh | Owner: Michael Curran <mi...@nv...> Type: | Status: closed defect | Milestone: 2014.1 Priority: | Version: minor | Keywords: regression Component: | Blocked by: Distribution | Resolution: | fixed | Operating system: | Blocking: | -------------------------+------------------------------------------------- Changes entry: -------------------------+------------------------------------------------- Changes (by Michael Curran <mi...@nv...>): * status: new => closed * owner: => Michael Curran <mi...@nv...> * resolution: => fixed Comment: In [changeset:"65ae5aab5f267ecf8d0d5bd8fb1b320a3ad2743a"]: {{{ #!CommitTicketReference repository="" revision="65ae5aab5f267ecf8d0d5bd8fb1b320a3ad2743a" Again place 64-bit controllerClient libs in a subdir of x64. It was changed to x86_64 around the time of moving to msvc 2012. Fixes #3796 }}} -- Ticket URL: </ticket/3796#comment:1> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
The branch master has been updated From ad3398c to 65ae5aa New revisions: - Log ----------------------------------------------------------------- commit 65ae5aab5f267ecf8d0d5bd8fb1b320a3ad2743a Author: Michael Curran <mi...@nv...> Date: Tue Feb 4 12:04:16 2014 +1000 Again place 64-bit controllerClient libs in a subdir of x64. It was changed to x86_64 around the time of moving to msvc 2012. Fixes #3796 ----------------------------------------------------------------------- Summary of changes: sconstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sconstruct b/sconstruct index 7b6c37d..672cb6b 100755 --- a/sconstruct +++ b/sconstruct @@ -126,7 +126,7 @@ env.SConscript('source/comInterfaces_sconscript',exports=['env']) #Process nvdaHelper scons files env32.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env32,'clientInstallDir':clientDir.Dir('x86'),'libInstallDir':sourceLibDir},variant_dir='build/x86') -env64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env64,'clientInstallDir':clientDir.Dir('x86_64'),'libInstallDir':sourceLibDir64},variant_dir='build/x86_64') +env64.SConscript('nvdaHelper/archBuild_sconscript',exports={'env':env64,'clientInstallDir':clientDir.Dir('x64'),'libInstallDir':sourceLibDir64},variant_dir='build/x86_64') #Allow all NVDA's gettext po files to be compiled in source/locale for po in env.Glob(sourceDir.path+'/locale/*/lc_messages/*.po'): |
From: NVDA T. <nor...@nv...> - 2014-02-04 00:28:04
|
#3844: Please update espeak voice files for Persian (Farsi) ----------------------------+------------------ Reporter: taghavi | Owner: Type: defect | Status: new Priority: trivial | Milestone: Component: Core | Version: Resolution: | Keywords: Operating system: | Blocked by: Blocking: | ----------------------------+------------------ Changes entry: ----------------------------+------------------ Changes (by jteh): * priority: minor => trivial Comment: I'm very reluctant to have our eSpeak deviate from the official eSpeak project. Please consider making this request in the eSpeak project. -- Ticket URL: <http://community.nvda-project.org/ticket/3844#comment:1> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-04 00:16:08
|
#3845: Crash because of adding a new line on top of a table in Word 2010 ---------------------------------+--------------------- Reporter: The_Dark_Man | Owner: Type: defect | Status: new Priority: minor | Milestone: Component: Core | Version: 2013.3 Resolution: | Keywords: Operating system: Windows 7 | Blocked by: Blocking: | ---------------------------------+--------------------- Changes entry: ---------------------------------+--------------------- Comment (by The_Dark_Man): I mean a new row at the top. I am in the table and add a new row for column heading for example. Sorry, my English is not so good. -- Ticket URL: <http://community.nvda-project.org/ticket/3845#comment:2> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: <nor...@nv...> - 2014-02-03 23:46:55
|
The branch next has been updated From 2b2fd0a to 9a684b1 New revisions: - Log ----------------------------------------------------------------- commit 9a684b145083a6a56fb112c65c707655f08b5910 Merge: 2b2fd0a ad3398c Author: Michael Curran <mi...@nv...> Date: Tue Feb 4 09:46:41 2014 +1000 Merge branch 'master' into next ----------------------------------------------------------------------- Summary of changes: source/NVDAObjects/IAccessible/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index faf90c8..2ac2130 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -920,7 +920,7 @@ the NVDAObject for IAccessible #Hack around bad MSAA implementations that deliberately skip the window root IAccessible in the ancestry (Skype, iTunes) if parentObj.windowHandle!=self.windowHandle and self.IAccessibleRole!=oleacc.ROLE_SYSTEM_WINDOW and winUser.getAncestor(self.windowHandle,winUser.GA_PARENT)==parentObj.windowHandle: windowObj=Window(windowHandle=self.windowHandle) - if windowObj and windowObj.IAccessibleRole==oleacc.ROLE_SYSTEM_WINDOW and windowObj.parent==parentObj: + if windowObj and isinstance(windowObj,IAccessible) and windowObj.IAccessibleRole==oleacc.ROLE_SYSTEM_WINDOW and windowObj.parent==parentObj: return windowObj return self.correctAPIForRelation(parentObj,relation="parent") or super(IAccessible,self).parent return super(IAccessible,self).parent |
From: <nor...@nv...> - 2014-02-03 23:46:01
|
The branch master has been updated From 7ac923a to ad3398c New revisions: - Log ----------------------------------------------------------------- commit ad3398cd842ba82ff36d95c4d3dfe2a55bb7819e Author: Michael Curran <mi...@nv...> Date: Tue Feb 4 09:45:36 2014 +1000 IAccessible NVDAObject's parent property: ensure windowObj is an IAccessible before fetching IAccessibleRole ----------------------------------------------------------------------- Summary of changes: source/NVDAObjects/IAccessible/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index faf90c8..2ac2130 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -920,7 +920,7 @@ the NVDAObject for IAccessible #Hack around bad MSAA implementations that deliberately skip the window root IAccessible in the ancestry (Skype, iTunes) if parentObj.windowHandle!=self.windowHandle and self.IAccessibleRole!=oleacc.ROLE_SYSTEM_WINDOW and winUser.getAncestor(self.windowHandle,winUser.GA_PARENT)==parentObj.windowHandle: windowObj=Window(windowHandle=self.windowHandle) - if windowObj and windowObj.IAccessibleRole==oleacc.ROLE_SYSTEM_WINDOW and windowObj.parent==parentObj: + if windowObj and isinstance(windowObj,IAccessible) and windowObj.IAccessibleRole==oleacc.ROLE_SYSTEM_WINDOW and windowObj.parent==parentObj: return windowObj return self.correctAPIForRelation(parentObj,relation="parent") or super(IAccessible,self).parent return super(IAccessible,self).parent |
From: <nor...@nv...> - 2014-02-03 22:36:28
|
The branch t3825 has been updated From 47fd8ab to 99d5c9a New revisions: - Log ----------------------------------------------------------------- commit 99d5c9a1611ae5cd5a3d791ffceaf68360776a1b Author: James Teh <ja...@nv...> Date: Tue Feb 4 08:36:23 2014 +1000 cancellableSendMessageTimeout: Don't pump if SMTO_BLOCK is specified. ----------------------------------------------------------------------- Summary of changes: nvdaHelper/local/nvdaHelperLocal.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nvdaHelper/local/nvdaHelperLocal.cpp b/nvdaHelper/local/nvdaHelperLocal.cpp index cf11b47..fba2d56 100644 --- a/nvdaHelper/local/nvdaHelperLocal.cpp +++ b/nvdaHelper/local/nvdaHelperLocal.cpp @@ -208,7 +208,15 @@ LRESULT cancellableSendMessageTimeout(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM HANDLE waitHandles[] = {bgSendMessageData->completeEvent, cancelSendMessageEvent}; DWORD waitIndex = 0; - CoWaitForMultipleHandles(0, INFINITE, 2, waitHandles, &waitIndex); + if (fuFlags & SMTO_BLOCK) { + waitIndex = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE); + } else { + // We need to pump nonqueued messages while waiting. + // MsgWaitForMultipleObjects can wake for nonqueued messages, + // but we'd have to manage the actual pump ourselves. + // CoWaitForMultipleHandles does exactly what we need. + CoWaitForMultipleHandles(0, INFINITE, 2, waitHandles, &waitIndex); + } isActiveBgSendMessage = false; if (waitIndex == 1) { // Cancelled. Abandon the thread. |
From: NVDA T. <nor...@nv...> - 2014-02-03 21:12:51
|
#3845: Crash because of adding a new line on top of a table in Word 2010 ---------------------------------+--------------------- Reporter: The_Dark_Man | Owner: Type: defect | Status: new Priority: minor | Milestone: Component: Core | Version: 2013.3 Resolution: | Keywords: Operating system: Windows 7 | Blocked by: Blocking: | ---------------------------------+--------------------- Changes entry: ---------------------------------+--------------------- Comment (by jteh): This is unclear. For example, I'm not sure whether you mean a blank line before the table or a new row at the top. Please provide exact steps to reproduce, including the commands you used to create the table and insert the "new line on top". -- Ticket URL: <http://community.nvda-project.org/ticket/3845#comment:1> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 20:58:19
|
#3845: Crash because of adding a new line on top of a table in Word 2010 ---------------------------+------------------------------ Reporter: The_Dark_Man | Owner: Type: defect | Status: new Priority: minor | Component: Core Version: 2013.3 | Operating system: Windows 7 Blocked by: | Blocking: ---------------------------+------------------------------ Changes entry: ---------------------------+------------------------------ When I want to insert a new line on top of a table in Word 2010 NVDA stops speaking and doesn't react anymore. I have to press ALT + Tab to make it work again. -- Ticket URL: <http://community.nvda-project.org/ticket/3845> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 19:15:59
|
#3814: NVDA next 10237: reading version numbers in commas instead of dots -------------------------------+------------------------------------------ Reporter: domasofan | Owner: Type: defect | Status: new Priority: minor | Milestone: Component: Speech | Version: next Resolution: | Keywords: needsExternalFix regression Operating system: Windows XP | Blocked by: 3842 Blocking: | -------------------------------+------------------------------------------ Changes entry: -------------------------------+------------------------------------------ Comment (by domasofan): hi, i also confirm that it is fixed and works now as expected. using next 10291. thanks very much. greetings, simon Replying to [comment:4 jteh]: > Is this fixed in the latest next snapshot? (Even if it is, please just comment; don't close the ticket yet.) -- Ticket URL: <http://community.nvda-project.org/ticket/3814#comment:6> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 13:46:09
|
#3814: NVDA next 10237: reading version numbers in commas instead of dots -------------------------------+------------------------------------------ Reporter: domasofan | Owner: Type: defect | Status: new Priority: minor | Milestone: Component: Speech | Version: next Resolution: | Keywords: needsExternalFix regression Operating system: Windows XP | Blocked by: 3842 Blocking: | -------------------------------+------------------------------------------ Changes entry: -------------------------------+------------------------------------------ Comment (by k_kolev1985): Yes, Jamie, for me at least it is fixed. Now eSpeak speaks version numbers with dots as it should, instead with commas as it did with the last few "next" snapshots. Thanks! -- Ticket URL: <http://community.nvda-project.org/ticket/3814#comment:5> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 13:20:28
|
#3844: Please update espeak voice files for Persian (Farsi) ----------------------+------------------------- Reporter: taghavi | Owner: Type: defect | Status: new Priority: minor | Component: Core Version: | Operating system: Blocked by: | Blocking: ----------------------+------------------------- Changes entry: ----------------------+------------------------- Persian language sometimes called Farsi. While NVDA correctly use "Persian" term for referring this language in general settings dialog box, espeak use "Farsi" term for refer this language in voice settings dialog box! Hence users confused between this two names. Please update using attached files for solve this problem. Thanks in advance Mahmood Taghavi Best Regards -- Ticket URL: <http://community.nvda-project.org/ticket/3844> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 11:03:17
|
#3814: NVDA next 10237: reading version numbers in commas instead of dots -------------------------------+------------------------------------------ Reporter: domasofan | Owner: Type: defect | Status: new Priority: minor | Milestone: Component: Speech | Version: next Resolution: | Keywords: needsExternalFix regression Operating system: Windows XP | Blocked by: 3842 Blocking: | -------------------------------+------------------------------------------ Changes entry: -------------------------------+------------------------------------------ Changes (by jteh): * blockedby: => 3842 Comment: Is this fixed in the latest next snapshot? (Even if it is, please just comment; don't close the ticket yet.) -- Ticket URL: <http://community.nvda-project.org/ticket/3814#comment:4> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 11:01:36
|
#3739: NVDA is crashed --------------------------------+------------------------------- Reporter: shadyar | Owner: mdcurran Type: defect | Status: assigned Priority: minor | Milestone: Component: Core | Version: master Resolution: | Keywords: NeedsExternalFix Operating system: Windows 8.1 | Blocked by: 3842 Blocking: 3838 | --------------------------------+------------------------------- Changes entry: --------------------------------+------------------------------- Changes (by jteh): * owner: Michael Curran <mi...@nv...> => mdcurran * status: incubating => assigned * blockedby: 3814 => 3842 Comment: Branch superceded by #3842 (eSpeak 1.48). -- Ticket URL: <http://community.nvda-project.org/ticket/3739#comment:9> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 11:00:10
|
#3739: NVDA is crashed --------------------------------+------------------------------- Reporter: shadyar | Owner: mdcurran Type: defect | Status: assigned Priority: minor | Milestone: Component: Core | Version: master Resolution: | Keywords: NeedsExternalFix Operating system: Windows 8.1 | Blocked by: 3842 Blocking: | --------------------------------+------------------------------- Changes entry: --------------------------------+------------------------------- Changes (by jteh): * status: incubating => assigned * owner: Michael Curran <mi...@nv...> => mdcurran * blocking: 3838 => * blockedby: 3814 => 3842 Comment: Branch superceded by #3842 (eSpeak 1.48). -- Ticket URL: <http://community.nvda-project.org/ticket/3739#comment:9> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:57:32
|
#3838: Bug: NVDA after version 2013.3 crash when reading this word! -------------------------------+--------------------- Reporter: taghavi | Owner: Type: defect | Status: closed Priority: minor | Milestone: Component: Core | Version: master Resolution: duplicate | Keywords: Operating system: Windows XP | Blocked by: 3739 Blocking: | -------------------------------+--------------------- Changes entry: -------------------------------+--------------------- Changes (by jteh): * status: new => closed * resolution: => duplicate * blockedby: => 3739 Comment: Marking as a duplicate of #3739, as that is very probably the same crash. In any case, it's fixed in eSpeak 1.48. See #3842. -- Ticket URL: <http://community.nvda-project.org/ticket/3838#comment:2> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:52:07
|
#3842: Request to upgrade espeak. --------------------------------+------------------------- Reporter: MHameed | Owner: Type: enhancement | Status: incubating Priority: trivial | Milestone: next Component: Speech | Version: Resolution: | Keywords: Operating system: | Blocked by: Blocking: | --------------------------------+------------------------- Changes entry: --------------------------------+------------------------- Changes (by jteh): * status: reopened => incubating Comment: changeset:21e25ea5 for next. Note that readme.txt and changes.t2t need to be updated once it's merged to master. -- Ticket URL: <http://community.nvda-project.org/ticket/3842#comment:3> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:50:34
|
#3842: Request to upgrade espeak. --------------------------------+----------------------- Reporter: MHameed | Owner: Type: enhancement | Status: reopened Priority: trivial | Milestone: next Component: Speech | Version: Resolution: | Keywords: Operating system: | Blocked by: Blocking: | --------------------------------+----------------------- Changes entry: --------------------------------+----------------------- Changes (by jteh): * status: closed => reopened * resolution: fixed => * milestone: => next Comment: Now that you've created a specific ticket for it, we may as well set it to incubating. :) -- Ticket URL: <http://community.nvda-project.org/ticket/3842#comment:2> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:48:42
|
#3843: sysListView32.List.columnCount can send to a null HWND ----------------------+------------------------ Reporter: jteh | Owner: Type: defect | Status: new Priority: trivial | Milestone: Component: Core | Version: Keywords: | Operating system: Blocked by: | Blocking: ----------------------+------------------------ Changes entry: ----------------------+------------------------ It fetches the header window, but doesn't check whether the result is null. This seems to happen when pressing backspace in Windows Explorer in Windows XP. We shouldn't send messages to a null HWND, though this is normally harmless. -- Ticket URL: <http://community.nvda-project.org/ticket/3843> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:46:56
|
#3842: Request to upgrade espeak. --------------------------------+--------------------- Reporter: MHameed | Owner: Type: enhancement | Status: closed Priority: trivial | Milestone: Component: Speech | Version: Resolution: fixed | Keywords: Operating system: | Blocked by: Blocking: | --------------------------------+--------------------- Changes entry: --------------------------------+--------------------- Changes (by MHameed): * status: new => closed * resolution: => fixed Comment: Sorry Jamie, I see that you have done this already in next. -- Ticket URL: <http://community.nvda-project.org/ticket/3842#comment:1> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:42:42
|
#3842: Request to upgrade espeak. --------------------------+------------------------ Reporter: MHameed | Owner: Type: enhancement | Status: new Priority: trivial | Milestone: Component: Speech | Version: Keywords: | Operating system: Blocked by: | Blocking: --------------------------+------------------------ Changes entry: --------------------------+------------------------ Espeak stable 1.48.02 is now available: http://espeak.sourceforge.net/download.html This is a request to update nvda to use this version. This fixes a regression in the german language, and has important improvements for aragonese. Thanks -- Ticket URL: <http://community.nvda-project.org/ticket/3842> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |
From: NVDA T. <nor...@nv...> - 2014-02-03 10:39:18
|
#3825: Unable to cancel SendMessage when switching apps in some cases ---------------------------+------------------------- Reporter: jteh | Owner: jteh Type: defect | Status: incubating Priority: minor | Milestone: next Component: Core | Version: Resolution: | Keywords: freeze Operating system: | Blocked by: Blocking: | ---------------------------+------------------------- Changes entry: Bug Fixes: - NVDA recovers in more cases when switching away from applications that stop responding. (#3825) ---------------------------+------------------------- Comment (by James Teh <ja...@nv...>): In [changeset:"2b2fd0ae21d2ccff8bcf73aa3ff0732cf7d1e267"]: {{{ #!CommitTicketReference repository="" revision="2b2fd0ae21d2ccff8bcf73aa3ff0732cf7d1e267" Merge branch 't3825' into next Incubates #3825. }}} -- Ticket URL: </ticket/3825#comment:5> NVDA Community <http://community.nvda-project.org/> A free and open-source screen reader for Windows |