Skip to content

Commit 5564d38

Browse files
committed
Bug fix on macOS
Terminate NSApp before endLoop
1 parent c6492ab commit 5564d38

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "py3-tts"
3-
version = "3.2"
3+
version = "3.3a"
44
dependencies = [
55
"comtypes; platform_system == 'Windows'",
66
"pypiwin32; platform_system == 'Windows'",

pyttsx3/drivers/nsss.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,28 @@
22
from AppKit import NSSpeechSynthesizer
33
from Foundation import *
44
from PyObjCTools import AppHelper
5+
# noinspection PyProtectedMember
6+
from PyObjCTools.AppHelper import PyObjCAppHelperRunLoopStopper
57

68
from ..voice import Voice
79

810

11+
# noinspection PyUnresolvedReferences
12+
class RunLoopStopper(PyObjCAppHelperRunLoopStopper):
13+
"""
14+
Overrides PyObjCAppHelperRunLoopStopper to terminate after endLoop.
15+
"""
16+
17+
def __init__(self):
18+
self.shouldStop = False
19+
20+
def init(self):
21+
return objc.super(RunLoopStopper, self).init()
22+
23+
def stop(self):
24+
self.shouldStop = True
25+
26+
927
# noinspection PyPep8Naming
1028
def buildDriver(proxy):
1129
return NSSpeechDriver.alloc().initWithProxy(proxy)
@@ -42,9 +60,22 @@ def onPumpFirst_(self, timer):
4260
self._proxy.setBusy(False)
4361

4462
def startLoop(self):
63+
# https://github.com/ronaldoussoren/pyobjc/blob/mater/pyobjc-framework-Cocoa/Lib/PyObjCTools/AppHelper.py#L243C25-L243C25 # noqa
4564
NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(
46-
0.0, self, 'onPumpFirst:', None, False)
47-
AppHelper.runConsoleEventLoop()
65+
0.0, self, 'onPumpFirst:', None, False
66+
)
67+
runLoop = NSRunLoop.currentRunLoop()
68+
stopper = RunLoopStopper.alloc().init()
69+
PyObjCAppHelperRunLoopStopper.addRunLoopStopper_toRunLoop_(stopper, runLoop)
70+
while stopper.shouldRun():
71+
nextfire = runLoop.limitDateForMode_(NSDefaultRunLoopMode)
72+
soon = NSDate.dateWithTimeIntervalSinceNow_(0) # maxTimeout in runConsoleEventLoop
73+
if nextfire is not None:
74+
nextfire = soon.earlierDate_(nextfire)
75+
if not runLoop.runMode_beforeDate_(NSDefaultRunLoopMode, nextfire):
76+
stopper.stop()
77+
break
78+
PyObjCAppHelperRunLoopStopper.removeRunLoopStopperFromRunLoop_(runLoop)
4879

4980
@staticmethod
5081
def endLoop():

0 commit comments

Comments
 (0)