detached d601f8c

Merge pull request #76 from bnema/feat/flatpak-support

feat(flatpak): add Flatpak packaging support
commit
d601f8ce40aaa8b47aef8ad3921c6ad2218de1a7
author
bnema · · 2025-12-30 20:42 UTC
committer
GitHub · · 2025-12-30 20:42 UTC
merge of
d05d132 + d347c59 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
12 files · +364 -1
A .github/workflows/flatpak.yml +128 -0
@@ -0,0 +1,128 @@
1+name: Flatpak
2+
3+on:
4+ push:
5+ tags:
6+ - 'v*'
7+ workflow_dispatch:
8+ inputs:
9+ tag:
10+ description: 'Release tag to build (e.g., v0.23.0)'
11+ required: true
12+
13+permissions:
14+ contents: write
15+
16+jobs:
17+ flatpak:
18+ name: Build Flatpak
19+ runs-on: ubuntu-latest
20+ container:
21+ image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48
22+ options: --privileged
23+ steps:
24+ - uses: actions/checkout@v4
25+
26+ - name: Get version
27+ id: version
28+ run: |
29+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
30+ VERSION="${{ github.event.inputs.tag }}"
31+ else
32+ VERSION="${GITHUB_REF#refs/tags/}"
33+ fi
34+ echo "version=$VERSION" >> $GITHUB_OUTPUT
35+ echo "Building Flatpak for version: $VERSION"
36+
37+ - name: Wait for release assets
38+ run: |
39+ VERSION="${{ steps.version.outputs.version }}"
40+ URL="https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz"
41+ echo "Waiting for release asset: $URL"
42+ for i in $(seq 1 30); do
43+ if curl -sL --fail -o /dev/null "$URL"; then
44+ echo "Release asset available!"
45+ exit 0
46+ fi
47+ echo "Attempt $i/30: Asset not ready, waiting 10s..."
48+ sleep 10
49+ done
50+ echo "Timeout waiting for release asset"
51+ exit 1
52+
53+ - name: Download and compute SHA256
54+ id: sha256
55+ run: |
56+ VERSION="${{ steps.version.outputs.version }}"
57+ URL="https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz"
58+ SHA256=$(curl -sL "$URL" | sha256sum | cut -d' ' -f1)
59+ echo "sha256=$SHA256" >> $GITHUB_OUTPUT
60+ echo "SHA256: $SHA256"
61+
62+ - name: Generate manifest
63+ run: |
64+ VERSION="${{ steps.version.outputs.version }}"
65+ SHA256="${{ steps.sha256.outputs.sha256 }}"
66+ cat > dev.bnema.Dumber.yml << EOF
67+ id: dev.bnema.Dumber
68+ runtime: org.gnome.Platform
69+ runtime-version: '48'
70+ sdk: org.gnome.Sdk
71+ command: dumber
72+
73+ finish-args:
74+ - --socket=wayland
75+ - --device=dri
76+ - --share=network
77+ - --socket=pulseaudio
78+ - --device=all
79+ - --filesystem=xdg-download
80+ - --filesystem=home:ro
81+ - --filesystem=xdg-run/pipewire-0:ro
82+
83+ modules:
84+ - name: dumber
85+ buildsystem: simple
86+ build-commands:
87+ - install -Dm755 dumber /app/bin/dumber
88+ - install -Dm644 dev.bnema.Dumber.desktop /app/share/applications/dev.bnema.Dumber.desktop
89+ - install -Dm644 logo.svg /app/share/icons/hicolor/scalable/apps/dev.bnema.Dumber.svg
90+ - install -Dm644 logo-512.png /app/share/icons/hicolor/512x512/apps/dev.bnema.Dumber.png
91+ - install -Dm644 dev.bnema.Dumber.metainfo.xml /app/share/metainfo/dev.bnema.Dumber.metainfo.xml
92+ sources:
93+ - type: archive
94+ url: https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz
95+ sha256: ${SHA256}
96+ - type: file
97+ path: dev.bnema.Dumber.desktop
98+ - type: file
99+ path: assets/logo.svg
100+ dest-filename: logo.svg
101+ - type: file
102+ path: assets/logo-512.png
103+ dest-filename: logo-512.png
104+ - type: file
105+ path: dev.bnema.Dumber.metainfo.xml
106+ EOF
107+ echo "Generated manifest:"
108+ cat dev.bnema.Dumber.yml
109+
110+ - name: Import GPG key
111+ run: |
112+ echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
113+ gpg --list-secret-keys --keyid-format=long
114+
115+ - uses: flatpak/flatpak-github-actions/flatpak-builder@v6
116+ with:
117+ bundle: dumber.flatpak
118+ manifest-path: dev.bnema.Dumber.yml
119+ cache-key: flatpak-builder-${{ steps.version.outputs.version }}
120+ gpg-sign: ${{ secrets.GPG_KEY_ID }}
121+
122+ - name: Upload Flatpak to Release
123+ if: startsWith(github.ref, 'refs/tags/')
124+ uses: softprops/action-gh-release@v2
125+ with:
126+ files: dumber.flatpak
127+ env:
128+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,128 @@
1+name: Flatpak
2+
3+on:
4+ push:
5+ tags:
6+ - 'v*'
7+ workflow_dispatch:
8+ inputs:
9+ tag:
10+ description: 'Release tag to build (e.g., v0.23.0)'
11+ required: true
12+
13+permissions:
14+ contents: write
15+
16+jobs:
17+ flatpak:
18+ name: Build Flatpak
19+ runs-on: ubuntu-latest
20+ container:
21+ image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48
22+ options: --privileged
23+ steps:
24+ - uses: actions/checkout@v4
25+
26+ - name: Get version
27+ id: version
28+ run: |
29+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
30+ VERSION="${{ github.event.inputs.tag }}"
31+ else
32+ VERSION="${GITHUB_REF#refs/tags/}"
33+ fi
34+ echo "version=$VERSION" >> $GITHUB_OUTPUT
35+ echo "Building Flatpak for version: $VERSION"
36+
37+ - name: Wait for release assets
38+ run: |
39+ VERSION="${{ steps.version.outputs.version }}"
40+ URL="https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz"
41+ echo "Waiting for release asset: $URL"
42+ for i in $(seq 1 30); do
43+ if curl -sL --fail -o /dev/null "$URL"; then
44+ echo "Release asset available!"
45+ exit 0
46+ fi
47+ echo "Attempt $i/30: Asset not ready, waiting 10s..."
48+ sleep 10
49+ done
50+ echo "Timeout waiting for release asset"
51+ exit 1
52+
53+ - name: Download and compute SHA256
54+ id: sha256
55+ run: |
56+ VERSION="${{ steps.version.outputs.version }}"
57+ URL="https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz"
58+ SHA256=$(curl -sL "$URL" | sha256sum | cut -d' ' -f1)
59+ echo "sha256=$SHA256" >> $GITHUB_OUTPUT
60+ echo "SHA256: $SHA256"
61+
62+ - name: Generate manifest
63+ run: |
64+ VERSION="${{ steps.version.outputs.version }}"
65+ SHA256="${{ steps.sha256.outputs.sha256 }}"
66+ cat > dev.bnema.Dumber.yml << EOF
67+ id: dev.bnema.Dumber
68+ runtime: org.gnome.Platform
69+ runtime-version: '48'
70+ sdk: org.gnome.Sdk
71+ command: dumber
72+
73+ finish-args:
74+ - --socket=wayland
75+ - --device=dri
76+ - --share=network
77+ - --socket=pulseaudio
78+ - --device=all
79+ - --filesystem=xdg-download
80+ - --filesystem=home:ro
81+ - --filesystem=xdg-run/pipewire-0:ro
82+
83+ modules:
84+ - name: dumber
85+ buildsystem: simple
86+ build-commands:
87+ - install -Dm755 dumber /app/bin/dumber
88+ - install -Dm644 dev.bnema.Dumber.desktop /app/share/applications/dev.bnema.Dumber.desktop
89+ - install -Dm644 logo.svg /app/share/icons/hicolor/scalable/apps/dev.bnema.Dumber.svg
90+ - install -Dm644 logo-512.png /app/share/icons/hicolor/512x512/apps/dev.bnema.Dumber.png
91+ - install -Dm644 dev.bnema.Dumber.metainfo.xml /app/share/metainfo/dev.bnema.Dumber.metainfo.xml
92+ sources:
93+ - type: archive
94+ url: https://github.com/bnema/dumber/releases/download/${VERSION}/dumber_linux_x86_64.tar.gz
95+ sha256: ${SHA256}
96+ - type: file
97+ path: dev.bnema.Dumber.desktop
98+ - type: file
99+ path: assets/logo.svg
100+ dest-filename: logo.svg
101+ - type: file
102+ path: assets/logo-512.png
103+ dest-filename: logo-512.png
104+ - type: file
105+ path: dev.bnema.Dumber.metainfo.xml
106+ EOF
107+ echo "Generated manifest:"
108+ cat dev.bnema.Dumber.yml
109+
110+ - name: Import GPG key
111+ run: |
112+ echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
113+ gpg --list-secret-keys --keyid-format=long
114+
115+ - uses: flatpak/flatpak-github-actions/flatpak-builder@v6
116+ with:
117+ bundle: dumber.flatpak
118+ manifest-path: dev.bnema.Dumber.yml
119+ cache-key: flatpak-builder-${{ steps.version.outputs.version }}
120+ gpg-sign: ${{ secrets.GPG_KEY_ID }}
121+
122+ - name: Upload Flatpak to Release
123+ if: startsWith(github.ref, 'refs/tags/')
124+ uses: softprops/action-gh-release@v2
125+ with:
126+ files: dumber.flatpak
127+ env:
128+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
M .gitignore +7 -0
@@ -89,3 +89,10 @@ vendor/
8989 serviceworkers/
9090 storage/
9191 mediakeys/
92+
93+# Flatpak build artifacts
94+flatpak-build/
95+flatpak-repo/
96+.flatpak-builder/
97+*.flatpak
98+builddir/
@@ -89,3 +89,10 @@ vendor/
89 serviceworkers/89 serviceworkers/
90 storage/90 storage/
91 mediakeys/91 mediakeys/
92+
93+# Flatpak build artifacts
94+flatpak-build/
95+flatpak-repo/
96+.flatpak-builder/
97+*.flatpak
98+builddir/
M CHANGELOG.md +11 -0
@@ -10,6 +10,17 @@ All notable changes to this project will be documented in this file.
1010
1111 ### Fixed
1212
13+## [0.23.1] - 2025-12-30
14+
15+### Added
16+- **Flatpak packaging support**: Dumber is now available as a Flatpak bundle for easy installation with all dependencies included.
17+ - `dumber.flatpak` bundle attached to each GitHub release.
18+ - Install with `flatpak install --user dumber.flatpak`.
19+ - Includes Wayland, GPU, audio, webcam, and PipeWire permissions.
20+ - Automatic builds via GitHub Actions on every release.
21+- **Flatpak runtime detection**: Skip pkg-config runtime checks when running inside Flatpak sandbox (GNOME runtime provides all dependencies).
22+- **Self-updater disabled in Flatpak**: Binary self-update is disabled when running as Flatpak (use Flatpak update mechanisms instead).
23+
1324 ## [0.23.0] - 2025-12-30
1425
1526 ### Added
@@ -10,6 +10,17 @@ All notable changes to this project will be documented in this file.
10 10
11 ### Fixed11 ### Fixed
12 12
13+## [0.23.1] - 2025-12-30
14+
15+### Added
16+- **Flatpak packaging support**: Dumber is now available as a Flatpak bundle for easy installation with all dependencies included.
17+ - `dumber.flatpak` bundle attached to each GitHub release.
18+ - Install with `flatpak install --user dumber.flatpak`.
19+ - Includes Wayland, GPU, audio, webcam, and PipeWire permissions.
20+ - Automatic builds via GitHub Actions on every release.
21+- **Flatpak runtime detection**: Skip pkg-config runtime checks when running inside Flatpak sandbox (GNOME runtime provides all dependencies).
22+- **Self-updater disabled in Flatpak**: Binary self-update is disabled when running as Flatpak (use Flatpak update mechanisms instead).
23+
13 ## [0.23.0] - 2025-12-3024 ## [0.23.0] - 2025-12-30
14 25
15 ### Added26 ### Added
M Makefile +30 -1
@@ -1,6 +1,6 @@
11 # Makefile for dumber (Clean Architecture - puregotk)
22
3-.PHONY: build build-frontend test lint clean install-tools dev generate help init check-docs man
3+.PHONY: build build-frontend test lint clean install-tools dev generate help init check-docs man flatpak-deps flatpak-build flatpak-install flatpak-run flatpak-clean
44
55 # Load local overrides from .env.local if present (Makefile syntax)
66 ifneq (,$(wildcard .env.local))
@@ -152,3 +152,32 @@ release-snapshot: build-frontend ## Build snapshot using goreleaser
152152 release: ## Create full release using goreleaser
153153 @echo "Building release with goreleaser..."
154154 GITHUB_TOKEN=$$(gh auth token) goreleaser release --clean
155+
156+# Flatpak targets
157+flatpak-deps: ## Install Flatpak build dependencies (Arch)
158+ @echo "Installing Flatpak build dependencies..."
159+ sudo pacman -S --needed flatpak flatpak-builder
160+ flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
161+ flatpak install --user -y flathub org.gnome.Platform//48 org.gnome.Sdk//48
162+ flatpak install --user -y flathub org.freedesktop.Sdk.Extension.golang//24.08
163+ flatpak install --user -y flathub org.freedesktop.Sdk.Extension.node20//24.08
164+ @echo "Flatpak dependencies installed!"
165+
166+flatpak-build: ## Build Flatpak bundle locally
167+ @echo "Building Flatpak bundle..."
168+ flatpak-builder --force-clean --user --repo=flatpak-repo flatpak-build dev.bnema.Dumber.yml
169+ flatpak build-bundle flatpak-repo dumber.flatpak dev.bnema.Dumber
170+ @echo "Flatpak bundle created: dumber.flatpak"
171+
172+flatpak-install: ## Install Flatpak locally for testing
173+ @echo "Installing Flatpak locally..."
174+ flatpak-builder --force-clean --user --install flatpak-build dev.bnema.Dumber.yml
175+ @echo "Flatpak installed! Run with: make flatpak-run"
176+
177+flatpak-run: ## Run the installed Flatpak
178+ flatpak run dev.bnema.Dumber
179+
180+flatpak-clean: ## Clean Flatpak build artifacts
181+ @echo "Cleaning Flatpak build artifacts..."
182+ rm -rf flatpak-build flatpak-repo .flatpak-builder dumber.flatpak
183+ @echo "Flatpak artifacts cleaned!"
@@ -1,6 +1,6 @@
1 # Makefile for dumber (Clean Architecture - puregotk)1 # Makefile for dumber (Clean Architecture - puregotk)
2 2
3-.PHONY: build build-frontend test lint clean install-tools dev generate help init check-docs man3+.PHONY: build build-frontend test lint clean install-tools dev generate help init check-docs man flatpak-deps flatpak-build flatpak-install flatpak-run flatpak-clean
4 4
5 # Load local overrides from .env.local if present (Makefile syntax)5 # Load local overrides from .env.local if present (Makefile syntax)
6 ifneq (,$(wildcard .env.local))6 ifneq (,$(wildcard .env.local))
@@ -152,3 +152,32 @@ release-snapshot: build-frontend ## Build snapshot using goreleaser
152 release: ## Create full release using goreleaser152 release: ## Create full release using goreleaser
153 @echo "Building release with goreleaser..."153 @echo "Building release with goreleaser..."
154 GITHUB_TOKEN=$$(gh auth token) goreleaser release --clean154 GITHUB_TOKEN=$$(gh auth token) goreleaser release --clean
155+
156+# Flatpak targets
157+flatpak-deps: ## Install Flatpak build dependencies (Arch)
158+ @echo "Installing Flatpak build dependencies..."
159+ sudo pacman -S --needed flatpak flatpak-builder
160+ flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
161+ flatpak install --user -y flathub org.gnome.Platform//48 org.gnome.Sdk//48
162+ flatpak install --user -y flathub org.freedesktop.Sdk.Extension.golang//24.08
163+ flatpak install --user -y flathub org.freedesktop.Sdk.Extension.node20//24.08
164+ @echo "Flatpak dependencies installed!"
165+
166+flatpak-build: ## Build Flatpak bundle locally
167+ @echo "Building Flatpak bundle..."
168+ flatpak-builder --force-clean --user --repo=flatpak-repo flatpak-build dev.bnema.Dumber.yml
169+ flatpak build-bundle flatpak-repo dumber.flatpak dev.bnema.Dumber
170+ @echo "Flatpak bundle created: dumber.flatpak"
171+
172+flatpak-install: ## Install Flatpak locally for testing
173+ @echo "Installing Flatpak locally..."
174+ flatpak-builder --force-clean --user --install flatpak-build dev.bnema.Dumber.yml
175+ @echo "Flatpak installed! Run with: make flatpak-run"
176+
177+flatpak-run: ## Run the installed Flatpak
178+ flatpak run dev.bnema.Dumber
179+
180+flatpak-clean: ## Clean Flatpak build artifacts
181+ @echo "Cleaning Flatpak build artifacts..."
182+ rm -rf flatpak-build flatpak-repo .flatpak-builder dumber.flatpak
183+ @echo "Flatpak artifacts cleaned!"
M README.md +20 -0
@@ -178,6 +178,26 @@ Development:
178178
179179 Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions.
180180
181+### Flatpak
182+
183+A Flatpak bundle is available in each release. This is the easiest way to install Dumber with all dependencies included:
184+
185+```bash
186+# Download the Flatpak bundle from the latest release
187+wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak
188+
189+# Install it (user-level, no root required)
190+flatpak install --user dumber.flatpak
191+
192+# Run it
193+flatpak run dev.bnema.Dumber browse
194+```
195+
196+To uninstall:
197+```bash
198+flatpak uninstall --user dev.bnema.Dumber
199+```
200+
181201 ### Dependencies
182202
183203 Required for both pre-built binaries and source builds:
@@ -178,6 +178,26 @@ Development:
178 178
179 Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions.179 Pre-built binaries are available for Linux (x86_64/amd64) in the [releases page](https://github.com/bnema/dumber/releases). See [Quick Start](#quick-start) for installation instructions.
180 180
181+### Flatpak
182+
183+A Flatpak bundle is available in each release. This is the easiest way to install Dumber with all dependencies included:
184+
185+```bash
186+# Download the Flatpak bundle from the latest release
187+wget https://github.com/bnema/dumber/releases/latest/download/dumber.flatpak
188+
189+# Install it (user-level, no root required)
190+flatpak install --user dumber.flatpak
191+
192+# Run it
193+flatpak run dev.bnema.Dumber browse
194+```
195+
196+To uninstall:
197+```bash
198+flatpak uninstall --user dev.bnema.Dumber
199+```
200+
181 ### Dependencies201 ### Dependencies
182 202
183 Required for both pre-built binaries and source builds:203 Required for both pre-built binaries and source builds:
A assets/logo-512.png +0 -0 binary file: no text diff

binary file: no text diff

A dev.bnema.Dumber.desktop +12 -0
@@ -0,0 +1,12 @@
1+[Desktop Entry]
2+Name=Dumber
3+Comment=A minimal keyboard-driven browser for tiling WMs
4+Exec=dumber browse
5+Icon=dev.bnema.Dumber
6+Terminal=false
7+Type=Application
8+Categories=Network;WebBrowser;GTK;
9+Keywords=browser;webkit;wayland;tiling;keyboard;
10+StartupNotify=true
11+StartupWMClass=dumber
12+MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
@@ -0,0 +1,12 @@
1+[Desktop Entry]
2+Name=Dumber
3+Comment=A minimal keyboard-driven browser for tiling WMs
4+Exec=dumber browse
5+Icon=dev.bnema.Dumber
6+Terminal=false
7+Type=Application
8+Categories=Network;WebBrowser;GTK;
9+Keywords=browser;webkit;wayland;tiling;keyboard;
10+StartupNotify=true
11+StartupWMClass=dumber
12+MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
A dev.bnema.Dumber.metainfo.xml +71 -0
@@ -0,0 +1,71 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<component type="desktop-application">
3+ <id>dev.bnema.Dumber</id>
4+ <metadata_license>CC0-1.0</metadata_license>
5+ <project_license>MIT</project_license>
6+ <name>Dumber</name>
7+ <summary>A minimal keyboard-driven browser for tiling WMs</summary>
8+ <description>
9+ <p>
10+ A dumb browser that works like your favorite terminal multiplexer.
11+ Wayland native, keyboard-driven with Zellij-inspired workflow, featuring
12+ tabs with split and stacked panes, built-in ad blocking, and session management.
13+ </p>
14+ <p>Features include:</p>
15+ <ul>
16+ <li>Wayland native - no X11/XWayland dependency</li>
17+ <li>Tabs and workspaces with split or stacked panes</li>
18+ <li>Keyboard-driven workflow inspired by Zellij</li>
19+ <li>Smart popup handling for OAuth flows and tiling WMs</li>
20+ <li>GPU rendering with automatic VA-API/VDPAU detection</li>
21+ <li>Built-in ad blocking with UBlock-based filtering</li>
22+ <li>Launcher integration with rofi/fuzzel support</li>
23+ <li>Search shortcuts via bangs</li>
24+ <li>Customizable light and dark themes</li>
25+ <li>Session save/restore with automatic snapshots</li>
26+ </ul>
27+ </description>
28+ <launchable type="desktop-id">dev.bnema.Dumber.desktop</launchable>
29+ <url type="homepage">https://github.com/bnema/dumber</url>
30+ <url type="bugtracker">https://github.com/bnema/dumber/issues</url>
31+ <url type="vcs-browser">https://github.com/bnema/dumber</url>
32+ <developer id="dev.bnema">
33+ <name>bnema</name>
34+ </developer>
35+ <branding>
36+ <color type="primary" scheme_preference="light">#f5f5f5</color>
37+ <color type="primary" scheme_preference="dark">#1a1a1a</color>
38+ </branding>
39+ <content_rating type="oars-1.1" />
40+ <supports>
41+ <control>keyboard</control>
42+ <control>pointing</control>
43+ </supports>
44+ <requires>
45+ <display_length compare="ge">768</display_length>
46+ </requires>
47+ <categories>
48+ <category>Network</category>
49+ <category>WebBrowser</category>
50+ </categories>
51+ <keywords>
52+ <keyword>browser</keyword>
53+ <keyword>webkit</keyword>
54+ <keyword>wayland</keyword>
55+ <keyword>tiling</keyword>
56+ <keyword>keyboard</keyword>
57+ <keyword>minimal</keyword>
58+ </keywords>
59+ <releases>
60+ <release version="0.23.1" date="2025-12-30">
61+ <description>
62+ <p>Added Flatpak packaging support with automatic builds on GitHub releases.</p>
63+ </description>
64+ </release>
65+ <release version="0.23.0" date="2025-12-29">
66+ <description>
67+ <p>Previous release with improved session management and bug fixes.</p>
68+ </description>
69+ </release>
70+ </releases>
71+</component>
@@ -0,0 +1,71 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<component type="desktop-application">
3+ <id>dev.bnema.Dumber</id>
4+ <metadata_license>CC0-1.0</metadata_license>
5+ <project_license>MIT</project_license>
6+ <name>Dumber</name>
7+ <summary>A minimal keyboard-driven browser for tiling WMs</summary>
8+ <description>
9+ <p>
10+ A dumb browser that works like your favorite terminal multiplexer.
11+ Wayland native, keyboard-driven with Zellij-inspired workflow, featuring
12+ tabs with split and stacked panes, built-in ad blocking, and session management.
13+ </p>
14+ <p>Features include:</p>
15+ <ul>
16+ <li>Wayland native - no X11/XWayland dependency</li>
17+ <li>Tabs and workspaces with split or stacked panes</li>
18+ <li>Keyboard-driven workflow inspired by Zellij</li>
19+ <li>Smart popup handling for OAuth flows and tiling WMs</li>
20+ <li>GPU rendering with automatic VA-API/VDPAU detection</li>
21+ <li>Built-in ad blocking with UBlock-based filtering</li>
22+ <li>Launcher integration with rofi/fuzzel support</li>
23+ <li>Search shortcuts via bangs</li>
24+ <li>Customizable light and dark themes</li>
25+ <li>Session save/restore with automatic snapshots</li>
26+ </ul>
27+ </description>
28+ <launchable type="desktop-id">dev.bnema.Dumber.desktop</launchable>
29+ <url type="homepage">https://github.com/bnema/dumber</url>
30+ <url type="bugtracker">https://github.com/bnema/dumber/issues</url>
31+ <url type="vcs-browser">https://github.com/bnema/dumber</url>
32+ <developer id="dev.bnema">
33+ <name>bnema</name>
34+ </developer>
35+ <branding>
36+ <color type="primary" scheme_preference="light">#f5f5f5</color>
37+ <color type="primary" scheme_preference="dark">#1a1a1a</color>
38+ </branding>
39+ <content_rating type="oars-1.1" />
40+ <supports>
41+ <control>keyboard</control>
42+ <control>pointing</control>
43+ </supports>
44+ <requires>
45+ <display_length compare="ge">768</display_length>
46+ </requires>
47+ <categories>
48+ <category>Network</category>
49+ <category>WebBrowser</category>
50+ </categories>
51+ <keywords>
52+ <keyword>browser</keyword>
53+ <keyword>webkit</keyword>
54+ <keyword>wayland</keyword>
55+ <keyword>tiling</keyword>
56+ <keyword>keyboard</keyword>
57+ <keyword>minimal</keyword>
58+ </keywords>
59+ <releases>
60+ <release version="0.23.1" date="2025-12-30">
61+ <description>
62+ <p>Added Flatpak packaging support with automatic builds on GitHub releases.</p>
63+ </description>
64+ </release>
65+ <release version="0.23.0" date="2025-12-29">
66+ <description>
67+ <p>Previous release with improved session management and bug fixes.</p>
68+ </description>
69+ </release>
70+ </releases>
71+</component>
A dev.bnema.Dumber.yml +59 -0
@@ -0,0 +1,59 @@
1+id: dev.bnema.Dumber
2+runtime: org.gnome.Platform
3+runtime-version: '48'
4+sdk: org.gnome.Sdk
5+command: dumber
6+
7+finish-args:
8+ # Display (Wayland only)
9+ - --socket=wayland
10+ # GPU rendering and hardware video decoding (VA-API)
11+ - --device=dri
12+ # Network (browser)
13+ - --share=network
14+ # Audio/Video playback via PulseAudio
15+ - --socket=pulseaudio
16+ # Camera/Webcam access (for video calls like Zoom, Meet, etc.)
17+ - --device=all
18+ # Downloads folder
19+ - --filesystem=xdg-download
20+ # Open local HTML files
21+ - --filesystem=home:ro
22+ # PipeWire for screen sharing and modern audio/video
23+ - --filesystem=xdg-run/pipewire-0:ro
24+
25+modules:
26+ - name: dumber
27+ buildsystem: simple
28+ build-commands:
29+ # Install the pre-built binary (archive is auto-extracted)
30+ - install -Dm755 dumber /app/bin/dumber
31+ # Install desktop file
32+ - install -Dm644 dev.bnema.Dumber.desktop /app/share/applications/dev.bnema.Dumber.desktop
33+ # Install icons
34+ - install -Dm644 logo.svg /app/share/icons/hicolor/scalable/apps/dev.bnema.Dumber.svg
35+ - install -Dm644 logo-512.png /app/share/icons/hicolor/512x512/apps/dev.bnema.Dumber.png
36+ # Install metainfo
37+ - install -Dm644 dev.bnema.Dumber.metainfo.xml /app/share/metainfo/dev.bnema.Dumber.metainfo.xml
38+ sources:
39+ # Pre-built binary from GitHub release
40+ # NOTE: URL and SHA256 are dynamically generated in CI
41+ # For local builds, update these values manually:
42+ # curl -sL <url> | sha256sum
43+ - type: archive
44+ url: https://github.com/bnema/dumber/releases/download/v0.23.1/dumber_linux_x86_64.tar.gz
45+ sha256: PLACEHOLDER_UPDATED_BY_CI
46+ dest-filename: dumber_linux_x86_64.tar.gz
47+ # Desktop file
48+ - type: file
49+ path: dev.bnema.Dumber.desktop
50+ # Icons
51+ - type: file
52+ path: assets/logo.svg
53+ dest-filename: logo.svg
54+ - type: file
55+ path: assets/logo-512.png
56+ dest-filename: logo-512.png
57+ # Metainfo
58+ - type: file
59+ path: dev.bnema.Dumber.metainfo.xml
@@ -0,0 +1,59 @@
1+id: dev.bnema.Dumber
2+runtime: org.gnome.Platform
3+runtime-version: '48'
4+sdk: org.gnome.Sdk
5+command: dumber
6+
7+finish-args:
8+ # Display (Wayland only)
9+ - --socket=wayland
10+ # GPU rendering and hardware video decoding (VA-API)
11+ - --device=dri
12+ # Network (browser)
13+ - --share=network
14+ # Audio/Video playback via PulseAudio
15+ - --socket=pulseaudio
16+ # Camera/Webcam access (for video calls like Zoom, Meet, etc.)
17+ - --device=all
18+ # Downloads folder
19+ - --filesystem=xdg-download
20+ # Open local HTML files
21+ - --filesystem=home:ro
22+ # PipeWire for screen sharing and modern audio/video
23+ - --filesystem=xdg-run/pipewire-0:ro
24+
25+modules:
26+ - name: dumber
27+ buildsystem: simple
28+ build-commands:
29+ # Install the pre-built binary (archive is auto-extracted)
30+ - install -Dm755 dumber /app/bin/dumber
31+ # Install desktop file
32+ - install -Dm644 dev.bnema.Dumber.desktop /app/share/applications/dev.bnema.Dumber.desktop
33+ # Install icons
34+ - install -Dm644 logo.svg /app/share/icons/hicolor/scalable/apps/dev.bnema.Dumber.svg
35+ - install -Dm644 logo-512.png /app/share/icons/hicolor/512x512/apps/dev.bnema.Dumber.png
36+ # Install metainfo
37+ - install -Dm644 dev.bnema.Dumber.metainfo.xml /app/share/metainfo/dev.bnema.Dumber.metainfo.xml
38+ sources:
39+ # Pre-built binary from GitHub release
40+ # NOTE: URL and SHA256 are dynamically generated in CI
41+ # For local builds, update these values manually:
42+ # curl -sL <url> | sha256sum
43+ - type: archive
44+ url: https://github.com/bnema/dumber/releases/download/v0.23.1/dumber_linux_x86_64.tar.gz
45+ sha256: PLACEHOLDER_UPDATED_BY_CI
46+ dest-filename: dumber_linux_x86_64.tar.gz
47+ # Desktop file
48+ - type: file
49+ path: dev.bnema.Dumber.desktop
50+ # Icons
51+ - type: file
52+ path: assets/logo.svg
53+ dest-filename: logo.svg
54+ - type: file
55+ path: assets/logo-512.png
56+ dest-filename: logo-512.png
57+ # Metainfo
58+ - type: file
59+ path: dev.bnema.Dumber.metainfo.xml
M internal/bootstrap/gui.go +10 -0
@@ -15,6 +15,7 @@ import (
1515 "github.com/bnema/dumber/internal/infrastructure/colorscheme"
1616 "github.com/bnema/dumber/internal/infrastructure/config"
1717 "github.com/bnema/dumber/internal/infrastructure/deps"
18+ "github.com/bnema/dumber/internal/infrastructure/env"
1819 "github.com/bnema/dumber/internal/infrastructure/media"
1920 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
2021 "github.com/bnema/dumber/internal/logging"
@@ -185,7 +186,16 @@ func RunDeferredInit(input DeferredInitInput) DeferredInitResult {
185186
186187 // CheckRuntimeRequirements verifies WebKitGTK and other runtime dependencies.
187188 // Returns error if requirements are not met; caller should log details and exit.
189+// Note: When running in a Flatpak sandbox, runtime checks are skipped because
190+// the Flatpak runtime provides all required libraries.
188191 func CheckRuntimeRequirements(ctx context.Context, cfg *config.Config) error {
192+ // Skip pkg-config checks in Flatpak - the runtime provides all dependencies
193+ if env.IsFlatpak() {
194+ log := logging.FromContext(ctx)
195+ log.Debug().Msg("running in Flatpak sandbox, skipping runtime dependency checks")
196+ return nil
197+ }
198+
189199 probe := deps.NewPkgConfigProbe()
190200 checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe)
191201 runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{
@@ -15,6 +15,7 @@ import (
15 "github.com/bnema/dumber/internal/infrastructure/colorscheme"15 "github.com/bnema/dumber/internal/infrastructure/colorscheme"
16 "github.com/bnema/dumber/internal/infrastructure/config"16 "github.com/bnema/dumber/internal/infrastructure/config"
17 "github.com/bnema/dumber/internal/infrastructure/deps"17 "github.com/bnema/dumber/internal/infrastructure/deps"
18+ "github.com/bnema/dumber/internal/infrastructure/env"
18 "github.com/bnema/dumber/internal/infrastructure/media"19 "github.com/bnema/dumber/internal/infrastructure/media"
19 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"20 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
20 "github.com/bnema/dumber/internal/logging"21 "github.com/bnema/dumber/internal/logging"
@@ -185,7 +186,16 @@ func RunDeferredInit(input DeferredInitInput) DeferredInitResult {
185 186
186 // CheckRuntimeRequirements verifies WebKitGTK and other runtime dependencies.187 // CheckRuntimeRequirements verifies WebKitGTK and other runtime dependencies.
187 // Returns error if requirements are not met; caller should log details and exit.188 // Returns error if requirements are not met; caller should log details and exit.
189+// Note: When running in a Flatpak sandbox, runtime checks are skipped because
190+// the Flatpak runtime provides all required libraries.
188 func CheckRuntimeRequirements(ctx context.Context, cfg *config.Config) error {191 func CheckRuntimeRequirements(ctx context.Context, cfg *config.Config) error {
192+ // Skip pkg-config checks in Flatpak - the runtime provides all dependencies
193+ if env.IsFlatpak() {
194+ log := logging.FromContext(ctx)
195+ log.Debug().Msg("running in Flatpak sandbox, skipping runtime dependency checks")
196+ return nil
197+ }
198+
189 probe := deps.NewPkgConfigProbe()199 probe := deps.NewPkgConfigProbe()
190 checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe)200 checkRuntimeUC := usecase.NewCheckRuntimeDependenciesUseCase(probe)
191 runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{201 runtimeOut, err := checkRuntimeUC.Execute(ctx, usecase.CheckRuntimeDependenciesInput{
M internal/infrastructure/env/manager.go +8 -0
@@ -12,6 +12,14 @@ import (
1212 "github.com/bnema/dumber/internal/logging"
1313 )
1414
15+// IsFlatpak returns true if the application is running inside a Flatpak sandbox.
16+// The Flatpak runtime provides all required libraries, so host pkg-config checks
17+// should be skipped when running in this environment.
18+func IsFlatpak() bool {
19+ _, err := os.Stat("/.flatpak-info")
20+ return err == nil
21+}
22+
1523 // Manager implements port.RenderingEnvManager for configuring
1624 // environment variables for GStreamer, WebKit, and GTK/GSK.
1725 type Manager struct {
@@ -12,6 +12,14 @@ import (
12 "github.com/bnema/dumber/internal/logging"12 "github.com/bnema/dumber/internal/logging"
13 )13 )
14 14
15+// IsFlatpak returns true if the application is running inside a Flatpak sandbox.
16+// The Flatpak runtime provides all required libraries, so host pkg-config checks
17+// should be skipped when running in this environment.
18+func IsFlatpak() bool {
19+ _, err := os.Stat("/.flatpak-info")
20+ return err == nil
21+}
22+
15 // Manager implements port.RenderingEnvManager for configuring23 // Manager implements port.RenderingEnvManager for configuring
16 // environment variables for GStreamer, WebKit, and GTK/GSK.24 // environment variables for GStreamer, WebKit, and GTK/GSK.
17 type Manager struct {25 type Manager struct {
M internal/infrastructure/updater/applier.go +8 -0
@@ -9,6 +9,7 @@ import (
99 "golang.org/x/sys/unix"
1010
1111 "github.com/bnema/dumber/internal/infrastructure/config"
12+ "github.com/bnema/dumber/internal/infrastructure/env"
1213 "github.com/bnema/dumber/internal/logging"
1314 )
1415
@@ -58,9 +59,16 @@ func (a *Applier) stagedBinaryPath() string {
5859 }
5960
6061 // CanSelfUpdate checks if the current binary is writable by the current user.
62+// Returns false if running inside a Flatpak sandbox (updates handled by Flatpak).
6163 func (a *Applier) CanSelfUpdate(ctx context.Context) bool {
6264 log := logging.FromContext(ctx)
6365
66+ // Flatpak sandboxed apps should not self-update; Flatpak handles updates.
67+ if env.IsFlatpak() {
68+ log.Debug().Msg("running in Flatpak sandbox, self-update disabled")
69+ return false
70+ }
71+
6472 binaryPath, err := a.GetBinaryPath()
6573 if err != nil {
6674 log.Debug().Err(err).Msg("failed to get binary path")
@@ -9,6 +9,7 @@ import (
9 "golang.org/x/sys/unix"9 "golang.org/x/sys/unix"
10 10
11 "github.com/bnema/dumber/internal/infrastructure/config"11 "github.com/bnema/dumber/internal/infrastructure/config"
12+ "github.com/bnema/dumber/internal/infrastructure/env"
12 "github.com/bnema/dumber/internal/logging"13 "github.com/bnema/dumber/internal/logging"
13 )14 )
14 15
@@ -58,9 +59,16 @@ func (a *Applier) stagedBinaryPath() string {
58 }59 }
59 60
60 // CanSelfUpdate checks if the current binary is writable by the current user.61 // CanSelfUpdate checks if the current binary is writable by the current user.
62+// Returns false if running inside a Flatpak sandbox (updates handled by Flatpak).
61 func (a *Applier) CanSelfUpdate(ctx context.Context) bool {63 func (a *Applier) CanSelfUpdate(ctx context.Context) bool {
62 log := logging.FromContext(ctx)64 log := logging.FromContext(ctx)
63 65
66+ // Flatpak sandboxed apps should not self-update; Flatpak handles updates.
67+ if env.IsFlatpak() {
68+ log.Debug().Msg("running in Flatpak sandbox, self-update disabled")
69+ return false
70+ }
71+
64 binaryPath, err := a.GetBinaryPath()72 binaryPath, err := a.GetBinaryPath()
65 if err != nil {73 if err != nil {
66 log.Debug().Err(err).Msg("failed to get binary path")74 log.Debug().Err(err).Msg("failed to get binary path")

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close