Merge branch 'main' into gnome-44-max
This commit is contained in:
commit
6d6a658353
43
README.md
43
README.md
|
|
@ -16,11 +16,19 @@ There are two installations at the moment. **Note: Only install one of these at
|
|||
Breezy GNOME is a virtual workspace solution for Linux desktops that use the GNOME desktop environment (requires GNOME 45+ on an x86_64 system); see [non-GNOME setup](#non-gnome-setup) if you want to try it without a GNOME desktop environment. It currently supports one virtual monitor and multiple physical monitors, but it will soon support multiple virtual monitors. See [upcoming features](#upcoming-features) for more improvements on the horizon.
|
||||
|
||||
### GNOME Setup
|
||||
1. Ensure you have the latest graphics drivers installed for your distro.
|
||||
2. Download the Breezy GNOME [setup script](https://github.com/wheaney/breezy-desktop/releases/latest/download/breezy_gnome_setup) and set the execute flag (e.g. from the terminal: `chmod +x ~/Downloads/breezy_gnome_setup`)
|
||||
3. Run the setup script (e.g. `~/Downloads/breezy_gnome_setup`)
|
||||
4. 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.
|
||||
5. 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**
|
||||
|
||||
For the best performance, ensure you have the latest graphics drivers installed for your distro. Also, double-check that your glasses are extending your workspace and not just mirroring your primary monitor by opening up the `Displays` settings dialog and choosing the `Join` option for multiple displays.
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
*Note: if you've previously installed Breezy GNOME using the setup script, you must uninstall it first: `~/.local/bin/breezy_gnome_uninstall`*
|
||||
|
||||
Breezy GNOME is in AUR (but not pacman, yet). To install: `yay -S breezy-desktop-gnome-git` and, once that succeeds, `systemctl --user enable --now xreal-air-driver.service`
|
||||
|
||||
#### All other distros
|
||||
|
||||
1. Download the Breezy GNOME [setup script](https://github.com/wheaney/breezy-desktop/releases/latest/download/breezy_gnome_setup) and set the execute flag (e.g. from the terminal: `chmod +x ~/Downloads/breezy_gnome_setup`)
|
||||
2. Run the setup script (e.g. `~/Downloads/breezy_gnome_setup`)
|
||||
|
||||
### Non-GNOME Setup
|
||||
A workable solution (with some [QoL improvements needed](#upcoming-features)) is to use your preferred desktop environment with a GNOME window open in nested mode. To do this:
|
||||
|
|
@ -29,7 +37,10 @@ A workable solution (with some [QoL improvements needed](#upcoming-features)) is
|
|||
3. Launch the nested GNOME Shell using `MUTTER_DEBUG_DUMMY_MODE_SPECS="1920x1080@60" dbus-run-session -- gnome-shell --nested`
|
||||
|
||||
### Breezy GNOME Usage
|
||||
All controls are provided through the Breezy Desktop application. 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.**
|
||||
|
||||
### Upcoming Features
|
||||
1. Port to GNOME 43/44
|
||||
|
|
@ -76,7 +87,7 @@ If you don't receive a token, you can request one in the `License Details` view
|
|||
|
||||
#### Steam Deck via Decky Loader
|
||||
|
||||
For Steam Deck users, the driver is now available via the [Decky plugin loader](https://github.com/SteamDeckHomebrew/decky-loader). Just search "xreal" in the Decky store to install and use without leaving Gaming Mode. You can now enable or disable the driver and manage other driver settings via the Decky sidebar menu.
|
||||
For Steam Deck users, the driver is now available via the [Decky plugin loader](https://github.com/SteamDeckHomebrew/decky-loader). Just search "xr" in the Decky store to install and use without leaving Gaming Mode. You can now enable or disable the driver and manage other driver settings via the Decky sidebar menu.
|
||||
|
||||
You may still opt to do a manual installation using the instructions below if you enter Desktop Mode.
|
||||
|
||||
|
|
@ -91,13 +102,13 @@ See [XRLinuxDriver's supported devices](https://github.com/wheaney/XRLinuxDriver
|
|||
|
||||
### Usage
|
||||
|
||||
Once installed, you'll want to make sure you've enabled the driver (`~/bin/xreal_driver_config -e`) and then you can go into whichever output mode you'd like using (`~/bin/xreal_driver_config -m`) where `-m` is for mouse mode, `-j` for joystick, `-vd` for virtual display, and `-sv` for sideview; note that these two commands can't be combined, they have to be done separately. From there, you should be able to launch any Vulkan game, plug in your glasses (at any point, not just after launching), and see a floating virtual display or a sideview screen (depending on which mode you've chosen).
|
||||
Once installed, you'll want to make sure you've enabled the driver (`xr_driver_cli -e`) and then you can go into whichever output mode you'd like using (`xr_driver_cli -m`) where `-m` is for mouse mode, `-j` for joystick, `-vd` for virtual display, and `-sv` for sideview; note that these two commands can't be combined, they have to be done separately. From there, you should be able to launch any Vulkan game, plug in your glasses (at any point, not just after launching), and see a floating virtual display or a sideview screen (depending on which mode you've chosen).
|
||||
|
||||
There's a wait period of 15 seconds after plugging in XREAL glasses where the screen will stay static to allow for the glasses to calibrate. Once ready, the screen will anchor to the space where you are looking.
|
||||
|
||||
### Configurations
|
||||
|
||||
To see all the configuration options available to you, type `~/bin/xreal_driver_config` with no parameters to get the usage statement. There are some things you can't trigger from the script, like re-centering the virtual display or entering SBS mode; you can achieve these things through multi-tap or through the physical buttons on the glasses, respectively.
|
||||
To see all the configuration options available to you, type `xr_driver_cli` with no parameters to get the usage statement. There are some things you can't trigger from the script, like re-centering the virtual display or entering SBS mode; you can achieve these things through multi-tap or through the physical buttons on the glasses, respectively.
|
||||
|
||||
#### Multi-tap to re-center or re-calibrate
|
||||
I've implemented an experimental multi-tap detection feature for screen **re-centering (2 taps)** and **re-calibrating the device (3 taps)**. To perform a multi-tap, you'll want to give decent taps on the top of the glasses. I tend to do this on the corner, right on top of the hinge. It should be a firm, sharp tap, and wait just a split second to do the second tap, as it needs to detect a slight pause in between (but it also shouldn't take more than a half a second between taps so don't wait too long).
|
||||
|
|
@ -124,18 +135,18 @@ Features currently offered:
|
|||
|
||||
If you donate at least $10, you should immediately receive an email (to your Ko-fi email address) with a verification token. If you don't, request it using the config script:
|
||||
```bash
|
||||
~/bin/xreal_driver_config --request-token [emailAddress]
|
||||
xr_driver_cli --request-token [emailAddress]
|
||||
```
|
||||
|
||||
Once you have a token, verify it using:
|
||||
```bash
|
||||
~/bin/xreal_driver_config --verify-token [token]
|
||||
~/bin/xreal_driver_config --refresh-license
|
||||
xr_driver_cli --verify-token [token]
|
||||
xr_driver_cli --refresh-license
|
||||
```
|
||||
|
||||
### Disabling
|
||||
|
||||
To disable the floating screen effect, either disable the driver (`~/bin/xreal_driver_config -d`), unplug the glasses, or hit the `Home` key (you'll need to bind this to your controller, if on Steam Deck).
|
||||
To disable the floating screen effect, either disable the driver (`xr_driver_cli -d`), unplug the glasses, or hit the `Home` key (you'll need to bind this to your controller, if on Steam Deck).
|
||||
|
||||
### Updating
|
||||
|
||||
|
|
@ -143,7 +154,11 @@ Rerun the `breezy_vulkan_setup` script. No need to re-download this script, as i
|
|||
|
||||
### Uninstalling
|
||||
|
||||
If you wish to completely remove the installation, run the following: `sudo ~/bin/breezy_vulkan_uninstall`. This won't uninstall the base driver package, follow the instructions at the end of the uninstallation to do this manually.
|
||||
If you wish to completely remove the installation:
|
||||
* For **Breezy GNOME**:
|
||||
* If you installed *via the setup script* run the following: `~/.local/bin/breezy_gnome_uninstall`
|
||||
* If you installed via `yay` run the following: `pacman -R breezy-desktop-gnome-git`, you may also want to uninstall the base driver with `pacman -R xr-driver-breezy-gnome-git`
|
||||
* For **Breezy Vulkan** run the following: `~/.local/bin/breezy_vulkan_uninstall`. This won't uninstall the base driver package, follow the instructions at the end of the uninstallation to do this manually.
|
||||
|
||||
## Data Privacy Notice
|
||||
|
||||
|
|
|
|||
|
|
@ -13,19 +13,21 @@ fi
|
|||
|
||||
start_dir=$(pwd)
|
||||
|
||||
ARCH=$(uname -m)
|
||||
|
||||
# create temp directory
|
||||
tmp_dir=$(mktemp -d -t breezy-gnome-XXXXXXXXXX)
|
||||
pushd $tmp_dir > /dev/null
|
||||
echo "Created temp directory: ${tmp_dir}"
|
||||
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/latest/download/breezyGNOME.tar.gz"
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/latest/download/breezyGNOME-$ARCH.tar.gz"
|
||||
if [ "$1" = "-v" ]
|
||||
then
|
||||
metrics_version="$2"
|
||||
binary_path_arg="$3"
|
||||
elif [ "$1" = "--tag" ] && [ -n "$2" ]
|
||||
then
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/download/$2/breezyGNOME.tar.gz"
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/download/$2/breezyGNOME-$ARCH.tar.gz"
|
||||
else
|
||||
binary_path_arg="$1"
|
||||
fi
|
||||
|
|
@ -33,8 +35,9 @@ fi
|
|||
if [ -z "$binary_path_arg" ]
|
||||
then
|
||||
# download and unzip the binary
|
||||
echo "Downloading to: ${tmp_dir}/breezyGNOME.tar.gz"
|
||||
echo "Downloading to: ${tmp_dir}/breezyGNOME-$ARCH.tar.gz"
|
||||
curl -L -O $binary_download_url
|
||||
binary_path_arg="breezyGNOME-$ARCH.tar.gz"
|
||||
else
|
||||
if [[ "$binary_path_arg" = /* ]]; then
|
||||
abs_path="$binary_path_arg"
|
||||
|
|
@ -45,16 +48,8 @@ else
|
|||
cp $abs_path $tmp_dir
|
||||
fi
|
||||
|
||||
# if abs_path is present, grab the filename from it
|
||||
if [ -n "$abs_path" ]
|
||||
then
|
||||
filename=$(basename $abs_path)
|
||||
else
|
||||
filename="breezyGNOME.tar.gz"
|
||||
fi
|
||||
|
||||
echo "Extracting to: ${tmp_dir}/breezy_gnome"
|
||||
tar -xf $filename
|
||||
tar -xf $(basename $binary_path_arg)
|
||||
|
||||
pushd breezy_gnome > /dev/null
|
||||
|
||||
|
|
|
|||
|
|
@ -14,17 +14,25 @@ fi
|
|||
|
||||
start_dir=$(pwd)
|
||||
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" != "x86_64" ]; then
|
||||
echo "Breezy Vulkan only supports x86_64 currently"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create temp directory
|
||||
tmp_dir=$(mktemp -d -t breezy-vulkan-XXXXXXXXXX)
|
||||
pushd $tmp_dir > /dev/null
|
||||
echo "Created temp directory: ${tmp_dir}"
|
||||
|
||||
# if the first argument is "-v" then the second argument is metrics version, and the third argument is binary path
|
||||
# otherwise, if the first argument is present, it's the binary path
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/latest/download/breezyVulkan-$ARCH.tar.gz"
|
||||
if [ "$1" = "-v" ]
|
||||
then
|
||||
metrics_version="$2"
|
||||
binary_path_arg="$3"
|
||||
elif [ "$1" = "--tag" ] && [ -n "$2" ]
|
||||
then
|
||||
binary_download_url="https://github.com/wheaney/breezy-desktop/releases/download/$2/breezyVulkan-$ARCH.tar.gz"
|
||||
else
|
||||
binary_path_arg="$1"
|
||||
fi
|
||||
|
|
@ -32,8 +40,9 @@ fi
|
|||
if [ -z "$binary_path_arg" ]
|
||||
then
|
||||
# download and unzip the latest driver
|
||||
echo "Downloading latest release to: ${tmp_dir}/breezyVulkan.tar.gz"
|
||||
curl -L -O https://github.com/wheaney/breezy-desktop/releases/latest/download/breezyVulkan.tar.gz
|
||||
echo "Downloading to: ${tmp_dir}/breezyVulkan-$ARCH.tar.gz"
|
||||
curl -L -O $binary_download_url
|
||||
binary_path_arg="breezyVulkan-$ARCH.tar.gz"
|
||||
else
|
||||
if [[ "$binary_path_arg" = /* ]]; then
|
||||
abs_path="$binary_path_arg"
|
||||
|
|
@ -45,7 +54,7 @@ else
|
|||
fi
|
||||
|
||||
echo "Extracting to: ${tmp_dir}/breezy_vulkan"
|
||||
tar -xf breezyVulkan.tar.gz
|
||||
tar -xf $(basename $binary_path_arg)
|
||||
|
||||
pushd breezy_vulkan > /dev/null
|
||||
|
||||
|
|
|
|||
|
|
@ -3,25 +3,28 @@
|
|||
# exit when any command fails
|
||||
set -e
|
||||
|
||||
ARCH=${ARCH:-$(uname -m)}
|
||||
echo "Building Breezy GNOME for $ARCH"
|
||||
|
||||
# https://stackoverflow.com/a/246128
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
ROOT_DIR=$(realpath $SCRIPT_DIR/..)
|
||||
VULKAN_DIR=$ROOT_DIR/vulkan
|
||||
GNOME_DIR=$ROOT_DIR/gnome
|
||||
GNOME_BUILD_DIR=$GNOME_DIR/build
|
||||
BUILD_FILE_NAME=breezyGNOME-$ARCH.tar.gz
|
||||
|
||||
rm -rf $GNOME_BUILD_DIR
|
||||
mkdir -p $GNOME_BUILD_DIR
|
||||
if [ -e "$GNOME_BUILD_DIR/$BUILD_FILE_NAME" ]; then
|
||||
rm $GNOME_BUILD_DIR/$BUILD_FILE_NAME
|
||||
fi
|
||||
|
||||
PACKAGE_DIR=$GNOME_BUILD_DIR/breezy_gnome
|
||||
rm -rf $PACKAGE_DIR
|
||||
mkdir -p $PACKAGE_DIR
|
||||
|
||||
XREAL_DRIVER_DIR=$ROOT_DIR/modules/XRLinuxDriver
|
||||
source $XREAL_DRIVER_DIR/bin/inject_ua
|
||||
|
||||
# check out submodules, recursively for nested ones
|
||||
git submodule update --init --recursive
|
||||
XR_DRIVER_DIR=$ROOT_DIR/modules/XRLinuxDriver
|
||||
source $XR_DRIVER_DIR/bin/inject_ua
|
||||
|
||||
# if a custom_banner image exists, copy it over the sombrero one
|
||||
if [ -e "$VULKAN_DIR/custom_banner.png" ]; then
|
||||
|
|
@ -30,48 +33,63 @@ fi
|
|||
|
||||
# copy vulkan setup scripts and configs
|
||||
mkdir -p $PACKAGE_DIR/bin
|
||||
copy_and_inject_ua "$XREAL_DRIVER_DIR/bin/ua.sh" "$PACKAGE_DIR/bin" "$GNOME_DIR/bin/setup" "$GNOME_DIR/bin/breezy_gnome_verify" "$GNOME_DIR/bin/breezy_gnome_uninstall"
|
||||
copy_and_inject_ua "$XR_DRIVER_DIR/bin/ua.sh" "$PACKAGE_DIR/bin" "$GNOME_DIR/bin/setup" "$GNOME_DIR/bin/breezy_gnome_verify" "$GNOME_DIR/bin/breezy_gnome_uninstall"
|
||||
|
||||
XREAL_BINARY=$XREAL_DRIVER_DIR/build/xrealAirLinuxDriver.tar.gz
|
||||
pushd $XREAL_DRIVER_DIR
|
||||
XR_DRIVER_BINARY=$XR_DRIVER_DIR/out/xrDriver-$ARCH.tar.gz
|
||||
|
||||
if [ ! -e "$XREAL_BINARY" ] || [ "$1" != "--skip-module-builds" ]; then
|
||||
if [ ! -e "$XR_DRIVER_BINARY" ] || [ "$1" == "--rebuild-driver" ]; then
|
||||
# if a file exists at custom_banner_config.yml, copy it to the xrealAirLinuxDriver directory
|
||||
if [ -e "$VULKAN_DIR/custom_banner_config.yml" ]; then
|
||||
cp $VULKAN_DIR/custom_banner_config.yml $XREAL_DRIVER_DIR
|
||||
cp $VULKAN_DIR/custom_banner_config.yml $XR_DRIVER_DIR
|
||||
fi
|
||||
|
||||
pushd $XR_DRIVER_DIR
|
||||
|
||||
# strange issue where the base library produces a .so file if the build is not cleaned
|
||||
rm -rf build/
|
||||
|
||||
BREEZY_DESKTOP=1 bin/package
|
||||
docker-build/init.sh
|
||||
BREEZY_DESKTOP=1 docker-build/run-build.sh $ARCH
|
||||
popd
|
||||
fi
|
||||
|
||||
XREAL_MANIFEST_LINE=$(sha256sum build/driver_air_glasses/manifest)
|
||||
popd
|
||||
TMP_DIR=$(mktemp -d -t breezy-gnome-XXXXXXXXXX)
|
||||
pushd $TMP_DIR
|
||||
cp $XR_DRIVER_BINARY $TMP_DIR/xrDriver.tar.gz
|
||||
tar -xf $TMP_DIR/xrDriver.tar.gz
|
||||
|
||||
cp $XREAL_BINARY $PACKAGE_DIR
|
||||
cp $XREAL_DRIVER_DIR/bin/xreal_driver_setup $PACKAGE_DIR/bin
|
||||
XR_DRIVER_MANIFEST_LINE=$(sha256sum xr_driver/manifest)
|
||||
popd
|
||||
rm -rf $TMP_DIR
|
||||
|
||||
cp $XR_DRIVER_BINARY $PACKAGE_DIR/xrDriver.tar.gz
|
||||
cp $XR_DRIVER_DIR/bin/xr_driver_setup $PACKAGE_DIR/bin
|
||||
|
||||
gnome/bin/package_extension
|
||||
cp gnome/out/* $PACKAGE_DIR
|
||||
cp gnome/out/breezydesktop@xronlinux.com.shell-extension.zip $PACKAGE_DIR
|
||||
|
||||
# create a checksum that combines the checksums of all files in the directory
|
||||
pushd gnome/src
|
||||
GNOME_MANIFEST_LINE=$(find -L . -type f ! -name "*.compiled" -exec sha256sum {} \; | sort | sha256sum | sed 's/ .*//')
|
||||
popd
|
||||
|
||||
ui/bin/package
|
||||
cp ui/out/* $PACKAGE_DIR
|
||||
ui/bin/package $ARCH
|
||||
cp ui/out/com.xronlinux.BreezyDesktop-$ARCH.flatpak $PACKAGE_DIR/com.xronlinux.BreezyDesktop.flatpak
|
||||
|
||||
# create manifest file for verifying installed file checksums against the originally packaged versions
|
||||
# include any file that doesn't get modified during setup (e.g. vkBasalt.json files)
|
||||
pushd $PACKAGE_DIR
|
||||
echo $XREAL_MANIFEST_LINE > manifest
|
||||
echo $XR_DRIVER_MANIFEST_LINE > manifest
|
||||
echo -e "$GNOME_MANIFEST_LINE breezydesktop@xronlinux.com" >> manifest
|
||||
popd
|
||||
|
||||
# bundle everything up
|
||||
pushd $GNOME_BUILD_DIR
|
||||
tar -zcvf breezyGNOME.tar.gz breezy_gnome
|
||||
popd
|
||||
tar -zcvf $BUILD_FILE_NAME breezy_gnome
|
||||
popd
|
||||
|
||||
mkdir -p out
|
||||
if [ -e "out/$BUILD_FILE_NAME" ]; then
|
||||
rm out/$BUILD_FILE_NAME
|
||||
fi
|
||||
cp $GNOME_BUILD_DIR/$BUILD_FILE_NAME out
|
||||
|
|
@ -3,27 +3,28 @@
|
|||
# exit when any command fails
|
||||
set -e
|
||||
|
||||
XREAL_DRIVER_DIR=modules/XRLinuxDriver
|
||||
source $XREAL_DRIVER_DIR/bin/inject_ua
|
||||
ARCH=${ARCH:-$(uname -m)}
|
||||
echo "Building Breezy Vulkan for $ARCH"
|
||||
|
||||
# check out submodules, recursively for nested ones
|
||||
git submodule update --init --recursive
|
||||
XR_DRIVER_DIR=modules/XRLinuxDriver
|
||||
source $XR_DRIVER_DIR/bin/inject_ua
|
||||
|
||||
VULKAN_DIR=vulkan
|
||||
VULKAN_BUILD=$VULKAN_DIR/build
|
||||
if [ ! -d "$VULKAN_BUILD" ]; then
|
||||
mkdir -p $VULKAN_BUILD
|
||||
VULKAN_BUILD_DIR=$VULKAN_DIR/build
|
||||
if [ ! -d "$VULKAN_BUILD_DIR" ]; then
|
||||
mkdir -p $VULKAN_BUILD_DIR
|
||||
else
|
||||
rm -rf $VULKAN_BUILD/*
|
||||
rm -rf $VULKAN_BUILD_DIR/*
|
||||
fi
|
||||
|
||||
VULKAN_MODULES=$VULKAN_DIR/modules
|
||||
PACKAGE_DIR=$VULKAN_BUILD/breezy_vulkan
|
||||
PACKAGE_DIR=$VULKAN_BUILD_DIR/breezy_vulkan
|
||||
if [ ! -d "$PACKAGE_DIR" ]; then
|
||||
mkdir -p $PACKAGE_DIR
|
||||
else
|
||||
rm -rf $PACKAGE_DIR/*
|
||||
fi
|
||||
BUILD_FILE_NAME=breezyVulkan-$ARCH.tar.gz
|
||||
|
||||
# build vkBasalt
|
||||
VKBASALT_MODULE_DIR=$VULKAN_MODULES/vkBasalt
|
||||
|
|
@ -53,41 +54,55 @@ fi
|
|||
|
||||
# copy vulkan setup scripts and configs
|
||||
mkdir -p $PACKAGE_DIR/bin
|
||||
copy_and_inject_ua "$XREAL_DRIVER_DIR/bin/ua.sh" "$PACKAGE_DIR/bin" "$VULKAN_DIR/bin/setup" "$VULKAN_DIR/bin/verify_installation" "$VULKAN_DIR/bin/breezy_vulkan_uninstall"
|
||||
copy_and_inject_ua "$XR_DRIVER_DIR/bin/ua.sh" "$PACKAGE_DIR/bin" "$VULKAN_DIR/bin/setup" "$VULKAN_DIR/bin/breezy_vulkan_verify" "$VULKAN_DIR/bin/breezy_vulkan_uninstall"
|
||||
cp -r $VULKAN_DIR/config $PACKAGE_DIR
|
||||
|
||||
# build xreal driver
|
||||
XREAL_BINARY=$XREAL_DRIVER_DIR/build/xrealAirLinuxDriver.tar.gz
|
||||
# build XR driver
|
||||
XR_DRIVER_BINARY=$XR_DRIVER_DIR/out/xrDriver-$ARCH.tar.gz
|
||||
|
||||
if [ ! -e "$XREAL_BINARY" ] || [ "$1" != "--skip-module-builds" ]; then
|
||||
if [ ! -e "$XR_DRIVER_BINARY" ] || [ "$1" != "--skip-module-builds" ]; then
|
||||
# if a file exists at custom_banner_config.yml, copy it to the xrealAirLinuxDriver directory
|
||||
if [ -e "$VULKAN_DIR/custom_banner_config.yml" ]; then
|
||||
cp $VULKAN_DIR/custom_banner_config.yml $XREAL_DRIVER_DIR
|
||||
cp $VULKAN_DIR/custom_banner_config.yml $XR_DRIVER_DIR
|
||||
fi
|
||||
|
||||
pushd $XREAL_DRIVER_DIR
|
||||
pushd $XR_DRIVER_DIR
|
||||
|
||||
# strange issue where the base library produces a .so file if the build is not cleaned
|
||||
rm -rf build/
|
||||
|
||||
bin/package
|
||||
else
|
||||
pushd $XREAL_DRIVER_DIR
|
||||
docker-build/init.sh
|
||||
docker-build/run-build.sh $ARCH
|
||||
popd
|
||||
fi
|
||||
|
||||
XREAL_MANIFEST_LINE=$(sha256sum build/driver_air_glasses/manifest)
|
||||
popd
|
||||
TMP_DIR=$(mktemp -d -t breezy-vulkan-XXXXXXXXXX)
|
||||
cp $XR_DRIVER_BINARY $TMP_DIR/xrDriver.tar.gz
|
||||
pushd $TMP_DIR
|
||||
tar -xf $TMP_DIR/xrDriver.tar.gz
|
||||
|
||||
# copy xreal binary and setup script
|
||||
cp $XREAL_BINARY $PACKAGE_DIR
|
||||
cp $XREAL_DRIVER_DIR/bin/xreal_driver_setup $PACKAGE_DIR/bin
|
||||
XR_DRIVER_MANIFEST_LINE=$(sha256sum xr_driver/manifest)
|
||||
popd
|
||||
rm -rf $TMP_DIR
|
||||
|
||||
# copy XR driver binary and setup script
|
||||
cp $XR_DRIVER_BINARY $PACKAGE_DIR/xrDriver.tar.gz
|
||||
cp $XR_DRIVER_DIR/bin/xr_driver_setup $PACKAGE_DIR/bin
|
||||
|
||||
# create manifest file for verifying installed file checksums against the originally packaged versions
|
||||
# include any file that doesn't get modified during setup (e.g. vkBasalt.json files)
|
||||
pushd $PACKAGE_DIR
|
||||
echo $XREAL_MANIFEST_LINE > manifest
|
||||
echo $XR_DRIVER_MANIFEST_LINE > manifest
|
||||
sha256sum bin/breezy_vulkan_uninstall vkBasalt.64/libvkbasalt.so vkBasalt.32/libvkbasalt.so *.fx* *.png >> manifest
|
||||
popd
|
||||
|
||||
# bundle everything up
|
||||
tar -zcvf $VULKAN_BUILD/breezyVulkan.tar.gz --directory $VULKAN_BUILD breezy_vulkan
|
||||
pushd $VULKAN_BUILD_DIR
|
||||
tar -zcvf $BUILD_FILE_NAME breezy_vulkan
|
||||
popd
|
||||
|
||||
mkdir -p out
|
||||
if [ -e "out/$BUILD_FILE_NAME" ]; then
|
||||
rm out/$BUILD_FILE_NAME
|
||||
fi
|
||||
cp $VULKAN_BUILD_DIR/$BUILD_FILE_NAME out
|
||||
|
|
@ -42,9 +42,9 @@ flatpak uninstall --user --noninteractive --force-remove com.xronlinux.BreezyDe
|
|||
[ "$for_install" -eq 0 ] && echo "Uninstalling XRLinuxDriver"
|
||||
# if for-install
|
||||
if [ "$for_install" -eq 1 ]; then
|
||||
sudo ~/bin/xreal_driver_uninstall --for-install
|
||||
sudo ~/.local/bin/xr_driver_uninstall --for-install
|
||||
else
|
||||
sudo ~/bin/xreal_driver_uninstall
|
||||
sudo ~/.local/bin/xr_driver_uninstall
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,11 @@
|
|||
|
||||
set -e
|
||||
|
||||
USER_HOME=$(realpath ~)
|
||||
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME="$USER_HOME/.local/share"
|
||||
fi
|
||||
DATA_DIR="$XDG_DATA_HOME/breezy_gnome"
|
||||
|
||||
# create a string to string mapping, file name to expected file location
|
||||
declare -A file_paths
|
||||
file_paths=(
|
||||
["build/driver_air_glasses/manifest"]="$USER_HOME/.local/bin/xr_driver/manifest"
|
||||
["breezydesktop@xronlinux.com"]="$XDG_DATA_HOME/gnome-shell/extensions/breezydesktop@xronlinux.com"
|
||||
["xr_driver/manifest"]="{xr_driver_data_dir}/manifest"
|
||||
["breezydesktop@xronlinux.com"]="{gnome_shell_data_dir}/extensions/breezydesktop@xronlinux.com"
|
||||
)
|
||||
|
||||
# verify the file hashes in ./manifest
|
||||
|
|
@ -41,9 +34,9 @@ do
|
|||
echo "Verification failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
done < "$XDG_DATA_HOME/breezy_gnome/manifest"
|
||||
done < "{data_dir}/manifest"
|
||||
|
||||
# if our checks succeeded, run the xr_driver verify script
|
||||
$USER_HOME/.local/bin/xr_driver/verify_installation > /dev/null
|
||||
{bin_dir}/xr_driver_verify > /dev/null
|
||||
|
||||
echo "Verification succeeded"
|
||||
|
|
@ -5,11 +5,6 @@ UUID="breezydesktop@xronlinux.com"
|
|||
# fail on error
|
||||
set -e
|
||||
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
echo "This script must NOT be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# https://stackoverflow.com/a/246128
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,17 @@ check_command "gnome-extensions"
|
|||
|
||||
USER_HOME=$(realpath ~)
|
||||
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME="$USER_HOME/.local/share"
|
||||
fi
|
||||
XR_DRIVER_DATA_DIR="$XDG_DATA_HOME/xr_driver"
|
||||
GNOME_SHELL_DATA_DIR="$XDG_DATA_HOME/gnome-shell"
|
||||
DATA_DIR="$XDG_DATA_HOME/breezy_gnome"
|
||||
|
||||
if [ -z "$XDG_BIN_HOME" ]; then
|
||||
XDG_BIN_HOME="$USER_HOME/.local/bin"
|
||||
fi
|
||||
BIN_DIR="$XDG_BIN_HOME"
|
||||
|
||||
if [ -d "$XDG_BIN_HOME" ]; then
|
||||
# check ownership and permissions before doing chown and chmod
|
||||
|
|
@ -36,11 +44,6 @@ if [ -d "$XDG_BIN_HOME" ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME="$USER_HOME/.local/share"
|
||||
fi
|
||||
DATA_DIR="$XDG_DATA_HOME/breezy_gnome"
|
||||
|
||||
UA_EVENT_NAME="breezy_gnome_install"
|
||||
if [ -e "$XDG_BIN_HOME/breezy_gnome_uninstall" ]; then
|
||||
echo "Cleaning up the previous installation"
|
||||
|
|
@ -55,9 +58,20 @@ UA_CLIENT_ID="BreezyGNOME"
|
|||
UA_EVENT_VERSION="$1"
|
||||
#INJECT_UA_CALL
|
||||
|
||||
# escaping sed replace: https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
|
||||
ESCAPED_BIN_DIR=$(printf '%s\n' "$BIN_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
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_GNOME_SHELL_DATA_DIR=$(printf '%s\n' "$GNOME_SHELL_DATA_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
|
||||
echo "Copying the breezy_gnome scripts to ${XDG_BIN_HOME}"
|
||||
mkdir -p $XDG_BIN_HOME
|
||||
cp bin/breezy_gnome_uninstall $XDG_BIN_HOME
|
||||
sed -i -e "s/{bin_dir}/$ESCAPED_BIN_DIR/g" \
|
||||
-e "s/{data_dir}/$ESCAPED_DATA_DIR/g" \
|
||||
-e "s/{xr_driver_data_dir}/$ESCAPED_XR_DRIVER_DATA_DIR/g" \
|
||||
-e "s/{gnome_shell_data_dir}/$ESCAPED_GNOME_SHELL_DATA_DIR/g" \
|
||||
bin/breezy_gnome_verify
|
||||
cp bin/breezy_gnome_verify $XDG_BIN_HOME
|
||||
|
||||
echo "Copying the manifest file to ${DATA_DIR}"
|
||||
|
|
@ -70,20 +84,14 @@ gnome-extensions install --force breezydesktop@xronlinux.com.shell-extension.zip
|
|||
echo "Installing the Breezy Desktop UI Flatpak (this may take a couple minutes the first time)"
|
||||
flatpak install --user --noninteractive --reinstall com.xronlinux.BreezyDesktop.flatpak
|
||||
|
||||
# set up the XREAL driver using the local binary
|
||||
echo "Installing xrealAirLinuxDriver"
|
||||
echo "BEGIN - xreal_driver_setup"
|
||||
# set up the XR driver using the local binary
|
||||
echo "Installing xrDriver"
|
||||
echo "BEGIN - xr_driver_setup"
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
sudo bin/xreal_driver_setup $(pwd)/xrealAirLinuxDriver.tar.gz
|
||||
sudo bin/xr_driver_setup $(pwd)/xrDriver.tar.gz
|
||||
else
|
||||
sudo bin/xreal_driver_setup -v $1 $(pwd)/xrealAirLinuxDriver.tar.gz
|
||||
sudo bin/xr_driver_setup -v $1 $(pwd)/xrDriver.tar.gz
|
||||
fi
|
||||
|
||||
echo "END - xreal_driver_setup"
|
||||
|
||||
echo "Enabling the driver and setting it to Breezy Desktop mode"
|
||||
$USER_HOME/bin/xreal_driver_config -e
|
||||
$USER_HOME/bin/xreal_driver_config -vd
|
||||
|
||||
sed -i 's/virtual_display/breezy_desktop/g' $USER_HOME/.xreal_driver_config
|
||||
echo "END - xr_driver_setup"
|
||||
|
|
@ -17,13 +17,15 @@ const { MonitorManager } = Me.imports.monitormanager;
|
|||
const { isValidKeepAlive } = Me.imports.time;
|
||||
const { IPC_FILE_PATH, XREffect } = Me.imports.xrEffect;
|
||||
|
||||
const NESTED_MONITOR_PRODUCT = 'MetaMonitor';
|
||||
const SUPPORTED_MONITOR_PRODUCTS = [
|
||||
'VITURE',
|
||||
'nreal air',
|
||||
'Air',
|
||||
'Air 2', // guessing this one
|
||||
'Air 2 Pro',
|
||||
'SmartGlasses' // TCL/RayNeo
|
||||
'SmartGlasses', // TCL/RayNeo
|
||||
NESTED_MONITOR_PRODUCT
|
||||
];
|
||||
|
||||
class BreezyDesktopExtension {
|
||||
|
|
@ -72,6 +74,7 @@ class BreezyDesktopExtension {
|
|||
this._monitor_manager = new MonitorManager({
|
||||
use_optimal_monitor_config: this.settings.get_boolean('use-optimal-monitor-config'),
|
||||
headset_as_primary: this.settings.get_boolean('headset-as-primary'),
|
||||
use_highest_refresh_rate: this.settings.get_boolean('use-highest-refresh-rate'),
|
||||
extension_path: this.path
|
||||
});
|
||||
this._monitor_manager.setChangeHook(this._handle_monitor_change.bind(this));
|
||||
|
|
@ -121,11 +124,12 @@ class BreezyDesktopExtension {
|
|||
const target_monitor = this._monitor_manager.getMonitorPropertiesList()?.find(
|
||||
monitor => SUPPORTED_MONITOR_PRODUCTS.includes(monitor.product));
|
||||
if (target_monitor !== undefined) {
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _find_supported_monitor - Identified supported monitor: ${target_monitor.connector}`);
|
||||
Globals.logger.log(`Identified supported monitor: ${target_monitor.product} on ${target_monitor.connector}`);
|
||||
return {
|
||||
monitor: this._monitor_manager.getMonitors()[target_monitor.index],
|
||||
connector: target_monitor.connector,
|
||||
refreshRate: target_monitor.refreshRate
|
||||
refreshRate: target_monitor.refreshRate,
|
||||
is_dummy: target_monitor.product === NESTED_MONITOR_PRODUCT
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -152,8 +156,11 @@ class BreezyDesktopExtension {
|
|||
// A false result means we'll expect _handle_monitor_change to be triggered, so active polling
|
||||
// can be disabled.
|
||||
_target_monitor_ready(target_monitor) {
|
||||
return target_monitor.is_dummy ||
|
||||
!this._monitor_manager.needsOptimalModeCheck(target_monitor.connector);
|
||||
if (target_monitor.is_dummy) return true;
|
||||
|
||||
const needs_sbs_mode_switch = this.settings.get_boolean('fast-sbs-mode-switching') &&
|
||||
this._needs_widescreen_monitor_update();
|
||||
return !needs_sbs_mode_switch && !this._monitor_manager.needsOptimalModeCheck(target_monitor.connector);
|
||||
}
|
||||
|
||||
_setup() {
|
||||
|
|
@ -214,7 +221,7 @@ class BreezyDesktopExtension {
|
|||
const widescreen_setting_enabled = this.settings.get_boolean('widescreen-mode');
|
||||
if (widescreen_setting_enabled !== sbs_enabled) {
|
||||
Globals.logger.log_debug('BreezyDesktopExtension _needs_widescreen_monitor_update - true');
|
||||
this._write_control('sbs_mode', widescreen_setting_enabled ? 'enable' : 'disable');
|
||||
this._request_sbs_mode_change(widescreen_setting_enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -260,7 +267,10 @@ class BreezyDesktopExtension {
|
|||
});
|
||||
|
||||
this._update_follow_threshold(this.settings);
|
||||
this._update_widescreen_mode_from_settings(this.settings);
|
||||
|
||||
// this gets triggered before _effect_enable if in fast-sbs-mode-switching mode
|
||||
if (!this.settings.get_boolean('fast-sbs-mode-switching'))
|
||||
this._update_widescreen_mode_from_settings(this.settings);
|
||||
|
||||
this._widescreen_mode_effect_state_connection = this._xr_effect.connect('notify::widescreen-mode-state', this._update_widescreen_mode_from_state.bind(this));
|
||||
this._supported_device_detected_connected = this._xr_effect.connect('notify::supported-device-detected', this._handle_supported_device_change.bind(this));
|
||||
|
|
@ -363,16 +373,41 @@ class BreezyDesktopExtension {
|
|||
if (value !== undefined) this._write_control('breezy_desktop_follow_threshold', value);
|
||||
}
|
||||
|
||||
// requests sbs_mode change and monitors to ensure the state reflects the setting
|
||||
_request_sbs_mode_change(value) {
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
if (!this._sbs_mode_update_timeout) {
|
||||
var attempts = 0;
|
||||
this._sbs_mode_update_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 10000, (() => {
|
||||
if (attempts++ < 3) {
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
// the state never updated to reflect our request, revert the setting
|
||||
this.settings.set_boolean('widescreen-mode', !value);
|
||||
this._sbs_mode_update_timeout = undefined;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}).bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
_update_widescreen_mode_from_settings(settings, event) {
|
||||
const value = settings.get_boolean('widescreen-mode');
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_widescreen_mode_from_settings ${value}`);
|
||||
if (value !== undefined && value !== this._xr_effect.widescreen_mode_state)
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
else
|
||||
if (value !== undefined && value !== this._xr_effect.widescreen_mode_state) {
|
||||
this._request_sbs_mode_change(value);
|
||||
} else
|
||||
Globals.logger.log_debug('effect.widescreen_mode_state already matched setting');
|
||||
}
|
||||
|
||||
_update_widescreen_mode_from_state(effect, _pspec) {
|
||||
// kill our state checker if it's running
|
||||
if (this._sbs_mode_update_timeout) {
|
||||
GLib.source_remove(this._sbs_mode_update_timeout);
|
||||
this._sbs_mode_update_timeout = undefined;
|
||||
}
|
||||
|
||||
const value = effect.widescreen_mode_state;
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_widescreen_mode_from_state ${value}`);
|
||||
if (value !== this.settings.get_boolean('widescreen-mode'))
|
||||
|
|
|
|||
|
|
@ -89,9 +89,18 @@ function getMonitorConfig(displayConfigProxy, callback) {
|
|||
}
|
||||
|
||||
// triggers callback with true result if an an async monitor config change was triggered, false if no config change needed
|
||||
function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, callback) {
|
||||
function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, useHighestRefreshRate,
|
||||
callback, allowConfigUpdateFn) {
|
||||
Globals.logger.log_debug(`monitormanager.js performOptimalModeCheck for ${connectorName}`);
|
||||
|
||||
displayConfigProxy.GetCurrentStateRemote((result, error) => {
|
||||
if (!allowConfigUpdateFn()) {
|
||||
// other requests are in progress, this monitor state may be stale, do nothing
|
||||
Globals.logger.log_debug('MonitorManager performOptimalModeCheck: allowConfigUpdate is false');
|
||||
callback(false, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
callback(null, `GetCurrentState failed: ${error}`);
|
||||
} else {
|
||||
|
|
@ -104,10 +113,19 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri
|
|||
let monitorToModeIdMap = {};
|
||||
let bestFitMode = undefined;
|
||||
for (let monitor of monitors) {
|
||||
const [details, modes, monProperties] = monitor;
|
||||
const [details, availableModes, monProperties] = monitor;
|
||||
const [connector, vendor, product, monitorSerial] = details;
|
||||
const isOurMonitor = connector == connectorName;
|
||||
if (isOurMonitor) ourMonitor = monitor;
|
||||
let modes = availableModes;
|
||||
if (isOurMonitor) {
|
||||
ourMonitor = monitor;
|
||||
if (!useHighestRefreshRate) {
|
||||
const currentMode = modes.find((mode) => !!mode[6]['is-current']);
|
||||
|
||||
// filter modes to only include the current refresh rate
|
||||
modes = availableModes.filter((mode) => mode[3] === currentMode[3]);
|
||||
}
|
||||
}
|
||||
|
||||
for (let mode of modes) {
|
||||
const [modeId, width, height, refreshRate, preferredScale, supportedScales, modeProperites] = mode;
|
||||
|
|
@ -202,6 +220,13 @@ var MonitorManager = GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
'use-highest-refresh-rate': GObject.ParamSpec.boolean(
|
||||
'use-highest-refresh-rate',
|
||||
'Use highest refresh rate',
|
||||
'Set the highest refresh rate which choosing optimal configs',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
'headset-as-primary': GObject.ParamSpec.boolean(
|
||||
'headset-as-primary',
|
||||
'Use headset as primary monitor',
|
||||
|
|
@ -227,6 +252,10 @@ var MonitorManager = GObject.registerClass({
|
|||
this._monitorProperties = null;
|
||||
this._changeHookFn = null;
|
||||
this._needsConfigCheck = this.use_optimal_monitor_config;
|
||||
|
||||
// help prevent certain actions from taking place multiple times in the event of rapid monitor updates
|
||||
this._asyncRequestsInFlight = 0;
|
||||
this._configCheckRequestsCount = 0;
|
||||
}
|
||||
|
||||
enable() {
|
||||
|
|
@ -266,36 +295,59 @@ var MonitorManager = GObject.registerClass({
|
|||
return this._monitorProperties;
|
||||
}
|
||||
|
||||
// returns true if a check is needed, caller should wait for the next change hook call
|
||||
// returns true if an async check is needed, caller should wait for the next change hook call
|
||||
needsOptimalModeCheck(monitorConnector) {
|
||||
Globals.logger.log_debug(`MonitorManager checkOptimalMode: ${monitorConnector}`);
|
||||
Globals.logger.log_debug(`MonitorManager needsOptimalModeCheck: ${monitorConnector}`);
|
||||
if (this._displayConfigProxy == null) {
|
||||
Globals.logger.log('MonitorManager checkOptimalMode: _displayConfigProxy not set!');
|
||||
Globals.logger.log('MonitorManager needsOptimalModeCheck: _displayConfigProxy not set!');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._needsConfigCheck) {
|
||||
performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, ((configChanged, error) => {
|
||||
this._needsConfigCheck = false;
|
||||
const isCheckingConfig = this._needsConfigCheck;
|
||||
if (this._needsConfigCheck && this._asyncRequestsInFlight === 0) {
|
||||
this._asyncRequestsInFlight++;
|
||||
|
||||
const configCheckCountSnapshot = this._configCheckRequestsCount;
|
||||
const allowConfigUpdateFn = (() => {
|
||||
// allow updates to the config if this is the only in-flight request and no more requests
|
||||
// were made while we were waiting for the previous request to complete
|
||||
return this._asyncRequestsInFlight === 1 && this._configCheckRequestsCount === configCheckCountSnapshot;
|
||||
}).bind(this);
|
||||
|
||||
performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, this.use_highest_refresh_rate, ((configChanged, error) => {
|
||||
if (--this._asyncRequestsInFlight > 0) {
|
||||
Globals.logger.log_debug(`MonitorManager needsOptimalModeCheck: ${this._asyncRequestsInFlight} async requests still pending, skipping change hook`);
|
||||
return;
|
||||
} else if (this._configCheckRequestsCount !== configCheckCountSnapshot) {
|
||||
Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: config checks requested while in-flight, skipping change hook');
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
Globals.logger.log(`Failed to switch to optimal mode for monitor ${monitorConnector}: ${error}`);
|
||||
|
||||
// tell the extension to proceed, this should result in another config check
|
||||
this._changeHookFn();
|
||||
} else {
|
||||
this._needsConfigCheck = false;
|
||||
if (configChanged) {
|
||||
Globals.logger.log(`Switched to optimal mode for monitor ${monitorConnector}`);
|
||||
} else if (!!this._changeHookFn) {
|
||||
Globals.logger.log_debug('MonitorManager checkOptimalMode: no config change');
|
||||
Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: no config change');
|
||||
|
||||
// no config change means this won't be triggered automatically, so trigger it manually
|
||||
this._changeHookFn();
|
||||
} else {
|
||||
Globals.logger.log('MonitorManager checkOptimalMode: can\'t trigger change hook, no hook set!');
|
||||
Globals.logger.log('MonitorManager needsOptimalModeCheck: can\'t trigger change hook, no hook set!');
|
||||
}
|
||||
}
|
||||
}).bind(this));
|
||||
}).bind(this), allowConfigUpdateFn);
|
||||
} else if (!this._needsConfigCheck) {
|
||||
Globals.logger.log_debug('MonitorManager needsOptimalModeCheck: skipping config check');
|
||||
} else {
|
||||
Globals.logger.log_debug('MonitorManager checkOptimalMode: skipping config check');
|
||||
Globals.logger.log_debug(`MonitorManager needsOptimalModeCheck: skipping due to async requests ${this._asyncRequestsInFlight}`);
|
||||
}
|
||||
return this._needsConfigCheck;
|
||||
return isCheckingConfig;
|
||||
}
|
||||
|
||||
_on_monitors_change() {
|
||||
|
|
@ -303,16 +355,22 @@ var MonitorManager = GObject.registerClass({
|
|||
if (this._displayConfigProxy == null) {
|
||||
return;
|
||||
}
|
||||
this._needsConfigCheck = this.use_optimal_monitor_config;
|
||||
if (this.use_optimal_monitor_config) {
|
||||
this._needsConfigCheck = true;
|
||||
this._configCheckRequestsCount++;
|
||||
}
|
||||
this._asyncRequestsInFlight++;
|
||||
getMonitorConfig(this._displayConfigProxy, ((result, error) => {
|
||||
if (error) {
|
||||
Globals.logger.log(error);
|
||||
return;
|
||||
}
|
||||
|
||||
const monitorProperties = [];
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
const [monitorName, connectorName, vendor, product, serial, refreshRate] = result[i];
|
||||
const monitorIndex = this._backendManager.get_monitor_for_connector(connectorName);
|
||||
Globals.logger.log(`Found monitor ${monitorName}, vendor ${vendor}, product ${product}, serial ${serial}, connector ${connectorName}, index ${monitorIndex}`);
|
||||
Globals.logger.log_debug(`Found monitor ${monitorName}, vendor ${vendor}, product ${product}, serial ${serial}, connector ${connectorName}, index ${monitorIndex}`);
|
||||
if (monitorIndex >= 0) {
|
||||
monitorProperties[monitorIndex] = {
|
||||
index: monitorIndex,
|
||||
|
|
@ -327,7 +385,11 @@ var MonitorManager = GObject.registerClass({
|
|||
}
|
||||
this._monitorProperties = monitorProperties;
|
||||
if (!!this._changeHookFn) {
|
||||
this._changeHookFn();
|
||||
if (--this._asyncRequestsInFlight === 0) {
|
||||
this._changeHookFn();
|
||||
} else {
|
||||
Globals.logger.log_debug(`MonitorManager _on_monitors_change: ${this._asyncRequestsInFlight} requests still pending, skipping change hook`);
|
||||
}
|
||||
} else {
|
||||
Globals.logger.log('MonitorManager _on_monitors_change: can\'t trigger change hook, no hook set!');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b97faa82a7767e4270e46886d68dd1c70b71abca
|
||||
Subproject commit b0080ca844e057d31aae0e70aa6d026059ea304f
|
||||
|
|
@ -3,6 +3,9 @@
|
|||
# exit when any command fails
|
||||
set -e
|
||||
|
||||
ARCH=${ARCH:-$(uname -m)}
|
||||
echo "Building Breezy UI for $ARCH"
|
||||
|
||||
check_command() {
|
||||
if ! command -v "$1" &>/dev/null; then
|
||||
echo "Please install \"$1\" and make sure it's available in your \$PATH"
|
||||
|
|
@ -16,13 +19,13 @@ check_command "flatpak-builder"
|
|||
# https://stackoverflow.com/a/246128
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
|
||||
TMP_DIR=$(mktemp -d -t breezy-ui-flatpak-XXXXXXXXXX)
|
||||
TMP_DIR=$(mktemp -d --tmpdir=$SCRIPT_DIR/.. -t .breezy-ui-flatpak-XXXXXXXXXX)
|
||||
OUT_DIR=$SCRIPT_DIR/../out
|
||||
rm -rf $OUT_DIR
|
||||
mkdir -p $OUT_DIR
|
||||
|
||||
flatpak-builder --force-clean $TMP_DIR/build $SCRIPT_DIR/../com.xronlinux.BreezyDesktop.json
|
||||
flatpak build-export $TMP_DIR/export $TMP_DIR/build
|
||||
flatpak build-bundle $TMP_DIR/export $OUT_DIR/com.xronlinux.BreezyDesktop.flatpak com.xronlinux.BreezyDesktop --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak-builder --arch $ARCH --disable-rofiles-fuse --disable-cache --force-clean --delete-build-dirs --user $TMP_DIR/build $SCRIPT_DIR/../com.xronlinux.BreezyDesktop.json
|
||||
flatpak build-export --arch $ARCH $TMP_DIR/export $TMP_DIR/build
|
||||
flatpak build-bundle --arch $ARCH $TMP_DIR/export $OUT_DIR/com.xronlinux.BreezyDesktop-$ARCH.flatpak com.xronlinux.BreezyDesktop --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
IFS=: read -ra host_data_dirs < <(flatpak-spawn --host sh -c 'echo "$XDG_DATA_DIRS"')
|
||||
IFS=: read -ra HOST_XDG_STATE_HOME < <(flatpak-spawn --host sh -c 'echo "$XDG_STATE_HOME"')
|
||||
IFS=: read -ra HOST_XDG_CONFIG_HOME < <(flatpak-spawn --host sh -c 'echo "$XDG_CONFIG_HOME"')
|
||||
IFS=: read -ra HOST_XDG_BIN_HOME < <(flatpak-spawn --host sh -c 'echo "$XDG_BIN_HOME"')
|
||||
IFS=: read -ra HOST_XDG_DATA_HOME < <(flatpak-spawn --host sh -c 'echo "$XDG_DATA_HOME"')
|
||||
|
||||
|
|
@ -48,6 +49,12 @@ else
|
|||
XDG_STATE_HOME="$(realpath ~)/.local/state"
|
||||
fi
|
||||
|
||||
if [[ ! -z "${HOST_XDG_CONFIG_HOME}" ]]; then
|
||||
XDG_CONFIG_HOME="${HOST_XDG_CONFIG_HOME}"
|
||||
else
|
||||
XDG_CONFIG_HOME="$(realpath ~)/.config"
|
||||
fi
|
||||
|
||||
if [[ ! -z "${HOST_XDG_DATA_HOME}" ]]; then
|
||||
XDG_DATA_HOME="${HOST_XDG_DATA_HOME}"
|
||||
else
|
||||
|
|
@ -57,5 +64,6 @@ fi
|
|||
export XDG_DATA_DIRS
|
||||
export XDG_BIN_HOME
|
||||
export XDG_STATE_HOME
|
||||
export XDG_CONFIG_HOME
|
||||
export XDG_DATA_HOME
|
||||
exec breezydesktop "$@"
|
||||
|
|
@ -118,6 +118,24 @@
|
|||
Automatically set the headset as the primary display upon connection
|
||||
</description>
|
||||
</key>
|
||||
<key name="use-highest-refresh-rate" type="b">
|
||||
<default>
|
||||
true
|
||||
</default>
|
||||
<summary>Use highest refresh rate</summary>
|
||||
<description>
|
||||
Automatically set the highest refresh rate upon connection
|
||||
</description>
|
||||
</key>
|
||||
<key name="fast-sbs-mode-switching" type="b">
|
||||
<default>
|
||||
true
|
||||
</default>
|
||||
<summary>Fast SBS mode switching</summary>
|
||||
<description>
|
||||
Enable fast SBS mode switching
|
||||
</description>
|
||||
</key>
|
||||
<key name="disable-anti-aliasing" type="b">
|
||||
<default>
|
||||
false
|
||||
|
|
|
|||
|
|
@ -3,7 +3,13 @@
|
|||
<id>com.xronlinux.BreezyDesktop.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-or-later</project_license>
|
||||
<name>Breezy Desktop</name>
|
||||
<summary>XR Desktop Control Panel</summary>
|
||||
<description>
|
||||
<p>No description</p>
|
||||
<p>XR Desktop Control Panel</p>
|
||||
</description>
|
||||
<categories>
|
||||
<category>Office</category>
|
||||
<category>Development</category>
|
||||
</categories>
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 34a349d39efc02f4b65550debd193d29d95a84f9
|
||||
Subproject commit a96fdeb1557d8cd24e73cb8e9e2559adfa46e3aa
|
||||
|
|
@ -31,6 +31,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
toggle_follow_shortcut_label = Gtk.Template.Child()
|
||||
headset_as_primary_switch = Gtk.Template.Child()
|
||||
use_optimal_monitor_config_switch = Gtk.Template.Child()
|
||||
use_highest_refresh_rate_switch = Gtk.Template.Child()
|
||||
fast_sbs_mode_switch = Gtk.Template.Child()
|
||||
movement_look_ahead_scale = Gtk.Template.Child()
|
||||
movement_look_ahead_adjustment = Gtk.Template.Child()
|
||||
|
||||
|
|
@ -52,6 +54,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.reassign_toggle_follow_shortcut_button,
|
||||
self.headset_as_primary_switch,
|
||||
self.use_optimal_monitor_config_switch,
|
||||
self.use_highest_refresh_rate_switch,
|
||||
self.fast_sbs_mode_switch,
|
||||
self.movement_look_ahead_scale
|
||||
]
|
||||
|
||||
|
|
@ -66,6 +70,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.settings.bind('curved-display', self.curved_display_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('headset-as-primary', self.headset_as_primary_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('use-optimal-monitor-config', self.use_optimal_monitor_config_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('use-highest-refresh-rate', self.use_highest_refresh_rate_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('fast-sbs-mode-switching', self.fast_sbs_mode_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('look-ahead-override', self.movement_look_ahead_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
bind_shortcut_settings(self.get_parent(), [
|
||||
|
|
@ -136,8 +142,10 @@ class ConnectedDevice(Gtk.Box):
|
|||
|
||||
def _refresh_use_optimal_monitor_config(self, switch, param):
|
||||
self.headset_as_primary_switch.set_sensitive(switch.get_active())
|
||||
self.use_highest_refresh_rate_switch.set_sensitive(switch.get_active())
|
||||
if not switch.get_active():
|
||||
self.headset_as_primary_switch.set_active(False)
|
||||
self.use_highest_refresh_rate_switch.set_active(False)
|
||||
|
||||
def set_device_name(self, name):
|
||||
self.device_label.set_markup(f"<b>{name}</b>")
|
||||
|
|
|
|||
|
|
@ -328,6 +328,17 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Use highest refresh rate</property>
|
||||
<property name="subtitle" translatable="true">Refresh rate may affect performance, disable this to set it manually.</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="use_highest_refresh_rate_switch">
|
||||
<property name="valign">3</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Always primary display</property>
|
||||
|
|
@ -339,6 +350,17 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Fast SBS mode switching</property>
|
||||
<property name="subtitle" translatable="true">Switches glasses to SBS mode immediately when plugged in, if widescreen mode is on. May cause instability.</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="fast_sbs_mode_switch">
|
||||
<property name="valign">3</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Movement look-ahead</property>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import gi
|
|||
import logging
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
|
|
@ -35,8 +36,12 @@ from .statemanager import StateManager
|
|||
from .window import BreezydesktopWindow
|
||||
from .xrdriveripc import XRDriverIPC
|
||||
|
||||
state_dir = os.path.expanduser("~/.local/state")
|
||||
log_dir = os.path.join(state_dir, 'breezy_gnome/logs/ui')
|
||||
config_home = os.environ.get('XDG_CONFIG_HOME', '~/.config')
|
||||
config_dir = os.path.expanduser(config_home)
|
||||
state_home = os.environ.get('XDG_STATE_HOME', '~/.local/state')
|
||||
state_dir = os.path.expanduser(state_home)
|
||||
breezy_state_dir = os.path.join(state_dir, 'breezy_gnome')
|
||||
log_dir = os.path.join(breezy_state_dir, 'logs/ui')
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
|
||||
logger = logging.getLogger('breezy_ui')
|
||||
|
|
@ -53,18 +58,19 @@ def excepthook(exc_type, exc_value, exc_traceback):
|
|||
|
||||
sys.excepthook = excepthook
|
||||
|
||||
XRDriverIPC.set_instance(XRDriverIPC(logger))
|
||||
XRDriverIPC.set_instance(XRDriverIPC(logger, config_dir))
|
||||
|
||||
class BreezydesktopApplication(Adw.Application):
|
||||
"""The main application singleton class."""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, skip_verification):
|
||||
super().__init__(application_id='com.xronlinux.BreezyDesktop',
|
||||
flags=Gio.ApplicationFlags.DEFAULT_FLAGS)
|
||||
self.create_action('quit', self.on_quit_action, ['<primary>q'])
|
||||
self.create_action('about', self.on_about_action)
|
||||
self.create_action('license', self.on_license_action)
|
||||
self.create_action('reset_driver', self.on_reset_driver_action)
|
||||
self._skip_verification = skip_verification
|
||||
|
||||
def do_activate(self):
|
||||
"""Called when the application is activated.
|
||||
|
|
@ -74,7 +80,7 @@ class BreezydesktopApplication(Adw.Application):
|
|||
"""
|
||||
win = self.props.active_window
|
||||
if not win:
|
||||
win = BreezydesktopWindow(application=self)
|
||||
win = BreezydesktopWindow(self._skip_verification, application=self)
|
||||
win.connect('close-request', lambda *_: self.on_quit_action())
|
||||
win.connect('destroy', lambda *_: self.on_quit_action())
|
||||
win.present()
|
||||
|
|
@ -125,5 +131,9 @@ class BreezydesktopApplication(Adw.Application):
|
|||
|
||||
|
||||
def main(version):
|
||||
app = BreezydesktopApplication()
|
||||
return app.run(sys.argv)
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-sv", "--skip-verification", action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
app = BreezydesktopApplication(args.skip_verification)
|
||||
return app.run(None)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
|
|||
license_action_needed_banner = Gtk.Template.Child()
|
||||
missing_breezy_features_banner = Gtk.Template.Child()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, skip_verification, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.state_manager = StateManager.get_instance()
|
||||
|
|
@ -57,6 +57,8 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
|
|||
|
||||
self._handle_state_update(self.state_manager, None)
|
||||
|
||||
self._skip_verification = skip_verification
|
||||
|
||||
self.connect("destroy", self._on_window_destroy)
|
||||
|
||||
def _handle_state_update(self, state_manager, val):
|
||||
|
|
@ -71,9 +73,11 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
|
|||
for child in self.main_content:
|
||||
self.main_content.remove(child)
|
||||
|
||||
if not verify_installation():
|
||||
self.main_content.append(self.failed_verification)
|
||||
elif not self.state_manager.get_property('license-present'):
|
||||
if not self._skip_verification:
|
||||
if not verify_installation():
|
||||
self.main_content.append(self.failed_verification)
|
||||
|
||||
if not self.state_manager.get_property('license-present'):
|
||||
self.main_content.append(self.no_license)
|
||||
elif not ExtensionsManager.get_instance().is_installed():
|
||||
self.main_content.append(self.no_extension)
|
||||
|
|
|
|||
|
|
@ -14,31 +14,88 @@ if [ "$(id -u)" != "0" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Get the directory of the current script
|
||||
script_dir=$(dirname "$0")
|
||||
|
||||
USER=${SUDO_USER:-$USER}
|
||||
GROUP=$(id -gn $USER)
|
||||
USER_HOME=$(getent passwd $USER | cut -d: -f6)
|
||||
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME="$USER_HOME/.local/share"
|
||||
fi
|
||||
DATA_DIR="$XDG_DATA_HOME/breezy_vulkan"
|
||||
if [ ! -d "$DATA_DIR" ]; then
|
||||
mkdir -p $DATA_DIR
|
||||
fi
|
||||
VULKAN_DATA_DIR="$XDG_DATA_HOME/vulkan"
|
||||
XR_DRIVER_DATA_DIR="$XDG_DATA_HOME/breezy_vulkan"
|
||||
|
||||
if [ -z "$XDG_CONFIG_HOME" ]; then
|
||||
XDG_CONFIG_HOME="$USER_HOME/.config"
|
||||
fi
|
||||
CONFIG_DIR="$XDG_CONFIG_HOME/breezy_vulkan"
|
||||
if [ ! -d "$CONFIG_DIR" ]; then
|
||||
mkdir -p $CONFIG_DIR
|
||||
fi
|
||||
|
||||
if [ -z "$XDG_BIN_HOME" ]; then
|
||||
XDG_BIN_HOME="$USER_HOME/.local/bin"
|
||||
fi
|
||||
OLD_BIN_DIR="$USER_HOME/bin"
|
||||
BIN_DIR="$XDG_BIN_HOME"
|
||||
if [ ! -d "$BIN_DIR" ]; then
|
||||
mkdir -p $BIN_DIR
|
||||
fi
|
||||
|
||||
if [ -z "$XDG_STATE_HOME" ]; then
|
||||
XDG_STATE_HOME="$USER_HOME/.local/state"
|
||||
fi
|
||||
STATE_DIR="$XDG_STATE_HOME/breezy_vulkan"
|
||||
if [ ! -d "$STATE_DIR" ]; then
|
||||
mkdir -p $STATE_DIR
|
||||
fi
|
||||
|
||||
LIB_DIR="$USER_HOME/.local/lib"
|
||||
if [ ! -d "$LIB_DIR" ]; then
|
||||
mkdir -p "$LIB_DIR"
|
||||
fi
|
||||
|
||||
LIB32_DIR="$USER_HOME/.local/lib32"
|
||||
if [ ! -d "$LIB32_DIR" ]; then
|
||||
mkdir -p "$LIB32_DIR"
|
||||
fi
|
||||
|
||||
if [ "$for_install" -eq 0 ]; then
|
||||
UA_EVENT_NAME="breezy_uninstall"
|
||||
UA_CLIENT_ID="BreezyVulkan"
|
||||
#INJECT_UA_CALL
|
||||
fi
|
||||
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt binaries from $USER_HOME/.local/lib[32]/"
|
||||
rm $USER_HOME/.local/lib/libvkbasalt.so
|
||||
rm $USER_HOME/.local/lib32/libvkbasalt.so
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt binaries from $LIB_DIR[32]/"
|
||||
rm $LIB_DIR/libvkbasalt.so
|
||||
rm $LIB32_DIR/libvkbasalt.so
|
||||
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt vulkan layer configs from $USER_HOME/.local/share/vulkan/implicit_layer.d/"
|
||||
rm $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.json
|
||||
rm $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.x86.json
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt vulkan layer configs from $VULKAN_DATA_DIR/implicit_layer.d/"
|
||||
rm $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.json
|
||||
rm $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.x86.json
|
||||
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt and reshade directories at $USER_HOME/.config/"
|
||||
rm -rf $USER_HOME/.config/vkBasalt
|
||||
rm -rf $USER_HOME/.config/reshade
|
||||
[ "$for_install" -eq 0 ] && echo "Removing vkBasalt and reshade directories at $CONFIG_DIR/"
|
||||
rm -rf $CONFIG_DIR/vkBasalt
|
||||
rm -rf $CONFIG_DIR/reshade
|
||||
|
||||
[ "$for_install" -eq 0 ] && echo "Removing scripts at $USER_HOME/.local/bin/breezy_vulkan"
|
||||
rm -rf $USER_HOME/.local/bin/breezy_vulkan
|
||||
[ "$for_install" -eq 0 ] && echo "Removing scripts at $BIN_DIR"
|
||||
rm -f $BIN_DIR/breezy_vulkan_verify
|
||||
|
||||
[ "$for_install" -eq 0 ] && echo "SKIPPING xrealAirLinuxDriver uninstall to keep mouse/joystick driver functionality."
|
||||
[ "$for_install" -eq 0 ] && echo "To manually uninstall xrealAirLinuxDriver, do: \"sudo ~/bin/xreal_driver_uninstall\""
|
||||
[ "$for_install" -eq 0 ] && echo "SKIPPING xrDriver uninstall to keep mouse/joystick driver functionality."
|
||||
[ "$for_install" -eq 0 ] && echo "To manually uninstall xrDriver, do: \"sudo xr_driver_uninstall\""
|
||||
|
||||
# this script is self-deleting, leave this as the last command
|
||||
rm -f $USER_HOME/bin/breezy_vulkan_uninstall
|
||||
# remove the one we're not using first
|
||||
if [ "$script_dir" = "$OLD_BIN_DIR" ]; then
|
||||
rm -f "$BIN_DIR/breezy_vulkan_uninstall"
|
||||
rm -f "$OLD_BIN_DIR/breezy_vulkan_uninstall"
|
||||
else
|
||||
rm -f "$OLD_BIN_DIR/breezy_vulkan_uninstall"
|
||||
rm -f "$BIN_DIR/breezy_vulkan_uninstall"
|
||||
fi
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# create a string to string mapping, file name to expected file location
|
||||
declare -A file_paths
|
||||
file_paths=(
|
||||
["bin/breezy_vulkan_uninstall"]="{bin_dir}/breezy_vulkan_uninstall"
|
||||
["vkBasalt.64/libvkbasalt.so"]="{lib_dir}/libvkbasalt.so"
|
||||
["vkBasalt.32/libvkbasalt.so"]="{lib32_dir}/libvkbasalt.so"
|
||||
["IMUAdjust.fx"]="{reshade_config_dir}/Shaders/IMUAdjust.fx"
|
||||
["ReShade.fxh"]="{reshade_config_dir}/Shaders/ReShade.fxh"
|
||||
["ReShadeUI.fxh"]="{reshade_config_dir}/Shaders/ReShadeUI.fxh"
|
||||
["Sideview.fx"]="{reshade_config_dir}/Shaders/Sideview.fx"
|
||||
["calibrating.png"]="{reshade_config_dir}/Textures/calibrating.png"
|
||||
["custom_banner.png"]="{reshade_config_dir}/Textures/custom_banner.png"
|
||||
["xr_driver/manifest"]="{xr_driver_data_dir}/manifest"
|
||||
)
|
||||
|
||||
# verify the file hashes in ./manifest
|
||||
while IFS= read -r line
|
||||
do
|
||||
# split the line into hash and filename
|
||||
manifest_hash=$(echo $line | awk '{print $1}')
|
||||
file=$(echo $line | awk '{print $2}')
|
||||
|
||||
actual_file_path=${file_paths[$file]}
|
||||
|
||||
# compute the SHA256 hash of the actual file
|
||||
actual_hash=$(sha256sum $actual_file_path | awk '{print $1}')
|
||||
|
||||
# compare the hashes
|
||||
if ! [ "$manifest_hash" = "$actual_hash" ]; then
|
||||
echo "Verification failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
done < "{data_dir}/manifest"
|
||||
|
||||
# if our checks succeeded, run the xr_driver verify script
|
||||
{bin_dir}/xr_driver_verify > /dev/null
|
||||
|
||||
echo "Verification succeeded"
|
||||
152
vulkan/bin/setup
152
vulkan/bin/setup
|
|
@ -6,8 +6,53 @@ set -e
|
|||
# to a specific release of the code, and guarantees it will never run along-side newer or older binaries.
|
||||
|
||||
USER=${SUDO_USER:-$USER}
|
||||
GROUP=$(id -gn $USER)
|
||||
USER_HOME=$(getent passwd $USER | cut -d: -f6)
|
||||
UA_EVENT_NAME="breezy_install"
|
||||
|
||||
if [ -z "$XDG_DATA_HOME" ]; then
|
||||
XDG_DATA_HOME="$USER_HOME/.local/share"
|
||||
fi
|
||||
DATA_DIR="$XDG_DATA_HOME/breezy_vulkan"
|
||||
if [ ! -d "$DATA_DIR" ]; then
|
||||
mkdir -p $DATA_DIR
|
||||
fi
|
||||
VULKAN_DATA_DIR="$XDG_DATA_HOME/vulkan"
|
||||
XR_DRIVER_DATA_DIR="$XDG_DATA_HOME/xr_driver"
|
||||
|
||||
if [ -z "$XDG_CONFIG_HOME" ]; then
|
||||
XDG_CONFIG_HOME="$USER_HOME/.config"
|
||||
fi
|
||||
RESHADE_CONFIG_DIR="$XDG_CONFIG_HOME/reshade"
|
||||
VKBASALT_CONFIG_DIR="$XDG_CONFIG_HOME/vkBasalt"
|
||||
|
||||
if [ -z "$XDG_BIN_HOME" ]; then
|
||||
XDG_BIN_HOME="$USER_HOME/.local/bin"
|
||||
fi
|
||||
OLD_BIN_DIR="$USER_HOME/bin"
|
||||
BIN_DIR="$XDG_BIN_HOME"
|
||||
if [ ! -d "$BIN_DIR" ]; then
|
||||
mkdir -p $BIN_DIR
|
||||
fi
|
||||
|
||||
if [ -z "$XDG_STATE_HOME" ]; then
|
||||
XDG_STATE_HOME="$USER_HOME/.local/state"
|
||||
fi
|
||||
STATE_DIR="$XDG_STATE_HOME/breezy_vulkan"
|
||||
if [ ! -d "$STATE_DIR" ]; then
|
||||
mkdir -p $STATE_DIR
|
||||
fi
|
||||
|
||||
LIB_DIR="$USER_HOME/.local/lib"
|
||||
if [ ! -d "$LIB_DIR" ]; then
|
||||
mkdir -p "$LIB_DIR"
|
||||
fi
|
||||
|
||||
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
|
||||
echo "Cleaning up the previous installation"
|
||||
|
||||
|
|
@ -17,68 +62,93 @@ if [ -e "$USER_HOME/bin/breezy_vulkan_uninstall" ]; then
|
|||
UA_EVENT_NAME="breezy_update"
|
||||
fi
|
||||
|
||||
if [ -e "$BIN_DIR/breezy_vulkan_uninstall" ]; then
|
||||
echo "Cleaning up the previous installation"
|
||||
|
||||
# ` || true` will ensure that this can't cause a failure, even with `set -e`
|
||||
$BIN_DIR/breezy_vulkan_uninstall --for-install || true
|
||||
|
||||
UA_EVENT_NAME="breezy_update"
|
||||
fi
|
||||
|
||||
UA_CLIENT_ID="BreezyVulkan"
|
||||
UA_EVENT_VERSION="$1"
|
||||
#INJECT_UA_CALL
|
||||
|
||||
echo "Copying the breezy_vulkan scripts to ${USER_HOME}/bin"
|
||||
if [ ! -d "$USER_HOME/bin" ]; then
|
||||
su -c 'mkdir -p '$USER_HOME'/bin' $USER
|
||||
fi
|
||||
cp bin/breezy_vulkan_uninstall $USER_HOME/bin
|
||||
|
||||
echo "Installing vkBasalt; copying binaries, configs, and shader files to ${USER_HOME}/.local and ${USER_HOME}/.config"
|
||||
# escaping sed replace: https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
|
||||
ESCAPED_BIN_DIR=$(printf '%s\n' "$BIN_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
ESCAPED_LIB_DIR=$(printf '%s\n' "$LIB_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
ESCAPED_LIB32_DIR=$(printf '%s\n' "$LIB32_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
ESCAPED_RESHADE_CONFIG_DIR=$(printf '%s\n' "$RESHADE_CONFIG_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
ESCAPED_STATE_DIR=$(printf '%s\n' "$STATE_DIR" | sed -e 's/[\/&]/\\&/g')
|
||||
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')
|
||||
|
||||
echo "Copying the breezy_vulkan scripts to ${BIN_DIR} and related files to ${DATA_DIR}"
|
||||
cp bin/breezy_vulkan_uninstall $BIN_DIR
|
||||
sed -i -e "s/{bin_dir}/$ESCAPED_BIN_DIR/g" \
|
||||
-e "s/{lib_dir}/$ESCAPED_LIB_DIR/g" \
|
||||
-e "s/{lib32_dir}/$ESCAPED_LIB32_DIR/g" \
|
||||
-e "s/{reshade_config_dir}/$ESCAPED_RESHADE_CONFIG_DIR/g" \
|
||||
-e "s/{state_dir}/$ESCAPED_STATE_DIR/g" \
|
||||
-e "s/{data_dir}/$ESCAPED_DATA_DIR/g" \
|
||||
-e "s/{xr_driver_data_dir}/$ESCAPED_XR_DRIVER_DATA_DIR/g" \
|
||||
bin/breezy_vulkan_verify
|
||||
cp bin/breezy_vulkan_verify $BIN_DIR
|
||||
cp manifest $DATA_DIR
|
||||
|
||||
# keep putting this in the old location in case an older version of the script tries to find it
|
||||
cp bin/breezy_vulkan_uninstall $OLD_BIN_DIR
|
||||
|
||||
echo "Installing vkBasalt; copying binaries, configs, and shader files"
|
||||
|
||||
# much of the setup below was informed by https://github.com/simons-public/steam-deck-vkbasalt-install
|
||||
# copy the vkBasalt binaries and configs
|
||||
su -c 'mkdir -p '$USER_HOME'/.local/{lib,lib32,share/vulkan/implicit_layer.d}' $USER
|
||||
su -c 'mkdir -p '$USER_HOME'/.config/{vkBasalt,reshade/Shaders,reshade/Textures}' $USER
|
||||
cp vkBasalt.64/libvkbasalt.so $USER_HOME/.local/lib/
|
||||
cp vkBasalt.32/libvkbasalt.so $USER_HOME/.local/lib32/
|
||||
chown $USER:$USER $USER_HOME/.local/lib/libvkbasalt.so
|
||||
chown $USER:$USER $USER_HOME/.local/lib32/libvkbasalt.so
|
||||
mkdir -p "$VULKAN_DATA_DIR"/implicit_layer.d
|
||||
mkdir -p "$XDG_CONFIG_HOME"/{vkBasalt,reshade/Shaders,reshade/Textures}
|
||||
cp vkBasalt.64/libvkbasalt.so $LIB_DIR/
|
||||
cp vkBasalt.32/libvkbasalt.so $LIB32_DIR/
|
||||
|
||||
# there is only one vkBasalt.json file, use the 64-bit directory for both, copy and make replacements
|
||||
if grep -q SteamOS /etc/os-release ; then
|
||||
sed -e "s|libvkbasalt.so|${USER_HOME}/.local/lib/libvkbasalt.so|" -e "s/ENABLE_VKBASALT/SteamDeck/" vkBasalt.64/vkBasalt.json > $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.json
|
||||
sed -e "s|libvkbasalt.so|${USER_HOME}/.local/lib32/libvkbasalt.so|" -e "s/ENABLE_VKBASALT/SteamDeck/" vkBasalt.64/vkBasalt.json > $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.x86.json
|
||||
sed -e "s|libvkbasalt.so|${LIB_DIR}/libvkbasalt.so|" -e "s/ENABLE_VKBASALT/SteamDeck/" vkBasalt.64/vkBasalt.json > $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.json
|
||||
sed -e "s|libvkbasalt.so|${LIB32_DIR}/libvkbasalt.so|" -e "s/ENABLE_VKBASALT/SteamDeck/" vkBasalt.64/vkBasalt.json > $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.x86.json
|
||||
else
|
||||
sed -e "s|libvkbasalt.so|${USER_HOME}/.local/lib/libvkbasalt.so|" vkBasalt.64/vkBasalt.json > $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.json
|
||||
sed -e "s|libvkbasalt.so|${USER_HOME}/.local/lib32/libvkbasalt.so|" vkBasalt.64/vkBasalt.json > $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.x86.json
|
||||
sed -e "s|libvkbasalt.so|${LIB_DIR}/libvkbasalt.so|" vkBasalt.64/vkBasalt.json > $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.json
|
||||
sed -e "s|libvkbasalt.so|${LIB32_DIR}/libvkbasalt.so|" vkBasalt.64/vkBasalt.json > $VULKAN_DATA_DIR/implicit_layer.d/vkBasalt.x86.json
|
||||
fi
|
||||
chown $USER:$USER $USER_HOME/.local/share/vulkan/implicit_layer.d/vkBasalt.*
|
||||
|
||||
# copy the vkBasalt.conf file and make replacements
|
||||
sed -e "s|/path/to/reshade-shaders|${USER_HOME}/.config/reshade|" \
|
||||
-e "s|/path/to/virtual_display|${USER_HOME}/.config/reshade/Shaders/IMUAdjust.fx|" \
|
||||
-e "s|/path/to/sideview|${USER_HOME}/.config/reshade/Shaders/Sideview.fx|" \
|
||||
config/vkBasalt.conf > $USER_HOME/.config/vkBasalt/vkBasalt.conf
|
||||
chown -R $USER:$USER $USER_HOME/.config/vkBasalt
|
||||
sed -e "s|/path/to/reshade-shaders|${RESHADE_CONFIG_DIR}|" \
|
||||
-e "s|/path/to/virtual_display|${RESHADE_CONFIG_DIR}/Shaders/IMUAdjust.fx|" \
|
||||
-e "s|/path/to/sideview|${RESHADE_CONFIG_DIR}/Shaders/Sideview.fx|" \
|
||||
config/vkBasalt.conf > $VKBASALT_CONFIG_DIR/vkBasalt.conf
|
||||
|
||||
echo "Installing the Sombrero shaders and texture files to ${USER_HOME}/.config/reshade/{Shaders,Textures}"
|
||||
cp *.fx* $USER_HOME/.config/reshade/Shaders
|
||||
cp *.png $USER_HOME/.config/reshade/Textures
|
||||
chown -R $USER:$USER $USER_HOME/.config/reshade
|
||||
echo "Installing the Sombrero shaders and texture files to ${RESHADE_CONFIG_DIR}/{Shaders,Textures}"
|
||||
cp *.fx* $RESHADE_CONFIG_DIR/Shaders
|
||||
cp *.png $RESHADE_CONFIG_DIR/Textures
|
||||
|
||||
# escaping sed replace: https://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
|
||||
ESCAPED_USER_HOME=$(printf '%s\n' "$USER_HOME" | sed -e 's/[\/&]/\\&/g')
|
||||
chown -R $USER:$GROUP $LIB_DIR
|
||||
chown -R $USER:$GROUP $LIB32_DIR
|
||||
chown -R $USER:$GROUP $DATA_DIR
|
||||
chown -R $USER:$GROUP $VULKAN_DATA_DIR
|
||||
chown -R $USER:$GROUP $RESHADE_CONFIG_DIR
|
||||
chown -R $USER:$GROUP $VKBASALT_CONFIG_DIR
|
||||
chown -R $USER:$GROUP $STATE_DIR
|
||||
chown -R $USER:$GROUP $BIN_DIR/breezy_vulkan_*
|
||||
|
||||
echo "Copying the verification script and manifest to ${USER_HOME}/.local/bin/breezy_vulkan"
|
||||
sed -i -e "s/{user_home}/$ESCAPED_USER_HOME/g" bin/verify_installation
|
||||
if [ ! -d "$USER_HOME/.local/bin/breezy_vulkan" ]; then
|
||||
mkdir -p $USER_HOME/.local/bin/breezy_vulkan
|
||||
fi
|
||||
cp -p bin/verify_installation $USER_HOME/.local/bin/breezy_vulkan
|
||||
cp manifest $USER_HOME/.local/bin/breezy_vulkan
|
||||
# clear bash's cache of executable locations, so it can find the newly installed scripts
|
||||
hash -r
|
||||
|
||||
# set up the XREAL driver using the local binary
|
||||
echo "Installing xrealAirLinuxDriver"
|
||||
echo "BEGIN - xreal_driver_setup"
|
||||
# set up the XR driver using the local binary
|
||||
echo "Installing xrDriver"
|
||||
echo "BEGIN - xr_driver_setup"
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
bin/xreal_driver_setup $(pwd)/xrealAirLinuxDriver.tar.gz
|
||||
bin/xr_driver_setup $(pwd)/xrDriver.tar.gz
|
||||
else
|
||||
bin/xreal_driver_setup -v $1 $(pwd)/xrealAirLinuxDriver.tar.gz
|
||||
bin/xr_driver_setup -v $1 $(pwd)/xrDriver.tar.gz
|
||||
fi
|
||||
|
||||
echo "END - xreal_driver_setup"
|
||||
echo "END - xr_driver_setup"
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# create a string to string mapping, file name to expected file location
|
||||
declare -A file_paths
|
||||
file_paths=(
|
||||
["bin/breezy_vulkan_uninstall"]="{user_home}/bin/breezy_vulkan_uninstall"
|
||||
["vkBasalt.64/libvkbasalt.so"]="{user_home}/.local/lib/libvkbasalt.so"
|
||||
["vkBasalt.32/libvkbasalt.so"]="{user_home}/.local/lib32/libvkbasalt.so"
|
||||
["IMUAdjust.fx"]="{user_home}/.config/reshade/Shaders/IMUAdjust.fx"
|
||||
["ReShade.fxh"]="{user_home}/.config/reshade/Shaders/ReShade.fxh"
|
||||
["ReShadeUI.fxh"]="{user_home}/.config/reshade/Shaders/ReShadeUI.fxh"
|
||||
["Sideview.fx"]="{user_home}/.config/reshade/Shaders/Sideview.fx"
|
||||
["calibrating.png"]="{user_home}/.config/reshade/Textures/calibrating.png"
|
||||
["custom_banner.png"]="{user_home}/.config/reshade/Textures/custom_banner.png"
|
||||
["build/driver_air_glasses/manifest"]="{user_home}/.local/bin/xr_driver/manifest"
|
||||
)
|
||||
|
||||
# verify the file hashes in ./manifest
|
||||
while IFS= read -r line
|
||||
do
|
||||
# split the line into hash and filename
|
||||
manifest_hash=$(echo $line | awk '{print $1}')
|
||||
file=$(echo $line | awk '{print $2}')
|
||||
|
||||
actual_file_path=${file_paths[$file]}
|
||||
|
||||
# compute the SHA256 hash of the actual file
|
||||
actual_hash=$(sha256sum $actual_file_path | awk '{print $1}')
|
||||
|
||||
# compare the hashes
|
||||
if ! [ "$manifest_hash" = "$actual_hash" ]; then
|
||||
echo "Verification failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
done < "{user_home}/.local/bin/breezy_vulkan/manifest"
|
||||
|
||||
# if our checks succeeded, run the xr_driver verify script
|
||||
{user_home}/.local/bin/xr_driver/verify_installation > /dev/null
|
||||
|
||||
echo "Verification succeeded"
|
||||
Loading…
Reference in New Issue