Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa5dadc302 | ||
|
|
7d67d4a74d | ||
|
|
d129c70c10 | ||
|
|
f962dd393e | ||
|
|
573c08a07c | ||
|
|
5270ef92c1 | ||
|
|
8c7b9fe521 | ||
|
|
599efb060e | ||
|
|
781283e628 | ||
|
|
214531fc8e |
11
README.md
11
README.md
@@ -1,3 +1,10 @@
|
|||||||
# overlaynote
|
## overlaynote
|
||||||
|
minimal note overlay
|
||||||
|
v1.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*v1* <br>
|
||||||
|
<a href="https://git.backend-3.com/admin/overlaynote/releases">download</a>
|
||||||
|
|
||||||
|
|
||||||
minimal note overlay
|
|
||||||
@@ -44,7 +44,7 @@ THEMES: Final[list[ThemePalette]] = [
|
|||||||
),
|
),
|
||||||
ThemePalette(
|
ThemePalette(
|
||||||
name="yellow",
|
name="yellow",
|
||||||
background="rgba(113,63,18,0.24)",
|
background="rgba(113,93,38,0.24)",
|
||||||
background_inactive="rgba(113,63,18,0.16)",
|
background_inactive="rgba(113,63,18,0.16)",
|
||||||
border_active="rgba(250,204,21,0.36)",
|
border_active="rgba(250,204,21,0.36)",
|
||||||
border_inactive="rgba(255,255,255,0.10)",
|
border_inactive="rgba(255,255,255,0.10)",
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ DEFAULT_SETTINGS: Final[dict] = {
|
|||||||
"enable_glass_blur": True,
|
"enable_glass_blur": True,
|
||||||
"enable_animations": True,
|
"enable_animations": True,
|
||||||
"enable_shadow": True,
|
"enable_shadow": True,
|
||||||
"opacity_active": 1.0,
|
"opacity_active": 0.99,
|
||||||
"opacity_inactive": 0.96,
|
"opacity_inactive": 0.95,
|
||||||
"opacity_dragging": 0.92,
|
"opacity_dragging": 0.98,
|
||||||
"focus_animation_ms": 180,
|
"focus_animation_ms": 180,
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
@@ -50,7 +50,7 @@ DEFAULT_SETTINGS: Final[dict] = {
|
|||||||
"Arial",
|
"Arial",
|
||||||
"system-ui",
|
"system-ui",
|
||||||
],
|
],
|
||||||
"font_size": 13,
|
"font_size": 15,
|
||||||
"preview_delay_ms": 700,
|
"preview_delay_ms": 700,
|
||||||
"save_debounce_ms": 500,
|
"save_debounce_ms": 500,
|
||||||
"max_note_size": 2_000_000,
|
"max_note_size": 2_000_000,
|
||||||
@@ -83,14 +83,14 @@ DEFAULT_SETTINGS: Final[dict] = {
|
|||||||
"startup_stabilize_ms": 80,
|
"startup_stabilize_ms": 80,
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"enable_mica": False,
|
"enable_mica": True,
|
||||||
"enable_acrylic": False,
|
"enable_acrylic": True,
|
||||||
"enable_glass_blur": False,
|
"enable_glass_blur": True,
|
||||||
"enable_animations": True,
|
"enable_animations": True,
|
||||||
"enable_shadow": False,
|
"enable_shadow": False,
|
||||||
"opacity_active": 1.0,
|
"opacity_active": 0.99,
|
||||||
"opacity_inactive": 0.98,
|
"opacity_inactive": 0.95,
|
||||||
"opacity_dragging": 0.96,
|
"opacity_dragging": 0.98,
|
||||||
"focus_animation_ms": 120,
|
"focus_animation_ms": 120,
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
@@ -133,13 +133,13 @@ DEFAULT_SETTINGS: Final[dict] = {
|
|||||||
"startup_stabilize_ms": 80,
|
"startup_stabilize_ms": 80,
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"enable_mica": False,
|
"enable_mica": True,
|
||||||
"enable_acrylic": False,
|
"enable_acrylic": True,
|
||||||
"enable_glass_blur": False,
|
"enable_glass_blur": True,
|
||||||
"enable_animations": False,
|
"enable_animations": False,
|
||||||
"enable_shadow": False,
|
"enable_shadow": True,
|
||||||
"opacity_active": 1.0,
|
"opacity_active": 0.92,
|
||||||
"opacity_inactive": 1.0,
|
"opacity_inactive": 0.98,
|
||||||
"opacity_dragging": 1.0,
|
"opacity_dragging": 1.0,
|
||||||
"focus_animation_ms": 0,
|
"focus_animation_ms": 0,
|
||||||
},
|
},
|
||||||
@@ -158,7 +158,7 @@ DEFAULT_SETTINGS: Final[dict] = {
|
|||||||
"enable_clickable_links": True,
|
"enable_clickable_links": True,
|
||||||
"enable_antialiasing": True,
|
"enable_antialiasing": True,
|
||||||
"enable_spellcheck": False,
|
"enable_spellcheck": False,
|
||||||
"padding": 10,
|
"padding": 6,
|
||||||
},
|
},
|
||||||
"behavior": {
|
"behavior": {
|
||||||
"enable_tray": True,
|
"enable_tray": True,
|
||||||
|
|||||||
241
core/app.py
241
core/app.py
@@ -1,4 +1,7 @@
|
|||||||
# v3.1.0 app.py
|
# v3.1.0 app.py
|
||||||
|
import atexit
|
||||||
|
import signal
|
||||||
|
import traceback
|
||||||
import contextlib
|
import contextlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@@ -33,6 +36,7 @@ from PyQt6.QtGui import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
|
QApplication,
|
||||||
QFrame,
|
QFrame,
|
||||||
QMenu,
|
QMenu,
|
||||||
QSizeGrip,
|
QSizeGrip,
|
||||||
@@ -137,6 +141,8 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self._is_quitting = False
|
||||||
|
self._force_close = False
|
||||||
|
|
||||||
self._closing = False
|
self._closing = False
|
||||||
|
|
||||||
@@ -172,19 +178,34 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
|
|
||||||
self.configure_window()
|
self.configure_window()
|
||||||
|
|
||||||
self.build_tray()
|
QTimer.singleShot(
|
||||||
|
120,
|
||||||
self.restore_state()
|
self.initialize_effects,
|
||||||
|
)
|
||||||
self.apply_style()
|
|
||||||
|
|
||||||
QTimer.singleShot(
|
QTimer.singleShot(
|
||||||
self.profile["window"][
|
220,
|
||||||
"startup_stabilize_ms"
|
self.build_tray,
|
||||||
],
|
)
|
||||||
|
|
||||||
|
QTimer.singleShot(
|
||||||
|
80,
|
||||||
|
self.restore_state,
|
||||||
|
)
|
||||||
|
|
||||||
|
QTimer.singleShot(
|
||||||
|
260,
|
||||||
|
self.apply_style,
|
||||||
|
)
|
||||||
|
|
||||||
|
QTimer.singleShot(
|
||||||
|
320,
|
||||||
self.finalize_startup,
|
self.finalize_startup,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.register_shutdown_hooks()
|
||||||
|
|
||||||
|
|
||||||
def configure_font(self) -> None:
|
def configure_font(self) -> None:
|
||||||
self.font_object = QFont()
|
self.font_object = QFont()
|
||||||
|
|
||||||
@@ -249,6 +270,7 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
QEasingCurve.Type.OutCubic
|
QEasingCurve.Type.OutCubic
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# v1.0.1 configure_window.py
|
||||||
def configure_window(self) -> None:
|
def configure_window(self) -> None:
|
||||||
window = self.profile["window"]
|
window = self.profile["window"]
|
||||||
|
|
||||||
@@ -262,10 +284,9 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
window["min_height"],
|
window["min_height"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setWindowFlags(
|
self.setWindowFlag(
|
||||||
Qt.WindowType.Tool
|
Qt.WindowType.WindowStaysOnTopHint,
|
||||||
| Qt.WindowType.WindowStaysOnTopHint
|
True,
|
||||||
| Qt.WindowType.FramelessWindowHint
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setAttribute(
|
self.setAttribute(
|
||||||
@@ -273,33 +294,22 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.setAutoFillBackground(False)
|
self.setAttribute(
|
||||||
|
Qt.WidgetAttribute.WA_NoSystemBackground,
|
||||||
appearance = (
|
True,
|
||||||
self.profile["appearance"]
|
)
|
||||||
|
self.setWindowFlag(
|
||||||
|
Qt.WindowType.WindowCloseButtonHint,
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
self.setAutoFillBackground(
|
||||||
|
False
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
QTimer.singleShot(
|
||||||
if appearance[
|
120,
|
||||||
"enable_mica"
|
self.initialize_effects,
|
||||||
]:
|
)
|
||||||
self.windowEffect.setMicaEffect(
|
|
||||||
self.winId(),
|
|
||||||
True,
|
|
||||||
)
|
|
||||||
|
|
||||||
elif appearance[
|
|
||||||
"enable_acrylic"
|
|
||||||
]:
|
|
||||||
self.windowEffect.setAcrylicEffect(
|
|
||||||
self.winId(),
|
|
||||||
"00000001",
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
logging.exception(
|
|
||||||
"window_effect_failure"
|
|
||||||
)
|
|
||||||
|
|
||||||
def build_ui(self) -> None:
|
def build_ui(self) -> None:
|
||||||
self.root = QWidget(self)
|
self.root = QWidget(self)
|
||||||
@@ -311,7 +321,7 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
self.layout = QVBoxLayout(
|
self.layout = QVBoxLayout(
|
||||||
self.root
|
self.root
|
||||||
)
|
)
|
||||||
|
|
||||||
window = self.profile["window"]
|
window = self.profile["window"]
|
||||||
|
|
||||||
margin = window[
|
margin = window[
|
||||||
@@ -434,7 +444,12 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
| Qt.AlignmentFlag.AlignRight,
|
| Qt.AlignmentFlag.AlignRight,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.titleBar.hide()
|
||||||
|
self.editor.setFocus()
|
||||||
|
|
||||||
def build_tray(self) -> None:
|
def build_tray(self) -> None:
|
||||||
|
if QSystemTrayIcon.isSystemTrayAvailable() is False:
|
||||||
|
return
|
||||||
if not self.profile[
|
if not self.profile[
|
||||||
"behavior"
|
"behavior"
|
||||||
]["enable_tray"]:
|
]["enable_tray"]:
|
||||||
@@ -474,7 +489,7 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
quit_action.triggered.connect(
|
quit_action.triggered.connect(
|
||||||
self.close
|
self.safe_exit
|
||||||
)
|
)
|
||||||
|
|
||||||
menu.addAction(open_settings)
|
menu.addAction(open_settings)
|
||||||
@@ -588,7 +603,40 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
def initialize_effects(self) -> None:
|
||||||
|
appearance = (
|
||||||
|
self.profile["appearance"]
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
hwnd = int(self.winId())
|
||||||
|
|
||||||
|
if not hwnd:
|
||||||
|
return
|
||||||
|
|
||||||
|
if appearance[
|
||||||
|
"enable_mica"
|
||||||
|
]:
|
||||||
|
self.windowEffect.setMicaEffect(
|
||||||
|
hwnd,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
|
||||||
|
elif appearance[
|
||||||
|
"enable_acrylic"
|
||||||
|
]:
|
||||||
|
self.windowEffect.setAcrylicEffect(
|
||||||
|
hwnd,
|
||||||
|
"00000001",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
self.repaint()
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
logging.exception(
|
||||||
|
"window_effect_failure"
|
||||||
|
)
|
||||||
def start_drag(
|
def start_drag(
|
||||||
self,
|
self,
|
||||||
global_pos: QPoint,
|
global_pos: QPoint,
|
||||||
@@ -668,9 +716,14 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def show_preview(self) -> None:
|
def show_preview(self) -> None:
|
||||||
if self.editor.hasFocus():
|
if (
|
||||||
|
self.editor.hasFocus()
|
||||||
|
or not self.isActiveWindow()
|
||||||
|
):
|
||||||
return
|
return
|
||||||
|
self.preview.setFocusPolicy(
|
||||||
|
Qt.FocusPolicy.NoFocus
|
||||||
|
)
|
||||||
markdown = (
|
markdown = (
|
||||||
self.editor.toPlainText()
|
self.editor.toPlainText()
|
||||||
)
|
)
|
||||||
@@ -844,25 +897,17 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
"open_settings_failure"
|
"open_settings_failure"
|
||||||
)
|
)
|
||||||
|
|
||||||
def nativeEvent(
|
def nativeEvent(self, eventType, message):
|
||||||
self,
|
|
||||||
eventType,
|
|
||||||
message,
|
|
||||||
):
|
|
||||||
if getattr(
|
|
||||||
self,
|
|
||||||
"_closing",
|
|
||||||
False,
|
|
||||||
):
|
|
||||||
return False, 0
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return super().nativeEvent(
|
return super().nativeEvent(eventType, message)
|
||||||
eventType,
|
except KeyboardInterrupt:
|
||||||
message,
|
self.safe_exit()
|
||||||
)
|
return False, 0
|
||||||
|
except SystemExit:
|
||||||
|
self.safe_exit()
|
||||||
|
return False, 0
|
||||||
except Exception:
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
return False, 0
|
return False, 0
|
||||||
|
|
||||||
def resizeEvent(self, event) -> None:
|
def resizeEvent(self, event) -> None:
|
||||||
@@ -921,22 +966,80 @@ class StickyNoteApp(AcrylicWindow):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def closeEvent(self, event) -> None:
|
def closeEvent(self, event) -> None:
|
||||||
self._closing = True
|
if self._is_quitting or self._force_close:
|
||||||
|
try:
|
||||||
|
self.save_state()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
with contextlib.suppress(Exception):
|
event.accept()
|
||||||
|
return
|
||||||
|
|
||||||
|
event.ignore()
|
||||||
|
self.hide()
|
||||||
|
|
||||||
|
def register_shutdown_hooks(self) -> None:
|
||||||
|
app = QApplication.instance()
|
||||||
|
|
||||||
|
def handle_shutdown(*_) -> None:
|
||||||
|
self.safe_exit()
|
||||||
|
|
||||||
|
atexit.register(handle_shutdown)
|
||||||
|
|
||||||
|
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||||
|
try:
|
||||||
|
signal.signal(sig, handle_shutdown)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if app is not None:
|
||||||
|
app.aboutToQuit.connect(
|
||||||
|
lambda: setattr(
|
||||||
|
self,
|
||||||
|
"_is_quitting",
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def safe_exit(self) -> None:
|
||||||
|
if self._is_quitting:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._is_quitting = True
|
||||||
|
|
||||||
|
try:
|
||||||
self.save_state()
|
self.save_state()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
with contextlib.suppress(Exception):
|
try:
|
||||||
self.save_timer.stop()
|
if hasattr(self, "save_timer"):
|
||||||
|
self.save_timer.stop()
|
||||||
|
|
||||||
with contextlib.suppress(Exception):
|
if hasattr(self, "preview_timer"):
|
||||||
self.preview_timer.stop()
|
self.preview_timer.stop()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
with contextlib.suppress(Exception):
|
try:
|
||||||
self.opacity_anim.stop()
|
|
||||||
|
|
||||||
with contextlib.suppress(Exception):
|
|
||||||
if hasattr(self, "tray"):
|
if hasattr(self, "tray"):
|
||||||
self.tray.hide()
|
self.tray.hide()
|
||||||
|
self.tray.deleteLater()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
super().closeEvent(event)
|
try:
|
||||||
|
self.hide()
|
||||||
|
self.deleteLater()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
app = QApplication.instance()
|
||||||
|
|
||||||
|
if app is not None:
|
||||||
|
app.quit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
app.quit()
|
||||||
|
except:
|
||||||
|
sys.exit(0)
|
||||||
55
start.py
55
start.py
@@ -1,36 +1,51 @@
|
|||||||
|
# v1.0.3 start.py
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
|
os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
|
||||||
|
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
|
||||||
|
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from PyQt6.QtCore import Qt
|
||||||
|
from PyQt6.QtGui import QGuiApplication
|
||||||
from PyQt6.QtWidgets import QApplication
|
from PyQt6.QtWidgets import QApplication
|
||||||
|
|
||||||
from core.app import StickyNoteApp
|
from core.app import StickyNoteApp
|
||||||
|
|
||||||
|
|
||||||
|
QGuiApplication.setHighDpiScaleFactorRoundingPolicy(
|
||||||
|
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1"
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
|
|
||||||
QApplication.setQuitOnLastWindowClosed(False)
|
app = QApplication(sys.argv)
|
||||||
|
|
||||||
app = QApplication.instance()
|
|
||||||
if app is None:
|
|
||||||
app = QApplication(sys.argv)
|
|
||||||
|
|
||||||
app.setQuitLockEnabled(False)
|
|
||||||
|
|
||||||
existing = getattr(app, "_sticky_note_instance", None)
|
|
||||||
if existing is not None:
|
|
||||||
existing.raise_()
|
|
||||||
existing.activateWindow()
|
|
||||||
return 0
|
|
||||||
|
|
||||||
window = StickyNoteApp()
|
window = StickyNoteApp()
|
||||||
|
|
||||||
app._sticky_note_instance = window
|
|
||||||
|
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
return app.exec()
|
try:
|
||||||
|
return app.exec()
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
try:
|
||||||
|
window.safe_exit()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
except SystemExit:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
raise SystemExit(main())
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user