Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 42 additions & 54 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,79 +160,69 @@ jobs:
name: appimage-x86_64
path: clipse-gui-v${{ needs.generate-changelog.outputs.version }}-linux-x86_64.AppImage

build-linux-arm64:
update-aur:
runs-on: ubuntu-latest
needs: generate-changelog
steps:
- uses: actions/checkout@v4
- name: Checkout AUR repo
uses: actions/checkout@v4
with:
repository: d7omdev/clipse-gui
path: aur
token: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/setup-qemu-action@v3
- name: Setup SSH for AUR
uses: webfactory/ssh-agent@v0.9.0
with:
platforms: arm64
ssh-private-key: ${{ secrets.AUR_SSH_KEY }}

- name: Build in ARM64 container
- name: Clone AUR package
run: |
set -e
docker run --rm --platform linux/arm64 \
-v ${{ github.workspace }}:/workspace \
-w /workspace arm64v8/ubuntu:22.04 bash -c "
set -e
apt-get update &&
apt-get install -y python3 python3-pip python3-venv python3-dev \
python3-gi python3-gi-cairo gir1.2-gtk-3.0 \
libgirepository1.0-dev build-essential \
libssl-dev zlib1g-dev patchelf libcairo2-dev pkg-config &&
python3 -m venv --system-site-packages venv &&
. venv/bin/activate &&
pip install -U pip Nuitka==2.6.9 ordered-set==4.1.0 zstandard==0.23.0 &&
make nuitka &&
mv dist/clipse-gui.bin \
dist/clipse-gui-v${{ needs.generate-changelog.outputs.version }}-linux-aarch64 &&
chmod +x dist/*
"
git clone ssh://aur@aur.archlinux.org/clipse-gui.git aur-package

- uses: actions/upload-artifact@v4
with:
name: linux-arm64
path: dist/clipse-gui-v${{ needs.generate-changelog.outputs.version }}-linux-aarch64
- name: Update AUR package version
run: |
VERSION="${{ needs.generate-changelog.outputs.version }}"
cd aur-package

build-macos:
needs: generate-changelog
runs-on: macos-15
steps:
- uses: actions/checkout@v4
# Update PKGBUILD version
sed -i "s/pkgver=.*/pkgver=$VERSION/" PKGBUILD

- uses: actions/setup-python@v5
with:
python-version: "3.11"
# Update .SRCINFO version
sed -i "s/pkgver = .*/pkgver = $VERSION/" .SRCINFO

- name: Install deps
run: brew install gtk+3 pygobject3 cairo
# Show changes
echo "Updated PKGBUILD:"
grep "pkgver=" PKGBUILD
echo ""
echo "Updated .SRCINFO:"
grep "pkgver =" .SRCINFO

- name: Build
- name: Build and verify AUR package
run: |
set -e
python -m pip install pyinstaller pillow
python -m PyInstaller --onefile \
--name clipse-gui-v${{ needs.generate-changelog.outputs.version }}-macos-arm64 \
--hidden-import=gi \
--collect-all gi \
clipse-gui.py
chmod +x dist/*
cd aur-package
# Validate PKGBUILD
makepkg --printsrcinfo > .SRCINFO

- uses: actions/upload-artifact@v4
with:
name: macos-arm64
path: dist/clipse-gui-v${{ needs.generate-changelog.outputs.version }}-macos-arm64
- name: Commit and push to AUR
run: |
VERSION="${{ needs.generate-changelog.outputs.version }}"
cd aur-package

git config user.name "GitHub Actions"
git config user.email "actions@github.com"

git add PKGBUILD .SRCINFO
git commit -m "Update to v$VERSION"
git push origin master

create-release:
runs-on: ubuntu-latest
needs:
- generate-changelog
- build-linux-x86_64
- build-linux-arm64
- build-macos
- build-appimage
- update-aur

steps:
- uses: actions/download-artifact@v4
Expand All @@ -246,6 +236,4 @@ jobs:
body: ${{ needs.generate-changelog.outputs.release_body }}
files: |
artifacts/linux-x86_64/*
artifacts/linux-arm64/*
artifacts/macos-arm64/*
artifacts/appimage-x86_64/*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,4 @@ node_modules/
# tasks.json
# tasks/
.taskmaster/
aur/
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ lint:
ruff check . && pyright; \
fi

lint-fix:
@echo "Running linting and type checking..."
@if [ -d "venv" ]; then \
echo "Activating virtual environment..."; \
. venv/bin/activate && ruff check . --fix && pyright; \
else \
echo "No virtual environment found, running directly..."; \
ruff check . --fix && pyright; \
fi


watch:
@echo "Starting Clipse GUI in watch mode..."
watchmedo auto-restart --directory=. --pattern="*.py" --recursive -- \
Expand All @@ -71,7 +82,7 @@ nuitka:
@echo "Building standalone app using Nuitka..."
$(PYTHON) -m nuitka $(NUITKA_OPTS) $(APP_SCRIPT)

install: nuitka
install:
@echo "Installing $(APP_NAME)..."
@sudo install -Dm755 "$(BUILD_DIR)/$(NUITKA_BINARY)" "$(BIN_DIR)/$(APP_NAME)"

Expand All @@ -89,7 +100,7 @@ install: nuitka
@mkdir -p "$(DESKTOP_DEST_DIR)"
@printf "%s\n" \
"[Desktop Entry]" \
"Version=0.5.0" \
"Version=0.6.0" \
"Type=Application" \
"Name=Clipse GUI" \
"GenericName=Clipboard Manager" \
Expand Down
12 changes: 12 additions & 0 deletions bump_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ def update_makefile(new_version):
print(f"Updated Makefile desktop entry to version {new_version}")


def update_justfile(new_version):
"""Update version in justfile desktop entry generation"""
justfile = Path("justfile")
if not justfile.exists():
print("Warning: justfile not found, skipping justfile version update")
return

# The justfile dynamically reads from __init__.py, so it should auto-update
print("justfile reads version dynamically from source (no update needed)")


def interactive_bump():
"""Interactive version bump with user selection"""
current_version = get_current_version()
Expand Down Expand Up @@ -149,6 +160,7 @@ def main():
# Update files
update_init_file(new_version)
update_makefile(new_version)
update_justfile(new_version)

print(f"Version successfully bumped to {new_version}")
print("Don't forget to commit the changes!")
Expand Down
2 changes: 1 addition & 1 deletion clipse_gui/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.5.0"
__version__ = "0.6.0"
21 changes: 16 additions & 5 deletions clipse_gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ClipseGuiApplication(Gtk.Application):

def __init__(self):
super().__init__(
application_id=APPLICATION_ID, flags=Gio.ApplicationFlags.FLAGS_NONE
application_id=APPLICATION_ID, flags=Gio.ApplicationFlags.DEFAULT_FLAGS
)
self.window = None
self.controller = None
Expand Down Expand Up @@ -58,10 +58,10 @@ def do_activate(self):
self.window.set_icon_name("edit-copy")
except GLib.Error as e:
log.warning(f"Could not set window icon name: {e}")

# Setup tray manager
self.tray_manager = TrayManager(self)

# Connect window events for tray functionality
self.window.connect("delete-event", self._on_window_delete)

Expand Down Expand Up @@ -91,7 +91,18 @@ def do_activate(self):
log.debug("Main window created and shown.")
else:
log.debug("Application already active - presenting existing window.")
self.window.present()
self._restore_window_from_tray()

def _restore_window_from_tray(self):
"""Restore and show the window, even if minimized to tray."""
if self.window:
# Restore from tray if minimized there
if self.tray_manager:
self.tray_manager._restore_window()
else:
# Fallback if no tray manager
self.window.present()
self.window.show_all()

def do_shutdown(self):
"""Called when the application is shutting down."""
Expand All @@ -110,7 +121,7 @@ def do_shutdown(self):
# Cleanup tray resources
if self.tray_manager:
self.tray_manager.cleanup()

Gtk.Application.do_shutdown(self)

def _on_window_delete(self, window, event):
Expand Down
24 changes: 24 additions & 0 deletions clipse_gui/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
"search_debounce_ms": "250",
"paste_simulation_delay_ms": "150",
"minimize_to_tray": "True",
"tray_items_count": "20",
"tray_paste_on_select": "True",
},
"Commands": {
"copy_tool_cmd": "wl-copy",
Expand Down Expand Up @@ -78,6 +80,10 @@
"General", "paste_simulation_delay_ms", fallback=150
)
MINIMIZE_TO_TRAY = config.getboolean("General", "minimize_to_tray", fallback=True)
TRAY_ITEMS_COUNT = config.getint("General", "tray_items_count", fallback=20)
TRAY_PASTE_ON_SELECT = config.getboolean(
"General", "tray_paste_on_select", fallback=True
)

COPY_TOOL_CMD = config.get("Commands", "copy_tool_cmd", fallback="wl-copy")
X11_COPY_TOOL_CMD = config.get(
Expand Down Expand Up @@ -230,6 +236,24 @@
.pin-icon.unpinned {
color: alpha(#ffffff, 0.25);
}

/* Settings window styling */
.settings-section {
border: 1px solid alpha(#ffffff, 0.1);
border-radius: 6px;
padding: 10px;
margin: 5px;
}

.settings-section > label {
color: alpha(#ffffff, 0.9);
font-weight: bold;
margin-bottom: 5px;
}

.settings-section frame {
background-color: alpha(#ffffff, 0.02);
}
"""
log.debug(f"Using configuration directory: {CONFIG_DIR}")
log.debug(f"Using configuration file: {CONFIG_FILE_PATH}")
Expand Down
Loading