Skip to content

Commit

Permalink
huhh
Browse files Browse the repository at this point in the history
  • Loading branch information
rdbende committed Nov 6, 2023
1 parent 570c26b commit 3d0cd91
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 46 deletions.
2 changes: 2 additions & 0 deletions porcupine/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def main() -> None:
)

args = parser.parse_args()

_state.init(args)

# Prevent showing up a not-ready-yet root window to user
Expand All @@ -139,6 +140,7 @@ def main() -> None:
get_main_window().mainloop()
finally:
settings.save()

log.info("exiting Porcupine successfully")


Expand Down
20 changes: 10 additions & 10 deletions porcupine/_ipc.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ def _listener2queue(listener: connection.Listener, object_queue: queue.Queue[Any
break


@contextlib.contextmanager
def session() -> Iterator[queue.Queue[Any]]:
def start_session() -> tuple[connection.Listener, queue.Queue[Any]]:
"""Context manager that listens for send().
Use this as a context manager:
Expand All @@ -64,11 +63,12 @@ def session() -> Iterator[queue.Queue[Any]]:
# the application
"""
message_queue: queue.Queue[Any] = queue.Queue()
with connection.Listener() as listener:
with _ADDRESS_FILE.open("w") as file:
print(listener.address, file=file)
thread = threading.Thread(
target=_listener2queue, args=[listener, message_queue], daemon=True
)
thread.start()
yield message_queue
listener = connection.Listener()

with _ADDRESS_FILE.open("w") as file:
print(listener.address, file=file)

thread = threading.Thread(target=_listener2queue, args=[listener, message_queue], daemon=True)
thread.start()

return listener, message_queue
52 changes: 31 additions & 21 deletions porcupine/_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
import tkinter
import types
from pathlib import Path
from typing import Any, Callable, Type
from typing import TYPE_CHECKING, Any, Callable, Iterable, Type
import queue

from multiprocessing import connection

from porcupine import _ipc, images, tabs, utils
from porcupine.tabs import FileTab

# Windows resolution
if sys.platform == "win32":
Expand All @@ -34,6 +38,7 @@ class _State:
tab_manager: tabs.TabManager
quit_callbacks: list[Callable[[], bool]]
parsed_args: Any # not None
ipc_session: connection.Listener


# global state makes some things a lot easier (I'm sorry)
Expand All @@ -46,10 +51,6 @@ def _log_tkinter_error(
log.error("Error in tkinter callback", exc_info=(exc, val, tb))


class Quit:
...


def open_files(files: Iterable[str]) -> None:
tabmanager = get_tab_manager()
for path_string in files:
Expand All @@ -61,24 +62,27 @@ def open_files(files: Iterable[str]) -> None:
# ^D
# bla bla
# ^D
tabmanager.file_queue.put(sys.stdin.read())
tabmanager.add_tab(FileTab(tabmanager, content=sys.stdin.read()))
else:
tabmanager.file_queue.put(Path(path_string))
tabmanager.open_file(Path(path_string))


Quit = object()

tabmanager.event_generate("<<OpenFilesQueue>>")

def listen_for_files(message_queue: queue.Queue):
try:
message = message_queue.get_nowait()
except queue.Empty:
message = None
else:
try:
open_files([message])
except Exception as e:
log.error(e)

def listen_for_files():
with _ipc.session() as ipc_message_queue:
while True:
message = ipc_message_queue.get()
if message is Quit:
break
else:
try:
open_files([message])
except Exception as e:
log.error(e)
if message is not Quit:
_get_state().root.after(500, listen_for_files, message_queue)


# undocumented on purpose, don't use in plugins
Expand All @@ -93,9 +97,9 @@ def init(args: Any) -> None:
try:
_ipc.send(args.files)
except ConnectionRefusedError:
thread = threading.Thread(target=listen_for_files, daemon=True).start()
ipc_session, message_queue = _ipc.start_session()
else:
log.error("another instance of Porcupine is already running, files were sent to it")
log.info("another instance of Porcupine is already running, files were sent to it")
sys.exit()

root = tkinter.Tk(className="Porcupine") # class name shows up in my alt+tab list
Expand Down Expand Up @@ -126,7 +130,11 @@ def init(args: Any) -> None:
tab_manager=tab_manager,
quit_callbacks=[],
parsed_args=args,
ipc_session=ipc_session,
)

listen_for_files(message_queue)

log.debug("init() done")


Expand Down Expand Up @@ -187,6 +195,8 @@ def quit() -> None:

_ipc.send([Quit])

_get_state().ipc_session.close()

for tab in get_tab_manager().tabs():
get_tab_manager().close_tab(tab)
get_main_window().destroy()
15 changes: 0 additions & 15 deletions porcupine/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import itertools
import logging
import os
import queue
import tkinter
import traceback
from pathlib import Path
Expand Down Expand Up @@ -87,11 +86,9 @@ class TabManager(ttk.Notebook):

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.file_queue = queue.Queue()

self.bind("<<NotebookTabChanged>>", self._on_tab_selected, add=True)
self.bind("<<FileSystemChanged>>", self._on_fs_changed, add=True)
self.bind("<<OpenFilesQueue>>", self.open_from_queue, add=True)
self.winfo_toplevel().bind("<FocusIn>", self._handle_main_window_focus, add=True)

# the string is call stack for adding callback
Expand Down Expand Up @@ -162,18 +159,6 @@ def tabs(self) -> tuple[Tab, ...]:
# strings instead of widget objects
return tuple(self.nametowidget(tab) for tab in super().tabs())

def open_from_queue(self, event: tkinter.Event):
while True:
try:
to_topen = self.file_queue.get(False)
except queue.Empty:
break

if isinstance(to_topen, str):
self.add_tab(FileTab(self, content=to_topen))
else:
self.open_file(to_topen)

def open_file(self, path: Path) -> FileTab | None:
"""Add a :class:`FileTab` for editing a file and select it.
Expand Down

0 comments on commit 3d0cd91

Please sign in to comment.