# Sticky Notes A Linux and Windows desktop sticky notes application. No account, cloud service or telemetry. Notes are stored in a local SQLite database. Optional sync keeps notes the same on every computer at home through a sync server you run yourself on your own network; it is off until you turn it on. ## Run Requires Python 3.10 or later. ```sh python -m venv .venv ``` Activate the environment: - Linux: `source .venv/bin/activate` - Windows PowerShell: `.venv\Scripts\Activate.ps1` ```sh python -m pip install -r requirements.txt python main.py ``` ## Features - Independent movable and resizable note windows - Six note colours and optional always on top - Bold, italic, underline, strikethrough and bullet lists - Autosave after 350 ms of inactivity and when closing - Searchable notes list; double-click a note to reopen it - Closing a note retains it in the list; Delete asks for confirmation - Closing the notes list exits the app; only notes left open reopen next launch - Only one copy runs at a time; starting a second copy says it is already running - The notes list shows when each note's text was last changed, in local time - Starting with no saved notes creates one blank note - Backup and restore buttons in the notes list (includes rich text and colours) Data lives in Qt's application-local data folder, generally `~/.local/share/LocalStickyNotes/Local Sticky Notes/` on Linux and beneath `%LOCALAPPDATA%` on Windows. The database is named `notes.sqlite3`. To back up the database directly, exit the app first, then copy it. ## Sync between computers at home Sync needs a Sticky Notes sync server on one computer at home that is usually on. The server comes with Sticky Notes; nothing else needs installing. Notes go only to that server, over an encrypted connection; nothing leaves your home network. 1. On the computer that will be the server, choose **Sync…** > **Use this computer as the sync server**. The server runs in the background, keeps running when Sticky Notes is closed and starts when you sign in. 2. On that computer, choose **Sync…** > **Add another computer** to get a pairing code. Each code works once, for 10 minutes. 3. On each other computer, choose **Sync…**. Servers on your network are found automatically (otherwise type the server's name or address, port 8765). Pick it, enter the code and choose **Connect**. Any computer that already syncs can give pairing codes. **Stop being the sync server** (on the server computer) stops it; the other computers then stop syncing until they pair with another server. Notes sync every minute, when Sticky Notes starts and when it closes. Text, colour and pinning are shared; window positions and which notes are open stay on each computer. Notes made on another computer appear closed in the notes list. Deleting a note deletes it everywhere. If a note was changed on two computers before they synced, both versions are kept: the second appears as a "Conflict copy" in the notes list. The first time a computer pairs, its existing notes are added to the server's. **Disconnect** stops syncing and keeps your notes. Pairing pins the server's identity (its Server ID); if a different server answers at that address later, Sticky Notes refuses to sync until you disconnect and pair again. ### The sync server When Sticky Notes is the server, its data is in a `sync-server` folder beside the notes database. On Windows, the installer's firewall option (ticked by default; it asks for administrator permission once) lets Sticky Notes and its sync server through Windows Firewall on private and domain networks. Without it, allow **Sticky Notes sync server** through Windows Firewall on private networks when asked. On Linux the sign-in entry is `~/.config/autostart/sticky-notes-server.desktop`; uninstalling the package does not remove it, so choose **Stop being the sync server** first. For a machine without a desktop (a home server or VM): - **Linux:** `sudo apt install ./dist/sticky-notes-server_0.3.3_amd64.deb`, then `sudo systemctl enable --now sticky-notes-server` and `sudo sticky-notes-server pair` for a code. It runs as the `sticky-notes` system user and keeps its data in `/var/lib/sticky-notes-server`. - **From source:** `pip install -r requirements-server.txt`, then `python server.py run`. Server commands: `run` (the default; `--port`, `--bind`, `--no-announce`), `stop`, `pair`, `devices` (paired computers and their last sync) and `revoke NAME` (unpair a computer). `--data FOLDER` chooses the data folder. The server announces itself on the local network (mDNS), so open UDP port 5353 as well as TCP port 8765 if a firewall runs on the server. Back up its data folder (`server.sqlite3`, `cert.pem`, `key.pem`); keeping `cert.pem` and `key.pem` lets paired computers trust a restored server. ## Build a standalone app Run on each target operating system: ```sh python -m pip install pyinstaller python -m PyInstaller --noconfirm --windowed --name StickyNotes main.py ``` The application is in `dist/StickyNotes/`. `packaging/build.py` (below) also builds the sync server. Build on Windows for Windows and Linux for Linux. PyQt6 is GPLv3/commercial; review its licensing before proprietary distribution. ## Development verification The sync tests start a real server on 127.0.0.1. ```sh QT_QPA_PLATFORM=offscreen python -m unittest -v ``` Windows PowerShell: set `$env:QT_QPA_PLATFORM='offscreen'` first, then run `python -m unittest -v`. ## Installable packages Packaging scripts bundle Python and Qt, so users do not need to install Python. Notes remain in the user's data folder across upgrades and uninstallation. Exit the application before upgrading. ### Linux Build on the oldest Linux release you intend to support, using Python 3.10+: ```sh python3 -m venv .venv-build .venv-build/bin/python -m pip install -r requirements-build.txt .venv-build/bin/python packaging/build.py --deb ``` Omit `--deb` if you only want the portable archive. Outputs in `dist/`: - `local-sticky-notes_0.3.3_amd64.deb`: Debian/Ubuntu package. Install with `sudo apt install ./dist/local-sticky-notes_0.3.3_amd64.deb`, then open **Sticky Notes** in your applications menu. Uninstall with `sudo apt remove local-sticky-notes`. - `sticky-notes-server_0.3.3_amd64.deb`: the sync server on its own, for a machine without a desktop, installed stopped (see Sync above). Removing it keeps `/var/lib/sticky-notes-server`. - `local-sticky-notes-0.3.3-linux-x86_64.tar.gz`: extract, then run `./StickyNotes/install.sh` for a per-user installation without sudo. It installs to `~/.local/opt/local-sticky-notes` and adds an applications-menu entry. To uninstall, remove that directory and `${XDG_DATA_HOME:-~/.local/share}/applications/local-sticky-notes.desktop`. You can also run `StickyNotes/StickyNotes` directly after extracting. Architecture names vary with the build machine. These binaries still require system graphics libraries and a compatible glibc. The first local build was made on **Ubuntu 26.04 x86_64 (glibc 2.43)**; it is intended for that environment, and has not been validated on other distributions or older releases. Use a matching older build environment for broader Linux compatibility. ### Windows On Windows, install Python 3.10+ and [Inno Setup 6](https://jrsoftware.org/isinfo.php), then run from the project directory: ```powershell py -m venv .venv-build .\.venv-build\Scripts\python.exe -m pip install -r requirements-build.txt .\.venv-build\Scripts\python.exe packaging/build.py & "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" packaging\windows\installer.iss ``` The installer is `dist/StickyNotes-0.3.3-Setup.exe`. It installs for the current user without requiring administrator rights, adds a Start menu shortcut, offers an optional desktop shortcut, includes the sync server, and supports removal through Windows Settings. Its firewall option adds two inbound rules, **Sticky Notes** and **Sticky Notes sync server** (private and domain networks), through one administrator prompt; uninstalling removes them. The initial installer is unsigned. Windows packaging is provided but has not been built or tested on this Linux machine. PyInstaller builds must run on their target operating system, or under Wine for Windows. Under Wine use PyQt6 6.9 (`pip install "PyQt6==6.9.*" "PyQt6-Qt6==6.9.*"`): Qt 6.10 and later need the ICU library built into Windows 10, which Wine lacks. Publish the source archive (`git archive`) beside the packages, as the GPL requires. Version 0.3.2 keeps the original application data and installation directories for compatibility with existing installations. Its displayed name is Sticky Notes. New note opens a colour chooser; cancelling creates nothing. The initial blank note uses yellow. If all saved notes were closed, startup shows just the notes list. Version 0.2.2 shows note times in local time, only updates a note's time when its text changes, frees closed note windows and runs only one copy at a time. Version 0.3.0 adds optional sync through a sync server on your home network. Version 0.3.1 lets any computer running Sticky Notes be that server. Version 0.3.2 fixes Windows letting two sync servers share one port, and a 10-second wait when stopping the server on Linux; it adds the GPL licence. Version 0.3.3 finds sync servers more reliably: it asks from a port of its own, so the server answers straight back (before, a Windows laptop could miss the answer and need the address typed in). The Windows installer can add the firewall rules. ## Licence Sticky Notes is free software under the GNU General Public License, version 3 or later. Copyright (C) 2026 Michael Slater. See COPYING and NOTICE.txt. Use **Backup…** in the notes list to save all notes (including closed notes) to a JSON file. Use **Restore…** to add copies from a backup without replacing existing notes. Restoring the same backup again adds another set of copies. Backups include formatting, colours, pinning, window positions, and open/closed state. Original JSON exports are also accepted. The application uses its own sticky-note icon on Linux and Windows. The per-user Linux installer also installs `icons/hicolor/256x256/apps/sticky-notes.png` beneath the XDG data folder; remove it when manually uninstalling.