Compare commits

..

No commits in common. "main" and "v2.9.3" have entirely different histories.
main ... v2.9.3

27 changed files with 148 additions and 296 deletions

View File

@ -148,7 +148,7 @@ jobs:
name: release-artifacts-gnome-aarch64 name: release-artifacts-gnome-aarch64
path: out/*.tar.gz path: out/*.tar.gz
build-kwin-steamos-3_7: build-kwin-steamos:
needs: check-version-change needs: check-version-change
if: needs.check-version-change.outputs.should-release == 'true' if: needs.check-version-change.outputs.should-release == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -163,70 +163,16 @@ jobs:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Build Breezy KWin (steamos-3.7) - name: Build Breezy KWin (steamos)
run: | run: |
STEAMOS=3.7 bin/package_kwin STEAMOS=1 bin/package_kwin
env: env:
UA_API_SECRET: ${{ secrets.UA_API_SECRET }} UA_API_SECRET: ${{ secrets.UA_API_SECRET }}
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: release-artifacts-kwin-steamos-3.7 name: release-artifacts-kwin-steamos
path: out/*.tar.gz
build-kwin-steamos-3_8:
needs: check-version-change
if: needs.check-version-change.outputs.should-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Breezy KWin (steamos-3.8)
run: |
STEAMOS=3.8 bin/package_kwin
env:
UA_API_SECRET: ${{ secrets.UA_API_SECRET }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: release-artifacts-kwin-steamos-3.8
path: out/*.tar.gz
build-kwin-steamos-3_9:
needs: check-version-change
if: needs.check-version-change.outputs.should-release == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Breezy KWin (steamos-3.9)
run: |
STEAMOS=3.9 bin/package_kwin
env:
UA_API_SECRET: ${{ secrets.UA_API_SECRET }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: release-artifacts-kwin-steamos-3.9
path: out/*.tar.gz path: out/*.tar.gz
build-vulkan-x86_64: build-vulkan-x86_64:
@ -262,9 +208,7 @@ jobs:
- build-libs - build-libs
- build-gnome-x86_64 - build-gnome-x86_64
- build-gnome-aarch64 - build-gnome-aarch64
- build-kwin-steamos-3_7 - build-kwin-steamos
- build-kwin-steamos-3_8
- build-kwin-steamos-3_9
- build-vulkan-x86_64 - build-vulkan-x86_64
if: needs.check-version-change.outputs.should-release == 'true' if: needs.check-version-change.outputs.should-release == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -8,9 +8,6 @@
## What is this? ## What is this?
> [!TIP]
> Interested in an XR desktop for **Windows**, **MacOS**, or **Android**? Star the work-in-progress [Breezy Box](https://github.com/wheaney/breezy-box) project ([watch the demo](https://youtu.be/AwEQXnabRxE)).
This repo contains a collection of tools to enable virtual desktop environments for gaming and productivity on Linux using [supported XR glasses](https://github.com/wheaney/XRLinuxDriver#supported-devices). This repo contains a collection of tools to enable virtual desktop environments for gaming and productivity on Linux using [supported XR glasses](https://github.com/wheaney/XRLinuxDriver#supported-devices).
There are two installations available. **Note: Don't manually install either of these if you're running the Decky plugin on the same machine, as they invalidate each other's installations. This is only temporary.** There are two installations available. **Note: Don't manually install either of these if you're running the Decky plugin on the same machine, as they invalidate each other's installations. This is only temporary.**
@ -19,7 +16,7 @@ There are two installations available. **Note: Don't manually install either of
## Breezy Desktop ## Breezy Desktop
Breezy Desktop is a virtual workspace solution for Linux desktops that use the KDE Plasma 6 or GNOME desktop environments (versions 45 through 50). It supports launching multiple virtual monitors alongside multiple physical monitors. Breezy Desktop is a virtual workspace solution for Linux desktops that use the KDE Plasma 6 or GNOME desktop environments (versions 42 through 49). It supports launching multiple virtual monitors alongside multiple physical monitors.
For the best performance, ensure you have the latest graphics drivers installed for your distro. For the best performance, ensure you have the latest graphics drivers installed for your distro.
@ -67,7 +64,7 @@ After setup, you'll have an application called `Breezy Desktop` installed. Launc
### GNOME Setup ### GNOME Setup
Breezy Desktop has best compatibility with GNOME versions 45 through 50. Breezy Desktop has best compatibility with GNOME versions 45 through 49.
**IMPORTANT** - Please read carefully through this list before you get started **IMPORTANT** - Please read carefully through this list before you get started
* **Make sure your glasses are in the [supported devices list](https://github.com/wheaney/XRLinuxDriver#supported-devices)** and are on the latest firmware. * **Make sure your glasses are in the [supported devices list](https://github.com/wheaney/XRLinuxDriver#supported-devices)** and are on the latest firmware.
@ -97,6 +94,8 @@ Breezy GNOME is in AUR. To install, run these commands from a terminal with your
After setup, you'll have an application called `Breezy Desktop` installed. Launch that and follow any instructions. You will need to log out and back in at least once to get the GNOME extension working. You can also configure keyboard shortcuts for the most common toggle actions. The Breezy Desktop app doesn't have to be running to use the virtual desktop or the keyboard shortcuts once you've configured everything to your liking. After setup, you'll have an application called `Breezy Desktop` installed. Launch that and follow any instructions. You will need to log out and back in at least once to get the GNOME extension working. You can also configure keyboard shortcuts for the most common toggle actions. The Breezy Desktop app doesn't have to be running to use the virtual desktop or the keyboard shortcuts once you've configured everything to your liking.
For a double-wide screen, enable "widescreen mode" using the toggle in the Breezy Desktop application. **Note: this can be significantly more resource intensive than non-widescreen, you may notice performance dips on older hardware.**
### Breezy Desktop Pricing ### Breezy Desktop Pricing
Breezy Desktop for GNOME and KDE comes with 2 free trial months. Trial access is granted automatically after setup (no token entry required), and you only need to be online once after setup so your device can activate/refresh access. Breezy Desktop for GNOME and KDE comes with 2 free trial months. Trial access is granted automatically after setup (no token entry required), and you only need to be online once after setup so your device can activate/refresh access.

View File

@ -1 +1 @@
2.11.2 2.9.3

View File

@ -49,8 +49,7 @@ LIBS_ARCH="$ARCH"
if [ -f /etc/os-release ]; then if [ -f /etc/os-release ]; then
. /etc/os-release . /etc/os-release
if [ "$ID" == "steamos" ]; then if [ "$ID" == "steamos" ]; then
IFS=. read -r steamos_major steamos_minor _ <<< "$VERSION_ID" ARCH="steamos"
ARCH="steamos-${steamos_major}.${steamos_minor}"
fi fi
fi fi
FILE_NAME="breezyKWin-$ARCH.tar.gz" FILE_NAME="breezyKWin-$ARCH.tar.gz"
@ -204,7 +203,7 @@ mv breezy_desktop_lib/* breezy_kwin/
pushd breezy_kwin > /dev/null pushd breezy_kwin > /dev/null
# run the setup script that comes with this release # run the setup script that comes with this release
ARCH="$ARCH" bin/setup $metrics_version bin/setup $metrics_version
echo "Deleting temp directory: ${tmp_dir}" echo "Deleting temp directory: ${tmp_dir}"
rm -rf $tmp_dir rm -rf $tmp_dir

View File

@ -7,7 +7,7 @@ ARCH=${ARCH:-$(uname -m)}
BUILD_ARCH=$ARCH BUILD_ARCH=$ARCH
if [ -n "${STEAMOS+x}" ]; then if [ -n "${STEAMOS+x}" ]; then
ARCH="x86_64" ARCH="x86_64"
BUILD_ARCH="steamos-$STEAMOS" BUILD_ARCH="steamos"
fi fi
# https://stackoverflow.com/a/246128 # https://stackoverflow.com/a/246128

View File

@ -44,9 +44,6 @@ rm -f $XDG_DATA_HOME/locale/*/LC_MESSAGES/breezydesktop.mo
rm -f $XDG_BIN_HOME/breezydesktop rm -f $XDG_BIN_HOME/breezydesktop
rm -f $XDG_BIN_HOME/virtualdisplay rm -f $XDG_BIN_HOME/virtualdisplay
[ "$for_install" -eq 0 ] && echo "Clearing Breezy Desktop icons from the GTK icon cache"
gtk-update-icon-cache -f -t "$XDG_DATA_HOME/icons/hicolor" >/dev/null 2>&1 || true
if [ -e "$XDG_BIN_HOME/xr_driver_uninstall" ]; then if [ -e "$XDG_BIN_HOME/xr_driver_uninstall" ]; then
[ "$for_install" -eq 0 ] && echo "Uninstalling XRLinuxDriver" [ "$for_install" -eq 0 ] && echo "Uninstalling XRLinuxDriver"
if [ "$for_install" -eq 1 ]; then if [ "$for_install" -eq 1 ]; then

View File

@ -146,8 +146,8 @@ sed -i -e "s/{bin_dir}/$ESCAPED_XDG_BIN_HOME/g" \
cp bin/breezy_gnome_verify $XDG_BIN_HOME cp bin/breezy_gnome_verify $XDG_BIN_HOME
echo "Copying the manifest file to ${BREEZY_GNOME_DATA_DIR}" echo "Copying the manifest file to ${BREEZY_GNOME_DATA_DIR}"
mkdir -p "$BREEZY_GNOME_DATA_DIR" mkdir -p $BREEZY_GNOME_DATA_DIR
cp manifest "$BREEZY_GNOME_DATA_DIR/manifest" cp manifest $BREEZY_GNOME_DATA_DIR
echo "Installing the breezydesktop@xronlinux.com GNOME extension" echo "Installing the breezydesktop@xronlinux.com GNOME extension"
gnome-extensions install --force breezydesktop@xronlinux.com.shell-extension.zip gnome-extensions install --force breezydesktop@xronlinux.com.shell-extension.zip

View File

@ -334,7 +334,7 @@ export const DeviceDataStream = GObject.registerClass({
} else if (this.breezy_desktop_running !== this.breezy_desktop_actually_running) { } else if (this.breezy_desktop_running !== this.breezy_desktop_actually_running) {
// update the breezy_desktop_running property if the state changes to trigger "notify::" events // update the breezy_desktop_running property if the state changes to trigger "notify::" events
this.breezy_desktop_running = this.breezy_desktop_actually_running; this.breezy_desktop_running = this.breezy_desktop_actually_running;
if (!this.breezy_desktop_running) { if (!this.breezy_desktop_running && keepalive_only) {
this.device_data = null; this.device_data = null;
this.imu_snapshots = null; this.imu_snapshots = null;
} }

View File

@ -5,7 +5,7 @@
"settings-schema": "com.xronlinux.BreezyDesktop", "settings-schema": "com.xronlinux.BreezyDesktop",
"session-modes": ["user"], "session-modes": ["user"],
"shell-version": [ "shell-version": [
"46", "47", "48", "49", "50" "46", "47", "48", "49"
], ],
"url": "https://github.com/wheaney/breezy-desktop" "url": "https://github.com/wheaney/breezy-desktop"
} }

View File

@ -27,7 +27,6 @@ export const NESTED_MONITOR_PRODUCT = 'MetaMonitor';
export const VIRTUAL_MONITOR_PRODUCT = 'Virtual remote monitor'; export const VIRTUAL_MONITOR_PRODUCT = 'Virtual remote monitor';
export const SUPPORTED_MONITOR_PRODUCTS = [ export const SUPPORTED_MONITOR_PRODUCTS = [
'VITURE', 'VITURE',
'VITURE Beast',
'nreal air', 'nreal air',
'Air', 'Air',
'Air 2', 'Air 2',

View File

@ -142,14 +142,8 @@ function findFocusedMonitor(quaternion, position, monitorVectors, currentFocused
* @returns {Object} - containing `begin`, `center`, and `end` radians for rotating the given monitor * @returns {Object} - containing `begin`, `center`, and `end` radians for rotating the given monitor
*/ */
function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPixel, monitorLengthPixels, lengthToRadianFn) { function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPixel, monitorLengthPixels, lengthToRadianFn) {
// Monitor coordinates can become fractional due to size adjustment. let closestWrapPixel = monitorBeginPixel;
// If a monitor edge lands extremely close to a cached pixel key, snap to it; let closestWrap = cachedMonitorRadians[monitorBeginPixel];
// otherwise tiny negative gaps can cause us to subtract a full spacing interval.
let beginPixel = monitorBeginPixel;
const pixelEpsilon = Math.max(1e-6, Math.abs(monitorLengthPixels) * 1e-6);
let closestWrapPixel = beginPixel;
let closestWrap = cachedMonitorRadians[beginPixel];
if (closestWrap === undefined) { if (closestWrap === undefined) {
closestWrapPixel = Object.keys(cachedMonitorRadians).reduce((previousPixel, currentPixel) => { closestWrapPixel = Object.keys(cachedMonitorRadians).reduce((previousPixel, currentPixel) => {
if (previousPixel === undefined) return currentPixel; if (previousPixel === undefined) return currentPixel;
@ -173,16 +167,10 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
closestWrap = cachedMonitorRadians[closestWrapPixel]; closestWrap = cachedMonitorRadians[closestWrapPixel];
} }
const closestWrapPixelNumber = Number(closestWrapPixel);
if (Number.isFinite(closestWrapPixelNumber) && Math.abs(closestWrapPixelNumber - beginPixel) < pixelEpsilon) {
beginPixel = closestWrapPixelNumber;
closestWrapPixel = closestWrapPixelNumber;
}
const spacingRadians = lengthToRadianFn(monitorSpacingPixels); const spacingRadians = lengthToRadianFn(monitorSpacingPixels);
if (closestWrapPixel !== beginPixel) { if (closestWrapPixel !== monitorBeginPixel) {
// there's a gap between the cached wrap value and this one // there's a gap between the cached wrap value and this one
const gapPixels = beginPixel - closestWrapPixel; const gapPixels = monitorBeginPixel - closestWrapPixel;
const gapRadians = lengthToRadianFn(gapPixels); const gapRadians = lengthToRadianFn(gapPixels);
// use Math.floor so if it's negative (this monitor is to the left of or above the closest) it will always // use Math.floor so if it's negative (this monitor is to the left of or above the closest) it will always
@ -191,7 +179,7 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
// update the closestWrap value and cache it // update the closestWrap value and cache it
closestWrap = closestWrap + gapRadians + appliedSpacingRadians; closestWrap = closestWrap + gapRadians + appliedSpacingRadians;
closestWrapPixel = beginPixel; closestWrapPixel = monitorBeginPixel;
cachedMonitorRadians[closestWrapPixel] = closestWrap; cachedMonitorRadians[closestWrapPixel] = closestWrap;
} }
@ -200,7 +188,7 @@ function monitorWrap(cachedMonitorRadians, monitorSpacingPixels, monitorBeginPix
const endRadians = closestWrap + monitorRadians; const endRadians = closestWrap + monitorRadians;
// since we're computing the end values for this monitor, cache them too in case they line up with a future monitor // since we're computing the end values for this monitor, cache them too in case they line up with a future monitor
const nextMonitorPixel = beginPixel + monitorLengthPixels; const nextMonitorPixel = monitorBeginPixel + monitorLengthPixels;
if (cachedMonitorRadians[nextMonitorPixel] === undefined) if (cachedMonitorRadians[nextMonitorPixel] === undefined)
cachedMonitorRadians[nextMonitorPixel] = endRadians + spacingRadians; cachedMonitorRadians[nextMonitorPixel] = endRadians + spacingRadians;
@ -313,7 +301,7 @@ function monitorsToPlacements(fovDetails, monitorDetailsList, monitorSpacing) {
centerNoRotate: [ centerNoRotate: [
monitorCenterRadius, monitorCenterRadius,
// west is flat when wrapping vertically // west is flat when wrapping horizontally
westCenterPixels, westCenterPixels,
// up is centered about the FOV center // up is centered about the FOV center

View File

@ -14,7 +14,7 @@ check_command "make"
ARCH=${ARCH:-$(uname -m)} ARCH=${ARCH:-$(uname -m)}
if [ -n "${STEAMOS+x}" ]; then if [ -n "${STEAMOS+x}" ]; then
ARCH="steamos-$STEAMOS" ARCH="steamos"
fi fi
echo "Building Breezy KWin plugin for $ARCH" echo "Building Breezy KWin plugin for $ARCH"

View File

@ -8,10 +8,6 @@ if [ "$XDG_SESSION_TYPE" != "wayland" ]; then
fi fi
install_steamos_shortcuts() { install_steamos_shortcuts() {
if [[ "${ARCH:-}" != "steamos-3.7" ]]; then
return
fi
local os_release="/etc/os-release" local os_release="/etc/os-release"
if [[ ! -r "$os_release" ]]; then if [[ ! -r "$os_release" ]]; then
return return

View File

@ -0,0 +1,37 @@
# To run the build from the package root:
# docker buildx build --platform linux/amd64,linux/arm64 -f ./docker-build/Dockerfile -t "breezy-kwin" .
# docker run --rm -t -v ./:/source -v --platform linux/amd64 "breezy-kwin:amd64"
# docker run --rm -t -v ./:/source -v --platform linux/arm64 "breezy-kwin:arm64"
FROM --platform=$TARGETPLATFORM archlinux:base-20250817.0.405639@sha256:31f0749bdb81517dc8f379feac0a3860b097f1da1f53c8315c1bae0817d6c0a1
ARG TARGETPLATFORM
RUN echo "Target platform: $TARGETPLATFORM"
RUN pacman -Sy --noconfirm --needed \
ca-certificates \
base-devel \
cmake \
pkgconf \
git \
curl \
wget \
extra-cmake-modules \
qt6-base \
qt6-declarative \
qt6-quick3d \
qt6-tools \
kconfig \
kconfigwidgets \
kcoreaddons \
kglobalaccel \
ki18n \
kcmutils \
kxmlgui \
kwindowsystem \
kwin \
&& pacman -Scc --noconfirm
WORKDIR /source
CMD bin/package_kwin_plugin

View File

@ -0,0 +1,37 @@
# To run the build from the package root:
# docker buildx build --platform linux/amd64,linux/arm64 -f ./docker-build/Dockerfile.steamos -t "breezy-kwin-steamos" .
# docker run --rm -t -v ./:/source -v --platform linux/amd64 "breezy-kwin-steamos:amd64"
# docker run --rm -t -v ./:/source -v --platform linux/arm64 "breezy-kwin-steamos:arm64"
FROM --platform=$TARGETPLATFORM ghcr.io/steamdeckhomebrew/holo-base:3.7@sha256:8da120a3e89c750abd0090c0aab86d543a55d667c3002c8d64960f7fd82ccdd6
ARG TARGETPLATFORM
ENV STEAMOS=1
RUN echo "SteamOS build - target platform: $TARGETPLATFORM"
RUN pacman -Sy --noconfirm --needed \
ca-certificates \
base-devel \
cmake \
pkgconf \
git \
curl \
wget \
extra-cmake-modules \
qt6-base \
qt6-declarative \
qt6-tools \
kconfig \
kconfigwidgets \
kcoreaddons \
kglobalaccel \
ki18n \
kcmutils \
kxmlgui \
kwindowsystem \
kwin \
&& pacman -Scc --noconfirm
WORKDIR /source
CMD bin/package_kwin_plugin

View File

@ -1,41 +0,0 @@
# To run the build from the package root:
# docker buildx build --platform linux/amd64,linux/arm64 -f ./docker-build/Dockerfile.steamos-3.7 -t "breezy-kwin-steamos-3.7" .
# docker run --rm -t -v ./:/source -v --platform linux/amd64 "breezy-kwin-steamos-3.7:amd64"
FROM --platform=$TARGETPLATFORM ghcr.io/wheaney/holo-base:3.7.20@sha256:1478200c51b8b287e294de6e98a1ab0fb79333503a5cc5681b58dfd209f17851
ARG TARGETPLATFORM
ENV STEAMOS=3.7
RUN echo "SteamOS 3.7 build - target platform: $TARGETPLATFORM"
# CheckSpace can't stat Docker's read-only /etc/hosts and /etc/resolv.conf bind mounts,
# which aborts the transaction; Arch's own container images disable it for this reason
RUN sed -i 's/^[[:space:]]*CheckSpace/#CheckSpace/' /etc/pacman.conf \
&& pacman -Syu --noconfirm --needed \
ca-certificates \
base-devel \
cmake \
pkgconf \
git \
curl \
wget \
extra-cmake-modules \
qt6-base \
qt6-declarative \
qt6-quick3d \
qt6-tools \
kconfig \
kconfigwidgets \
kcoreaddons \
kglobalaccel \
ki18n \
kcmutils \
kxmlgui \
kwindowsystem \
kwin \
vulkan-headers \
&& pacman -Scc --noconfirm
WORKDIR /source
CMD bin/package_kwin_plugin

View File

@ -1,41 +0,0 @@
# To run the build from the package root:
# docker buildx build --platform linux/amd64,linux/arm64 -f ./docker-build/Dockerfile.steamos-3.8 -t "breezy-kwin-steamos" .
# docker run --rm -t -v ./:/source -v --platform linux/amd64 "breezy-kwin-steamos-3.8:amd64"
FROM --platform=$TARGETPLATFORM ghcr.io/wheaney/holo-base:preview-3.8@sha256:a38cdf4ac0e9022ab55c2078381761b444362cfde63e61d988830b0aafb84850
ARG TARGETPLATFORM
ENV STEAMOS=3.8
RUN echo "SteamOS 3.8 build - target platform: $TARGETPLATFORM"
# CheckSpace can't stat Docker's read-only /etc/hosts and /etc/resolv.conf bind mounts,
# which aborts the transaction; Arch's own container images disable it for this reason
RUN sed -i 's/^[[:space:]]*CheckSpace/#CheckSpace/' /etc/pacman.conf \
&& pacman -Syu --noconfirm --needed \
ca-certificates \
base-devel \
cmake \
pkgconf \
git \
curl \
wget \
extra-cmake-modules \
qt6-base \
qt6-declarative \
qt6-quick3d \
qt6-tools \
kconfig \
kconfigwidgets \
kcoreaddons \
kglobalaccel \
ki18n \
kcmutils \
kxmlgui \
kwindowsystem \
kwin \
vulkan-headers \
&& pacman -Scc --noconfirm
WORKDIR /source
CMD bin/package_kwin_plugin

View File

@ -1,41 +0,0 @@
# To run the build from the package root:
# docker buildx build --platform linux/amd64,linux/arm64 -f ./docker-build/Dockerfile.steamos-3.9 -t "breezy-kwin-steamos" .
# docker run --rm -t -v ./:/source -v --platform linux/amd64 "breezy-kwin-steamos-3.9:amd64"
FROM --platform=$TARGETPLATFORM ghcr.io/wheaney/holo-base:main-3.9@sha256:a9e2c59fb1274cf31d544229134e6bc653f050661dd9b64b05795b964468fcbf
ARG TARGETPLATFORM
ENV STEAMOS=3.9
RUN echo "SteamOS 3.9 build - target platform: $TARGETPLATFORM"
# CheckSpace can't stat Docker's read-only /etc/hosts and /etc/resolv.conf bind mounts,
# which aborts the transaction; Arch's own container images disable it for this reason
RUN sed -i 's/^[[:space:]]*CheckSpace/#CheckSpace/' /etc/pacman.conf \
&& pacman -Syu --noconfirm --needed \
ca-certificates \
base-devel \
cmake \
pkgconf \
git \
curl \
wget \
extra-cmake-modules \
qt6-base \
qt6-declarative \
qt6-quick3d \
qt6-tools \
kconfig \
kconfigwidgets \
kcoreaddons \
kglobalaccel \
ki18n \
kcmutils \
kxmlgui \
kwindowsystem \
kwin \
vulkan-headers \
&& pacman -Scc --noconfirm
WORKDIR /source
CMD bin/package_kwin_plugin

View File

@ -18,6 +18,6 @@ else
fi fi
echo "Building docker image" echo "Building docker image"
docker buildx build --platform linux/amd64 -f ./docker-build/Dockerfile.steamos-3.7 -t "breezy-kwin-steamos-3.7:amd64" --load . # docker buildx build --platform linux/amd64 -f ./docker-build/Dockerfile -t "breezy-kwin:amd64" --load .
docker buildx build --platform linux/amd64 -f ./docker-build/Dockerfile.steamos-3.8 -t "breezy-kwin-steamos-3.8:amd64" --load . # docker buildx build --platform linux/arm64 -f ./docker-build/Dockerfile -t "breezy-kwin:arm64" --load .
docker buildx build --platform linux/amd64 -f ./docker-build/Dockerfile.steamos-3.9 -t "breezy-kwin-steamos-3.9:amd64" --load . docker buildx build --platform linux/amd64 -f ./docker-build/Dockerfile.steamos -t "breezy-kwin-steamos:amd64" --load .

View File

@ -5,10 +5,22 @@ set -e
USER=${SUDO_USER:-$USER} USER=${SUDO_USER:-$USER}
GROUP=$(id -gn $USER) GROUP=$(id -gn $USER)
# only SteamOS is pre-built # Run containers for each architecture
if [[ "$1" == steamos-* || -z "$1" ]]; then if [[ "$1" == "x86_64" || -z "$1" ]]; then
sudo rm -rf build/ sudo rm -rf build/
docker run --rm -t -v ./:/source --platform linux/amd64 "breezy-kwin-$1:amd64" docker run --rm -t -v ./:/source --platform linux/amd64 "breezy-kwin:amd64"
sudo chown -R $USER:$GROUP out/
fi
if [[ "$1" == "aarch64" || -z "$1" ]]; then
sudo rm -rf build/
docker run --rm -t -v ./:/source --platform linux/arm64 "breezy-kwin:arm64"
sudo chown -R $USER:$GROUP out/
fi
if [[ "$1" == "steamos" || -z "$1" ]]; then
sudo rm -rf build/
docker run --rm -t -v ./:/source --platform linux/amd64 "breezy-kwin-steamos:amd64"
sudo chown -R $USER:$GROUP out/ sudo chown -R $USER:$GROUP out/
fi fi

View File

@ -2,7 +2,6 @@
#include "core/rendertarget.h" #include "core/rendertarget.h"
#include "core/renderviewport.h" #include "core/renderviewport.h"
#include "cursor.h" #include "cursor.h"
#include "input.h"
#include "pointer_input.h" #include "pointer_input.h"
#include "kcm/shortcuts.h" #include "kcm/shortcuts.h"
#include "breezydesktopeffect.h" #include "breezydesktopeffect.h"
@ -1006,28 +1005,10 @@ void BreezyDesktopEffect::warpPointerToOutputCenter(ScreenOutput *output)
} }
const QRect geometry = output->geometry(); const QRect geometry = output->geometry();
const QPointF center = geometry.center(); const QPointF center = geometry.center();
Cursors::self()->mouse()->setPos(center);
bool warped = false; // When warping, we don't have a meaningful previous position; use center for both.
if (InputRedirection *inputRedirection = input(); inputRedirection && inputRedirection->supportsPointerWarping()) { evaluateCursorOnScreenState(center, center);
inputRedirection->warpPointer(center);
warped = true;
} else if (auto *mouseCursor = Cursors::self()->mouse(); mouseCursor) {
mouseCursor->setPos(center);
warped = true;
}
if (!warped) {
return;
}
const QPointF newPos = center - effects->cursorImage().hotSpot();
const QPointF prevPos = m_cursorPos;
if (m_cursorPos != newPos) {
m_cursorPos = newPos;
Q_EMIT cursorPosChanged();
}
evaluateCursorOnScreenState(prevPos, newPos);
} }
void BreezyDesktopEffect::moveCursorToFocusedDisplay() void BreezyDesktopEffect::moveCursorToFocusedDisplay()

View File

@ -10,7 +10,6 @@ Item {
readonly property var supportedModels: [ readonly property var supportedModels: [
"VITURE", "VITURE",
"VITURE Beast",
"nreal air", "nreal air",
"Air", "Air",
"Air 2", "Air 2",

@ -1 +1 @@
Subproject commit dd0d592130b7fb8bc0923d2df6238e0c6a8b419b Subproject commit 33f15b0e15b141e7664afcc4c09d2c19b62716c0

View File

@ -1,5 +1,6 @@
import sys import sys
from gi.repository import GObject, GLib import threading
from gi.repository import GObject
from .xrdriveripc import XRDriverIPC from .xrdriveripc import XRDriverIPC
class ConfigManager(GObject.GObject): class ConfigManager(GObject.GObject):
@ -59,15 +60,10 @@ class ConfigManager(GObject.GObject):
self.neck_saver_horizontal_multiplier = None self.neck_saver_horizontal_multiplier = None
self.neck_saver_vertical_multiplier = None self.neck_saver_vertical_multiplier = None
self._running = True self._running = True
self._refresh_source_id = None
self._refresh_config() self._refresh_config()
self._refresh_source_id = GLib.timeout_add_seconds(1, self._refresh_config)
def stop(self): def stop(self):
self._running = False self._running = False
if self._refresh_source_id is not None:
GLib.source_remove(self._refresh_source_id)
self._refresh_source_id = None
def _refresh_config(self): def _refresh_config(self):
self.config = self.ipc.retrieve_config(False) self.config = self.ipc.retrieve_config(False)
@ -95,7 +91,7 @@ class ConfigManager(GObject.GObject):
if self.config['neck_saver_vertical_multiplier'] != self.neck_saver_vertical_multiplier: if self.config['neck_saver_vertical_multiplier'] != self.neck_saver_vertical_multiplier:
self.set_property('neck-saver-vertical-multiplier', self.config['neck_saver_vertical_multiplier']) self.set_property('neck-saver-vertical-multiplier', self.config['neck_saver_vertical_multiplier'])
return self._running if self._running: threading.Timer(1.0, self._refresh_config).start()
def _is_breezy_desktop_enabled(self): def _is_breezy_desktop_enabled(self):
return self.config.get('disabled') == False and 'breezy_desktop' in self.config.get('external_mode', []) return self.config.get('disabled') == False and 'breezy_desktop' in self.config.get('external_mode', [])

View File

@ -1,5 +1,6 @@
import sys import sys
from gi.repository import GObject, GLib import threading
from gi.repository import GObject
from .time import LICENSE_WARN_SECONDS from .time import LICENSE_WARN_SECONDS
from .xrdriveripc import XRDriverIPC from .xrdriveripc import XRDriverIPC
@ -65,21 +66,14 @@ class StateManager(GObject.GObject):
self.connected_device_full_distance_cm = 0.0 self.connected_device_full_distance_cm = 0.0
self.connected_device_full_size_cm = 0.0 self.connected_device_full_size_cm = 0.0
self._running = True self._running = True
self._refresh_source_id = None
self._refresh_state() self._refresh_state()
self._refresh_source_id = GLib.timeout_add_seconds(1, self._refresh_state)
def stop(self): def stop(self):
self._running = False self._running = False
if self._refresh_source_id is not None:
GLib.source_remove(self._refresh_source_id)
self._refresh_source_id = None
def _refresh_state(self): def _refresh_state(self):
self.state = self.ipc.retrieve_driver_state() self.state = self.ipc.retrieve_driver_state()
driver_running = self.state['ui_view'].get('driver_running') self.set_property('driver-running', self.state['ui_view'].get('driver_running'))
if driver_running != self.driver_running:
self.set_property('driver-running', driver_running)
new_device_name = StateManager.device_name(self.state) new_device_name = StateManager.device_name(self.state)
if self.connected_device_name != new_device_name: if self.connected_device_name != new_device_name:
@ -106,21 +100,10 @@ class StateManager(GObject.GObject):
# only update these properties if a device is still connected # only update these properties if a device is still connected
if (self.connected_device_name): if (self.connected_device_name):
follow_mode = self.state.get('breezy_desktop_smooth_follow_enabled', False) self.set_property('follow-mode', self.state.get('breezy_desktop_smooth_follow_enabled', False))
if follow_mode != self.follow_mode: self.set_property('device-supports-sbs', self.state.get('sbs_mode_supported', False))
self.set_property('follow-mode', follow_mode) self.set_property('widescreen-mode', self.state.get('sbs_mode_enabled', False))
self.set_property('connected-device-pose-has-position', self.state.get('connected_device_pose_has_position', False) == True)
device_supports_sbs = self.state.get('sbs_mode_supported', False)
if device_supports_sbs != self.device_supports_sbs:
self.set_property('device-supports-sbs', device_supports_sbs)
widescreen_mode = self.state.get('sbs_mode_enabled', False)
if widescreen_mode != self.widescreen_mode:
self.set_property('widescreen-mode', widescreen_mode)
pose_has_position = (self.state.get('connected_device_pose_has_position', False) == True)
if pose_has_position != self.connected_device_pose_has_position:
self.set_property('connected-device-pose-has-position', pose_has_position)
full_distance = self.state.get('connected_device_full_distance_cm') or 0.0 full_distance = self.state.get('connected_device_full_distance_cm') or 0.0
if full_distance != self.connected_device_full_distance_cm: if full_distance != self.connected_device_full_distance_cm:
@ -130,7 +113,7 @@ class StateManager(GObject.GObject):
if full_size != self.connected_device_full_size_cm: if full_size != self.connected_device_full_size_cm:
self.set_property('connected-device-full-size-cm', full_size) self.set_property('connected-device-full-size-cm', full_size)
return self._running if self._running: threading.Timer(1.0, self._refresh_state).start()
def do_set_property(self, prop, value): def do_set_property(self, prop, value):
if prop.name == 'driver-running': if prop.name == 'driver-running':

View File

@ -6,7 +6,6 @@ set -e
declare -A file_paths declare -A file_paths
file_paths=( file_paths=(
["bin/breezy_vulkan_uninstall"]="{bin_dir}/breezy_vulkan_uninstall" ["bin/breezy_vulkan_uninstall"]="{bin_dir}/breezy_vulkan_uninstall"
["bin/breezy_vulkan_logs"]="{bin_dir}/breezy_vulkan_logs"
["vkBasalt.64/libvkbasalt.so"]="{lib_dir}/libvkbasalt.so" ["vkBasalt.64/libvkbasalt.so"]="{lib_dir}/libvkbasalt.so"
["vkBasalt.32/libvkbasalt.so"]="{lib32_dir}/libvkbasalt.so" ["vkBasalt.32/libvkbasalt.so"]="{lib32_dir}/libvkbasalt.so"
["Sombrero.frag"]="{reshade_config_dir}/Shaders/Sombrero.frag" ["Sombrero.frag"]="{reshade_config_dir}/Shaders/Sombrero.frag"

View File

@ -14,6 +14,9 @@ if [ -z "$XDG_DATA_HOME" ]; then
XDG_DATA_HOME="$USER_HOME/.local/share" XDG_DATA_HOME="$USER_HOME/.local/share"
fi fi
DATA_DIR="$XDG_DATA_HOME/breezy_vulkan" DATA_DIR="$XDG_DATA_HOME/breezy_vulkan"
if [ ! -d "$DATA_DIR" ]; then
mkdir -p $DATA_DIR
fi
VULKAN_DATA_DIR="$XDG_DATA_HOME/vulkan" VULKAN_DATA_DIR="$XDG_DATA_HOME/vulkan"
XR_DRIVER_DATA_DIR="$XDG_DATA_HOME/xr_driver" XR_DRIVER_DATA_DIR="$XDG_DATA_HOME/xr_driver"
@ -32,15 +35,27 @@ if [ -z "$XDG_BIN_HOME" ]; then
fi fi
OLD_BIN_DIR="$USER_HOME/bin" OLD_BIN_DIR="$USER_HOME/bin"
BIN_DIR="$XDG_BIN_HOME" BIN_DIR="$XDG_BIN_HOME"
if [ ! -d "$BIN_DIR" ]; then
mkdir -p $BIN_DIR
fi
if [ -z "$XDG_STATE_HOME" ]; then if [ -z "$XDG_STATE_HOME" ]; then
XDG_STATE_HOME="$USER_HOME/.local/state" XDG_STATE_HOME="$USER_HOME/.local/state"
fi fi
STATE_DIR="$XDG_STATE_HOME/breezy_vulkan" STATE_DIR="$XDG_STATE_HOME/breezy_vulkan"
if [ ! -d "$STATE_DIR" ]; then
mkdir -p $STATE_DIR
fi
LIB_DIR="$USER_HOME/.local/lib" LIB_DIR="$USER_HOME/.local/lib"
if [ ! -d "$LIB_DIR" ]; then
mkdir -p "$LIB_DIR"
fi
LIB32_DIR="$USER_HOME/.local/lib32" LIB32_DIR="$USER_HOME/.local/lib32"
if [ ! -d "$LIB32_DIR" ]; then
mkdir -p "$LIB32_DIR"
fi
if [ -e "$USER_HOME/bin/breezy_vulkan_uninstall" ]; then if [ -e "$USER_HOME/bin/breezy_vulkan_uninstall" ]; then
echo "Cleaning up the previous installation" echo "Cleaning up the previous installation"
@ -75,7 +90,6 @@ ESCAPED_DATA_DIR=$(printf '%s\n' "$DATA_DIR" | sed -e 's/[\/&]/\\&/g')
ESCAPED_XR_DRIVER_DATA_DIR=$(printf '%s\n' "$XR_DRIVER_DATA_DIR" | sed -e 's/[\/&]/\\&/g') ESCAPED_XR_DRIVER_DATA_DIR=$(printf '%s\n' "$XR_DRIVER_DATA_DIR" | sed -e 's/[\/&]/\\&/g')
echo "Copying the breezy_vulkan scripts to ${BIN_DIR} and related files to ${DATA_DIR}" echo "Copying the breezy_vulkan scripts to ${BIN_DIR} and related files to ${DATA_DIR}"
mkdir -p "$BIN_DIR"
cp bin/breezy_vulkan_uninstall $BIN_DIR cp bin/breezy_vulkan_uninstall $BIN_DIR
cp bin/breezy_vulkan_logs $BIN_DIR cp bin/breezy_vulkan_logs $BIN_DIR
sed -i -e "s/{bin_dir}/$ESCAPED_BIN_DIR/g" \ sed -i -e "s/{bin_dir}/$ESCAPED_BIN_DIR/g" \
@ -87,8 +101,7 @@ sed -i -e "s/{bin_dir}/$ESCAPED_BIN_DIR/g" \
-e "s/{xr_driver_data_dir}/$ESCAPED_XR_DRIVER_DATA_DIR/g" \ -e "s/{xr_driver_data_dir}/$ESCAPED_XR_DRIVER_DATA_DIR/g" \
bin/breezy_vulkan_verify bin/breezy_vulkan_verify
cp bin/breezy_vulkan_verify $BIN_DIR cp bin/breezy_vulkan_verify $BIN_DIR
mkdir -p "$DATA_DIR" cp manifest $DATA_DIR
cp manifest "$DATA_DIR/manifest"
# keep putting this in the old location in case an older version of the script tries to find it # keep putting this in the old location in case an older version of the script tries to find it
if [ ! -d "$OLD_BIN_DIR" ]; then if [ ! -d "$OLD_BIN_DIR" ]; then
@ -102,8 +115,6 @@ echo "Installing vkBasalt; copying binaries, configs, and shader files"
# copy the vkBasalt binaries and configs # copy the vkBasalt binaries and configs
mkdir -p "$VULKAN_DATA_DIR"/implicit_layer.d mkdir -p "$VULKAN_DATA_DIR"/implicit_layer.d
mkdir -p "$XDG_CONFIG_HOME"/{vkBasalt,reshade/Shaders,reshade/Textures} mkdir -p "$XDG_CONFIG_HOME"/{vkBasalt,reshade/Shaders,reshade/Textures}
mkdir -p "$LIB_DIR"
mkdir -p "$LIB32_DIR"
cp vkBasalt.64/libvkbasalt.so $LIB_DIR/ cp vkBasalt.64/libvkbasalt.so $LIB_DIR/
cp vkBasalt.32/libvkbasalt.so $LIB32_DIR/ cp vkBasalt.32/libvkbasalt.so $LIB32_DIR/
@ -132,8 +143,6 @@ cp *.frag $GAMESCOPE_RESHADE_SHADERS_DIR
cp *.fx* $GAMESCOPE_RESHADE_SHADERS_DIR cp *.fx* $GAMESCOPE_RESHADE_SHADERS_DIR
cp *.png $GAMESCOPE_RESHADE_TEXTURES_DIR cp *.png $GAMESCOPE_RESHADE_TEXTURES_DIR
mkdir -p "$STATE_DIR"
chown -R $USER:$GROUP $LIB_DIR chown -R $USER:$GROUP $LIB_DIR
chown -R $USER:$GROUP $LIB32_DIR chown -R $USER:$GROUP $LIB32_DIR
chown -R $USER:$GROUP $DATA_DIR chown -R $USER:$GROUP $DATA_DIR