app v1.1
This commit is contained in:
529
core/app.py
529
core/app.py
@@ -1,18 +1,15 @@
|
||||
# v3.1.0 app.py
|
||||
# v4.2.1 app.py
|
||||
import atexit
|
||||
import signal
|
||||
import traceback
|
||||
import contextlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from hashlib import sha256
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
from PyQt6.QtCore import (
|
||||
QEasingCurve,
|
||||
@@ -49,10 +46,16 @@ from PyQt6.QtWidgets import (
|
||||
from qframelesswindow import AcrylicWindow
|
||||
|
||||
from config.profiles import THEMES
|
||||
|
||||
from config.settings import (
|
||||
APP_DIR,
|
||||
MARKDOWN_FILE,
|
||||
SETTINGS_FILE,
|
||||
STATE_FILE,
|
||||
SettingsManager,
|
||||
atomic_write,
|
||||
)
|
||||
|
||||
from ui.editor import LinkTextEdit
|
||||
from ui.styles import build_stylesheet
|
||||
|
||||
@@ -63,15 +66,6 @@ logging.basicConfig(
|
||||
)
|
||||
|
||||
|
||||
STATE_FILE: Final[Path] = (
|
||||
APP_DIR / "sticky_state.json"
|
||||
)
|
||||
|
||||
MARKDOWN_FILE: Final[Path] = (
|
||||
APP_DIR / "sticky.md"
|
||||
)
|
||||
|
||||
|
||||
class WindowState(Enum):
|
||||
IDLE = auto()
|
||||
DRAGGING = auto()
|
||||
@@ -87,9 +81,8 @@ class ActiveState(Enum):
|
||||
class PersistedState:
|
||||
x: int = 100
|
||||
y: int = 100
|
||||
width: int = 260
|
||||
height: int = 300
|
||||
theme_index: int = 0
|
||||
width: int = 250
|
||||
height: int = 260
|
||||
|
||||
|
||||
class DragHandle(QFrame):
|
||||
@@ -141,15 +134,16 @@ class StickyNoteApp(AcrylicWindow):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self._is_quitting = False
|
||||
self._force_close = False
|
||||
|
||||
self._closing = False
|
||||
|
||||
self.settings_manager = (
|
||||
SettingsManager.load()
|
||||
)
|
||||
|
||||
self.ensure_runtime_files()
|
||||
|
||||
self.profile = (
|
||||
self.settings_manager.profile
|
||||
)
|
||||
@@ -164,6 +158,10 @@ class StickyNoteApp(AcrylicWindow):
|
||||
|
||||
self.drag_offset = QPoint()
|
||||
|
||||
self.drag_origin = QPoint()
|
||||
|
||||
self.pending_drag = False
|
||||
|
||||
self.last_saved_hash = ""
|
||||
|
||||
self.last_preview_hash = ""
|
||||
@@ -172,12 +170,17 @@ class StickyNoteApp(AcrylicWindow):
|
||||
|
||||
self.configure_font()
|
||||
|
||||
self.build_ui()
|
||||
|
||||
self.setup_timers()
|
||||
|
||||
self.build_ui()
|
||||
|
||||
self.configure_window()
|
||||
|
||||
QTimer.singleShot(
|
||||
80,
|
||||
self.restore_state,
|
||||
)
|
||||
|
||||
QTimer.singleShot(
|
||||
120,
|
||||
self.initialize_effects,
|
||||
@@ -188,11 +191,6 @@ class StickyNoteApp(AcrylicWindow):
|
||||
self.build_tray,
|
||||
)
|
||||
|
||||
QTimer.singleShot(
|
||||
80,
|
||||
self.restore_state,
|
||||
)
|
||||
|
||||
QTimer.singleShot(
|
||||
260,
|
||||
self.apply_style,
|
||||
@@ -205,6 +203,34 @@ class StickyNoteApp(AcrylicWindow):
|
||||
|
||||
self.register_shutdown_hooks()
|
||||
|
||||
def ensure_runtime_files(self) -> None:
|
||||
APP_DIR.mkdir(
|
||||
parents=True,
|
||||
exist_ok=True,
|
||||
)
|
||||
|
||||
if not SETTINGS_FILE.exists():
|
||||
self.settings_manager.save()
|
||||
|
||||
if not MARKDOWN_FILE.exists():
|
||||
atomic_write(
|
||||
MARKDOWN_FILE,
|
||||
"",
|
||||
)
|
||||
|
||||
if not STATE_FILE.exists():
|
||||
atomic_write(
|
||||
STATE_FILE,
|
||||
json.dumps(
|
||||
{
|
||||
"x": 100,
|
||||
"y": 100,
|
||||
"width": 250,
|
||||
"height": 260,
|
||||
},
|
||||
indent=2,
|
||||
),
|
||||
)
|
||||
|
||||
def configure_font(self) -> None:
|
||||
self.font_object = QFont()
|
||||
@@ -253,6 +279,16 @@ class StickyNoteApp(AcrylicWindow):
|
||||
self.show_preview
|
||||
)
|
||||
|
||||
self.drag_timer = QTimer(self)
|
||||
|
||||
self.drag_timer.setSingleShot(
|
||||
True
|
||||
)
|
||||
|
||||
self.drag_timer.timeout.connect(
|
||||
self.activate_delayed_drag
|
||||
)
|
||||
|
||||
self.opacity_anim = (
|
||||
QPropertyAnimation(
|
||||
self,
|
||||
@@ -270,7 +306,6 @@ class StickyNoteApp(AcrylicWindow):
|
||||
QEasingCurve.Type.OutCubic
|
||||
)
|
||||
|
||||
# v1.0.1 configure_window.py
|
||||
def configure_window(self) -> None:
|
||||
window = self.profile["window"]
|
||||
|
||||
@@ -289,6 +324,11 @@ class StickyNoteApp(AcrylicWindow):
|
||||
True,
|
||||
)
|
||||
|
||||
self.setWindowFlag(
|
||||
Qt.WindowType.FramelessWindowHint,
|
||||
True,
|
||||
)
|
||||
|
||||
self.setAttribute(
|
||||
Qt.WidgetAttribute.WA_TranslucentBackground,
|
||||
True,
|
||||
@@ -298,19 +338,11 @@ class StickyNoteApp(AcrylicWindow):
|
||||
Qt.WidgetAttribute.WA_NoSystemBackground,
|
||||
True,
|
||||
)
|
||||
self.setWindowFlag(
|
||||
Qt.WindowType.WindowCloseButtonHint,
|
||||
False,
|
||||
)
|
||||
|
||||
self.setAutoFillBackground(
|
||||
False
|
||||
)
|
||||
|
||||
QTimer.singleShot(
|
||||
120,
|
||||
self.initialize_effects,
|
||||
)
|
||||
|
||||
def build_ui(self) -> None:
|
||||
self.root = QWidget(self)
|
||||
|
||||
@@ -318,48 +350,34 @@ class StickyNoteApp(AcrylicWindow):
|
||||
"container"
|
||||
)
|
||||
|
||||
self.root.setGeometry(
|
||||
self.rect()
|
||||
)
|
||||
|
||||
self.layout = QVBoxLayout(
|
||||
self.root
|
||||
)
|
||||
|
||||
window = self.profile["window"]
|
||||
|
||||
margin = window[
|
||||
"layout_margin"
|
||||
]
|
||||
|
||||
self.layout.setContentsMargins(
|
||||
margin,
|
||||
margin,
|
||||
margin,
|
||||
margin,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
)
|
||||
|
||||
self.layout.setSpacing(
|
||||
window["layout_spacing"]
|
||||
)
|
||||
self.layout.setSpacing(0)
|
||||
|
||||
self.titleBar.hide()
|
||||
|
||||
self.titleBar.setFixedHeight(0)
|
||||
|
||||
self.drag_handle = DragHandle(
|
||||
self.root
|
||||
)
|
||||
|
||||
self.drag_handle.setFixedHeight(
|
||||
window[
|
||||
"drag_handle_height"
|
||||
]
|
||||
)
|
||||
self.drag_handle.hide()
|
||||
|
||||
self.drag_handle.drag_started.connect(
|
||||
self.start_drag
|
||||
)
|
||||
|
||||
self.drag_handle.drag_moved.connect(
|
||||
self.perform_drag
|
||||
)
|
||||
|
||||
self.drag_handle.drag_finished.connect(
|
||||
self.finish_drag
|
||||
)
|
||||
self.drag_handle.setFixedHeight(0)
|
||||
|
||||
self.editor = LinkTextEdit(
|
||||
self.root
|
||||
@@ -377,6 +395,37 @@ class StickyNoteApp(AcrylicWindow):
|
||||
0
|
||||
)
|
||||
|
||||
self.editor.setViewportMargins(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
|
||||
self.editor.setAcceptRichText(
|
||||
False
|
||||
)
|
||||
|
||||
self.editor.setMouseTracking(
|
||||
True
|
||||
)
|
||||
|
||||
self.editor.setStyleSheet("""
|
||||
QTextEdit {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QTextEdit > QWidget {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
""")
|
||||
|
||||
self.editor.textChanged.connect(
|
||||
self.queue_save
|
||||
)
|
||||
@@ -406,13 +455,13 @@ class StickyNoteApp(AcrylicWindow):
|
||||
)
|
||||
|
||||
content_layout.setContentsMargins(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
)
|
||||
|
||||
content_layout.setSpacing(0)
|
||||
content_layout.setSpacing(1)
|
||||
|
||||
content_layout.addWidget(
|
||||
self.editor,
|
||||
@@ -428,10 +477,6 @@ class StickyNoteApp(AcrylicWindow):
|
||||
self.root
|
||||
)
|
||||
|
||||
self.layout.addWidget(
|
||||
self.drag_handle
|
||||
)
|
||||
|
||||
self.layout.addWidget(
|
||||
content,
|
||||
1,
|
||||
@@ -444,12 +489,12 @@ class StickyNoteApp(AcrylicWindow):
|
||||
| Qt.AlignmentFlag.AlignRight,
|
||||
)
|
||||
|
||||
self.titleBar.hide()
|
||||
self.editor.setFocus()
|
||||
|
||||
def build_tray(self) -> None:
|
||||
if QSystemTrayIcon.isSystemTrayAvailable() is False:
|
||||
if not QSystemTrayIcon.isSystemTrayAvailable():
|
||||
return
|
||||
|
||||
if not self.profile[
|
||||
"behavior"
|
||||
]["enable_tray"]:
|
||||
@@ -603,6 +648,7 @@ class StickyNoteApp(AcrylicWindow):
|
||||
],
|
||||
)
|
||||
)
|
||||
|
||||
def initialize_effects(self) -> None:
|
||||
appearance = (
|
||||
self.profile["appearance"]
|
||||
@@ -631,16 +677,18 @@ class StickyNoteApp(AcrylicWindow):
|
||||
)
|
||||
|
||||
self.update()
|
||||
|
||||
self.repaint()
|
||||
|
||||
except Exception:
|
||||
logging.exception(
|
||||
"window_effect_failure"
|
||||
)
|
||||
def start_drag(
|
||||
self,
|
||||
global_pos: QPoint,
|
||||
) -> None:
|
||||
|
||||
def activate_delayed_drag(self) -> None:
|
||||
if not self.pending_drag:
|
||||
return
|
||||
|
||||
self.window_state = (
|
||||
WindowState.DRAGGING
|
||||
)
|
||||
@@ -651,27 +699,84 @@ class StickyNoteApp(AcrylicWindow):
|
||||
|
||||
self.apply_style()
|
||||
|
||||
self.drag_offset = (
|
||||
global_pos
|
||||
- self.frameGeometry().topLeft()
|
||||
)
|
||||
|
||||
self.setWindowOpacity(
|
||||
self.profile["appearance"][
|
||||
"opacity_dragging"
|
||||
]
|
||||
)
|
||||
|
||||
def perform_drag(
|
||||
self,
|
||||
global_pos: QPoint,
|
||||
) -> None:
|
||||
target = (
|
||||
global_pos
|
||||
- self.drag_offset
|
||||
def mousePressEvent(self, event) -> None:
|
||||
if (
|
||||
event.button()
|
||||
== Qt.MouseButton.LeftButton
|
||||
):
|
||||
self.pending_drag = True
|
||||
|
||||
self.drag_origin = (
|
||||
event.globalPosition()
|
||||
.toPoint()
|
||||
)
|
||||
|
||||
self.drag_offset = (
|
||||
self.drag_origin
|
||||
- self.frameGeometry().topLeft()
|
||||
)
|
||||
|
||||
if hasattr(
|
||||
self,
|
||||
"drag_timer",
|
||||
):
|
||||
self.drag_timer.start(180)
|
||||
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def mouseMoveEvent(self, event) -> None:
|
||||
if not (
|
||||
event.buttons()
|
||||
& Qt.MouseButton.LeftButton
|
||||
):
|
||||
return
|
||||
|
||||
global_pos = (
|
||||
event.globalPosition()
|
||||
.toPoint()
|
||||
)
|
||||
|
||||
self.move(target)
|
||||
if (
|
||||
self.pending_drag
|
||||
and (
|
||||
global_pos
|
||||
- self.drag_origin
|
||||
).manhattanLength()
|
||||
> 6
|
||||
):
|
||||
if (
|
||||
self.window_state
|
||||
== WindowState.DRAGGING
|
||||
):
|
||||
self.move(
|
||||
global_pos
|
||||
- self.drag_offset
|
||||
)
|
||||
|
||||
super().mouseMoveEvent(event)
|
||||
|
||||
def mouseReleaseEvent(self, event) -> None:
|
||||
if hasattr(
|
||||
self,
|
||||
"drag_timer",
|
||||
):
|
||||
self.drag_timer.stop()
|
||||
|
||||
self.pending_drag = False
|
||||
|
||||
if (
|
||||
self.window_state
|
||||
== WindowState.DRAGGING
|
||||
):
|
||||
self.finish_drag()
|
||||
|
||||
super().mouseReleaseEvent(event)
|
||||
|
||||
def finish_drag(self) -> None:
|
||||
self.window_state = (
|
||||
@@ -690,7 +795,15 @@ class StickyNoteApp(AcrylicWindow):
|
||||
]
|
||||
)
|
||||
|
||||
self.queue_save()
|
||||
|
||||
def queue_save(self) -> None:
|
||||
if not hasattr(
|
||||
self,
|
||||
"save_timer",
|
||||
):
|
||||
return
|
||||
|
||||
self.save_timer.start(
|
||||
self.profile["editor"][
|
||||
"save_debounce_ms"
|
||||
@@ -698,6 +811,12 @@ class StickyNoteApp(AcrylicWindow):
|
||||
)
|
||||
|
||||
def queue_preview(self) -> None:
|
||||
if not hasattr(
|
||||
self,
|
||||
"preview_timer",
|
||||
):
|
||||
return
|
||||
|
||||
if not self.profile[
|
||||
"editor"
|
||||
][
|
||||
@@ -721,9 +840,11 @@ class StickyNoteApp(AcrylicWindow):
|
||||
or not self.isActiveWindow()
|
||||
):
|
||||
return
|
||||
|
||||
self.preview.setFocusPolicy(
|
||||
Qt.FocusPolicy.NoFocus
|
||||
)
|
||||
|
||||
markdown = (
|
||||
self.editor.toPlainText()
|
||||
)
|
||||
@@ -751,49 +872,65 @@ class StickyNoteApp(AcrylicWindow):
|
||||
self.preview.show()
|
||||
|
||||
def save_state(self) -> None:
|
||||
markdown = (
|
||||
self.editor.toPlainText()
|
||||
)
|
||||
|
||||
current_hash = sha256(
|
||||
markdown.encode("utf-8")
|
||||
).hexdigest()
|
||||
|
||||
if current_hash != self.last_saved_hash:
|
||||
MARKDOWN_FILE.write_text(
|
||||
markdown,
|
||||
encoding="utf-8",
|
||||
try:
|
||||
APP_DIR.mkdir(
|
||||
parents=True,
|
||||
exist_ok=True,
|
||||
)
|
||||
|
||||
self.last_saved_hash = (
|
||||
markdown = (
|
||||
self.editor.toPlainText()
|
||||
)
|
||||
|
||||
current_hash = sha256(
|
||||
markdown.encode("utf-8")
|
||||
).hexdigest()
|
||||
|
||||
if (
|
||||
current_hash
|
||||
!= self.last_saved_hash
|
||||
):
|
||||
atomic_write(
|
||||
MARKDOWN_FILE,
|
||||
markdown,
|
||||
)
|
||||
|
||||
self.last_saved_hash = (
|
||||
current_hash
|
||||
)
|
||||
|
||||
atomic_write(
|
||||
STATE_FILE,
|
||||
json.dumps(
|
||||
{
|
||||
"x": self.x(),
|
||||
"y": self.y(),
|
||||
"width": self.width(),
|
||||
"height": self.height(),
|
||||
},
|
||||
indent=2,
|
||||
),
|
||||
)
|
||||
|
||||
STATE_FILE.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"x": self.x(),
|
||||
"y": self.y(),
|
||||
"width": self.width(),
|
||||
"height": self.height(),
|
||||
},
|
||||
indent=2,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
except Exception:
|
||||
logging.exception(
|
||||
"save_state_failure"
|
||||
)
|
||||
|
||||
def restore_state(self) -> None:
|
||||
if MARKDOWN_FILE.exists():
|
||||
self.editor.setPlainText(
|
||||
try:
|
||||
self.ensure_runtime_files()
|
||||
|
||||
markdown = (
|
||||
MARKDOWN_FILE.read_text(
|
||||
encoding="utf-8",
|
||||
)
|
||||
)
|
||||
|
||||
if not STATE_FILE.exists():
|
||||
return
|
||||
self.editor.setPlainText(
|
||||
markdown
|
||||
)
|
||||
|
||||
try:
|
||||
state = json.loads(
|
||||
STATE_FILE.read_text(
|
||||
encoding="utf-8",
|
||||
@@ -801,13 +938,25 @@ class StickyNoteApp(AcrylicWindow):
|
||||
)
|
||||
|
||||
self.resize(
|
||||
state["width"],
|
||||
state["height"],
|
||||
max(
|
||||
state.get(
|
||||
"width",
|
||||
250,
|
||||
),
|
||||
200,
|
||||
),
|
||||
max(
|
||||
state.get(
|
||||
"height",
|
||||
260,
|
||||
),
|
||||
100,
|
||||
),
|
||||
)
|
||||
|
||||
self.move(
|
||||
state["x"],
|
||||
state["y"],
|
||||
state.get("x", 100),
|
||||
state.get("y", 100),
|
||||
)
|
||||
|
||||
self.clamp_to_screen()
|
||||
@@ -867,29 +1016,38 @@ class StickyNoteApp(AcrylicWindow):
|
||||
self.apply_style()
|
||||
|
||||
def open_settings(self) -> None:
|
||||
path = (
|
||||
APP_DIR / "settings.json"
|
||||
SETTINGS_FILE.touch(
|
||||
exist_ok=True
|
||||
)
|
||||
|
||||
path.touch(exist_ok=True)
|
||||
|
||||
try:
|
||||
if os.name == "nt":
|
||||
os.startfile(str(path))
|
||||
os.startfile(
|
||||
str(SETTINGS_FILE)
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
if sys.platform.startswith(
|
||||
"linux"
|
||||
):
|
||||
subprocess.Popen(
|
||||
["xdg-open", str(path)]
|
||||
[
|
||||
"xdg-open",
|
||||
str(SETTINGS_FILE),
|
||||
]
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
if sys.platform == "darwin":
|
||||
subprocess.Popen(
|
||||
["open", str(path)]
|
||||
[
|
||||
"open",
|
||||
str(SETTINGS_FILE),
|
||||
]
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
except Exception:
|
||||
@@ -897,18 +1055,21 @@ class StickyNoteApp(AcrylicWindow):
|
||||
"open_settings_failure"
|
||||
)
|
||||
|
||||
def nativeEvent(self, eventType, message):
|
||||
try:
|
||||
return super().nativeEvent(eventType, message)
|
||||
except KeyboardInterrupt:
|
||||
self.safe_exit()
|
||||
return False, 0
|
||||
except SystemExit:
|
||||
self.safe_exit()
|
||||
return False, 0
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return False, 0
|
||||
def moveEvent(self, event) -> None:
|
||||
super().moveEvent(event)
|
||||
|
||||
if (
|
||||
getattr(
|
||||
self,
|
||||
"startup_ready",
|
||||
False,
|
||||
)
|
||||
and hasattr(
|
||||
self,
|
||||
"save_timer",
|
||||
)
|
||||
):
|
||||
self.queue_save()
|
||||
|
||||
def resizeEvent(self, event) -> None:
|
||||
super().resizeEvent(event)
|
||||
@@ -919,15 +1080,29 @@ class StickyNoteApp(AcrylicWindow):
|
||||
None,
|
||||
)
|
||||
|
||||
if root is None:
|
||||
return
|
||||
if root is not None:
|
||||
geometry = self.rect()
|
||||
|
||||
geometry = self.rect()
|
||||
if (
|
||||
root.geometry()
|
||||
!= geometry
|
||||
):
|
||||
root.setGeometry(
|
||||
geometry
|
||||
)
|
||||
|
||||
if root.geometry() != geometry:
|
||||
root.setGeometry(
|
||||
geometry
|
||||
if (
|
||||
getattr(
|
||||
self,
|
||||
"startup_ready",
|
||||
False,
|
||||
)
|
||||
and hasattr(
|
||||
self,
|
||||
"save_timer",
|
||||
)
|
||||
):
|
||||
self.queue_save()
|
||||
|
||||
def focusInEvent(self, event) -> None:
|
||||
super().focusInEvent(event)
|
||||
@@ -966,16 +1141,21 @@ class StickyNoteApp(AcrylicWindow):
|
||||
)
|
||||
|
||||
def closeEvent(self, event) -> None:
|
||||
if self._is_quitting or self._force_close:
|
||||
if (
|
||||
self._is_quitting
|
||||
or self._force_close
|
||||
):
|
||||
try:
|
||||
self.save_state()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
event.accept()
|
||||
|
||||
return
|
||||
|
||||
event.ignore()
|
||||
|
||||
self.hide()
|
||||
|
||||
def register_shutdown_hooks(self) -> None:
|
||||
@@ -984,11 +1164,20 @@ class StickyNoteApp(AcrylicWindow):
|
||||
def handle_shutdown(*_) -> None:
|
||||
self.safe_exit()
|
||||
|
||||
atexit.register(handle_shutdown)
|
||||
atexit.register(
|
||||
handle_shutdown
|
||||
)
|
||||
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
for sig in (
|
||||
signal.SIGINT,
|
||||
signal.SIGTERM,
|
||||
):
|
||||
try:
|
||||
signal.signal(sig, handle_shutdown)
|
||||
signal.signal(
|
||||
sig,
|
||||
handle_shutdown,
|
||||
)
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1013,24 +1202,38 @@ class StickyNoteApp(AcrylicWindow):
|
||||
traceback.print_exc()
|
||||
|
||||
try:
|
||||
if hasattr(self, "save_timer"):
|
||||
if hasattr(
|
||||
self,
|
||||
"save_timer",
|
||||
):
|
||||
self.save_timer.stop()
|
||||
|
||||
if hasattr(self, "preview_timer"):
|
||||
if hasattr(
|
||||
self,
|
||||
"preview_timer",
|
||||
):
|
||||
self.preview_timer.stop()
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
try:
|
||||
if hasattr(self, "tray"):
|
||||
if hasattr(
|
||||
self,
|
||||
"tray",
|
||||
):
|
||||
self.tray.hide()
|
||||
|
||||
self.tray.deleteLater()
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
try:
|
||||
self.hide()
|
||||
|
||||
self.deleteLater()
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -1040,6 +1243,6 @@ class StickyNoteApp(AcrylicWindow):
|
||||
app.quit()
|
||||
|
||||
try:
|
||||
app.quit()
|
||||
except:
|
||||
sys.exit(0)
|
||||
app.quit()
|
||||
except Exception:
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user