macOS: Fix opening multiple books from Finder with the editor only opening one of the books

This commit is contained in:
Kovid Goyal 2024-07-27 10:50:45 +05:30
parent f524711a3b
commit 28fded9122
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 37 additions and 20 deletions

View File

@ -1199,6 +1199,8 @@ class Application(QApplication):
self.headless = headless
from calibre_extensions import progress_indicator
self.pi = progress_indicator
self._file_open_paths = []
self._file_open_lock = RLock()
QApplication.setOrganizationName('calibre-ebook.com')
QApplication.setOrganizationDomain(QApplication.organizationName())
QApplication.setApplicationVersion(__version__)
@ -1258,8 +1260,6 @@ class Application(QApplication):
self._translator = None
self.load_translations()
qt_app = self
self._file_open_paths = []
self._file_open_lock = RLock()
if not ismacos:
# OS X uses a native color dialog that does not support custom
@ -1375,9 +1375,16 @@ class Application(QApplication):
def _send_file_open_events(self):
with self._file_open_lock:
if self._file_open_paths:
if callable(self.file_event_hook):
self.file_event_hook(self._file_open_paths)
self._file_open_paths = []
def get_pending_file_open_events(self):
with self._file_open_lock:
ans = self._file_open_paths
self._file_open_paths = []
return ans
def load_translations(self):
if self._translator is not None:
self.removeTranslator(self._translator)
@ -1386,7 +1393,7 @@ class Application(QApplication):
def event(self, e):
etype = e.type()
if callable(self.file_event_hook) and etype == QEvent.Type.FileOpen:
if etype == QEvent.Type.FileOpen:
url = e.url().toString(QUrl.ComponentFormattingOption.FullyEncoded)
if url and url.startswith('calibre://'):
with self._file_open_lock:
@ -1394,7 +1401,7 @@ class Application(QApplication):
QTimer.singleShot(1000, self._send_file_open_events)
return True
path = str(e.file())
if os.access(path, os.R_OK):
if path and os.access(path, os.R_OK):
with self._file_open_lock:
self._file_open_paths.append(path)
QTimer.singleShot(1000, self._send_file_open_events)

View File

@ -8,7 +8,7 @@ import time
from qt.core import QIcon
from calibre.constants import EDITOR_APP_UID, islinux
from calibre.constants import EDITOR_APP_UID, islinux, ismacos
from calibre.ebooks.oeb.polish.check.css import shutdown as shutdown_css_check_pool
from calibre.gui2 import Application, decouple, set_gui_prefs, setup_gui_option_parser
from calibre.ptempfile import reset_base_dir
@ -34,19 +34,23 @@ files inside the book which will be opened for editing automatically.
return parser
class EventAccumulator:
def __init__(self):
self.events = []
def __call__(self, ev):
self.events.append(ev)
def gui_main(path=None, notify=None):
_run(['ebook-edit', path], notify=notify)
def open_path_in_new_editor_instance(path: str):
import subprocess
from calibre.gui2 import sanitize_env_vars
with sanitize_env_vars():
if ismacos:
from calibre.utils.ipc.launch import macos_edit_book_bundle_path
bundle = os.path.dirname(os.path.dirname(macos_edit_book_bundle_path().rstrip('/')))
subprocess.Popen(['open', '-n', '-a', bundle, path])
else:
subprocess.Popen([sys.executable, path])
def _run(args, notify=None):
from calibre.utils.webengine import setup_fake_protocol
# Ensure we can continue to function if GUI is closed
@ -68,7 +72,6 @@ def _run(args, notify=None):
app = Application(args, override_program_name=override, color_prefs=tprefs, windows_app_uid=EDITOR_APP_UID)
from calibre.utils.webengine import setup_default_profile
setup_default_profile()
app.file_event_hook = EventAccumulator()
app.load_builtin_fonts()
app.setWindowIcon(QIcon.ic('tweak.png'))
main = Main(opts, notify=notify)
@ -78,9 +81,16 @@ def _run(args, notify=None):
if len(args) > 1:
main.boss.open_book(args[1], edit_file=args[2:], clear_notify_data=False, search_text=opts.select_text)
else:
for path in reversed(app.file_event_hook.events):
main.boss.open_book(path)
break
paths = app.get_pending_file_open_events()
if paths:
if len(paths) > 1:
for path in paths[1:]:
try:
open_path_in_new_editor_instance(path)
except Exception:
import traceback
traceback.print_exc()
main.boss.open_book(paths[0])
app.file_event_hook = main.boss.open_book
app.exec()
# Ensure that the parse worker has quit so that temp files can be deleted