Skip to content

Conversation

@GustavoWidman
Copy link

initializes a darwin module and nix package that can be used by nix-darwin users. usage is really simple, you just enable it and then either give it a path to a config, a string path (like a agenix secret path) or a freeform config, like so:

...
  services.rift = {
    enable = true;
    config = ./config.toml;
  };
...

or

...
  services.rift = {
    enable = true;
    config = "/run/agenix/rift-config";
  };
...

or

...
  services.rift = {
    enable = true;
    config = {
      settings = {
        animate = true;
        animation_duration = 0.3;
        animation_fps = 100.0;
        animation_easing = "ease_in_out";

        focus_follows_mouse = true;
        mouse_follows_focus = true;
        mouse_hides_on_focus = true;

        auto_focus_blacklist = [ ];

        run_on_start = [ ];

        hot_reload = true;

        layout = {
          mode = "traditional";

          stack = {
            stack_offset = 40.0;
            default_orientation = "perpendicular";
          };

          gaps = {
            outer = {
              top = 0;
              left = 0;
              bottom = 0;
              right = 0;
            };

            inner = {
              horizontal = 0;
              vertical = 0;
            };
          };
        };

        ui = {
          menu_bar = {
            enabled = false;
            show_empty = false;
          };

          stack_line = {
            enabled = false;
            horiz_placement = "top";
            vert_placement = "left";
            thickness = 0.0;
            spacing = 0.0;
          };

          mission_control = {
            enabled = false;
            fade_enabled = false;
            fade_duration_ms = 180.0;
          };
        };

        gestures = {
          enabled = false;
          invert_horizontal_swipe = false;
          swipe_vertical_tolerance = 0.4;
          skip_empty = true;
          fingers = 3;
          distance_pct = 0.08;
          haptics_enabled = true;
          haptic_pattern = "level_change";
        };

        window_snapping = {
          drag_swap_fraction = 0.3;
        };
      };

      virtual_workspaces = {
        enabled = true;
        default_workspace_count = 4;
        auto_assign_windows = true;
        preserve_focus_per_workspace = true;
        workspace_auto_back_and_forth = false;

        workspace_names = [
          "first"
          "second"
        ];

        app_rules = [ ];
      };

      modifier_combinations = {
        comb1 = "Alt + Shift";
      };

      keys = {
        "Alt + Z" = "toggle_space_activated";

        "Alt + H" = {
          move_focus = "left";
        };
        "Alt + J" = {
          move_focus = "down";
        };
        "Alt + K" = {
          move_focus = "up";
        };
        "Alt + L" = {
          move_focus = "right";
        };

        "comb1 + H" = {
          move_node = "left";
        };
        "comb1 + J" = {
          move_node = "down";
        };
        "comb1 + K" = {
          move_node = "up";
        };
        "comb1 + L" = {
          move_node = "right";
        };

        "Alt + 0" = {
          switch_to_workspace = 0;
        };
        "Alt + 1" = {
          switch_to_workspace = 1;
        };
        "Alt + 2" = {
          switch_to_workspace = 2;
        };
        "Alt + 3" = {
          switch_to_workspace = 3;
        };

        "comb1 + 0" = {
          move_window_to_workspace = 0;
        };
        "comb1 + 1" = {
          move_window_to_workspace = 1;
        };
        "comb1 + 2" = {
          move_window_to_workspace = 2;
        };
        "comb1 + 3" = {
          move_window_to_workspace = 3;
        };

        "Alt + Tab" = "switch_to_last_workspace";

        "Alt + Shift + Left" = {
          join_window = "left";
        };
        "Alt + Shift + Right" = {
          join_window = "right";
        };
        "Alt + Shift + Up" = {
          join_window = "up";
        };
        "Alt + Shift + Down" = {
          join_window = "down";
        };
        "Alt + Comma" = "toggle_stack";
        "Alt + Slash" = "toggle_orientation";
        "Alt + Ctrl + E" = "unjoin_windows";

        "Alt + Shift + Space" = "toggle_window_floating";
        "Alt + F" = "toggle_fullscreen";
        "Alt + Shift + F" = "toggle_fullscreen_within_gaps";
        "comb1 + Ctrl + Space" = "toggle_focus_floating";

        "Alt + Shift + Equal" = "resize_window_grow";
        "Alt + Shift + Minus" = "resize_window_shrink";

        "Alt + Shift + D" = "debug";

        "Alt + Ctrl + S" = "serialize";
        "Alt + Ctrl + Q" = "save_and_exit";
      };
    };
  };
...

the launchd agent is interoperable with rift's CLI service management, so you CAN restart the service by simply doing rift service restart (and any other rift service command)

there's also a package (duh) and a nixpkgs overlay, which allows you to do

{ rift, pkgs, ... }:
{
  nixpkgs.overlays = rift.overlays.default;
  environment.systemPackages = [
    pkgs.rift
  ];
}

everything is a flake and can be added to YOUR nix flake config by adding

...
    rift.url = "github:acsandmann/rift";
...

to your inputs key on flake.nix

@acsandmann
Copy link
Owner

i have a few concerns with this. we are introducing another copy of the default config and i would rather we don't as it means we have to update two places when updating and i fear i will eventually forget to and it will get out of sync. also, i haven't ever used nix, nor do i ever really plan to so i am somewhat wary of maintaining a flake as i don't really know how it works so im just not sure what is involved.

@GustavoWidman
Copy link
Author

i can try to embed the default config instead, that way it just turns low maintenance

@acsandmann
Copy link
Owner

that would be a lot more palatable

@GustavoWidman
Copy link
Author

alright, that should be it. i'm going to test this to see if there were any regressions...

@GustavoWidman
Copy link
Author

tested, seems to be working fine:

$ cat ~/Library/LaunchAgents/git.acsandmann.rift.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>EnvironmentVariables</key>
        <dict>
                <key>PATH</key>
                <string>/run/current-system/sw/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
                <key>RUST_LOG</key>
                <string>error,warn,info</string>
        </dict>
        <key>KeepAlive</key>
        <dict>
                <key>Crashed</key>
                <true/>
                <key>SuccessfulExit</key>
                <false/>
        </dict>
        <key>Label</key>
        <string>git.acsandmann.rift</string>
        <key>LimitLoadToSessionType</key>
        <string>Aqua</string>
        <key>Nice</key>
        <integer>-20</integer>
        <key>ProcessType</key>
        <string>Interactive</string>
        <key>ProgramArguments</key>
        <array>
                <string>/bin/sh</string>
                <string>-c</string>
                <string>/bin/wait4path /nix/store &amp;&amp; exec /nix/store/00j4ygzcl7vll888s0z2zqrxhd7wg44y-rift-wm-0.1.2-beta/bin/rift --config /nix/store/9vqyp2ia297fga1yp1b6878hc2kcpi6m-source/rift.default.toml</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/tmp/rift.err.log</string>
        <key>StandardOutPath</key>
        <string>/tmp/rift.out.log</string>
</dict>
</plist>
$ cat /nix/store/9vqyp2ia297fga1yp1b6878hc2kcpi6m-source/rift.default.toml
# rift config
# Copy this file to ~/.config/rift/config.toml or $HOME~/.config/rift/config.toml                                                                                                                                                                                               [settings]                                                                                                                              # Animations                                                                                                                            # - animate: master switch for all window animations
...

default config goes into nix store and is used as config if no config is specified. follows the config on the git repo. only downside to this is that it's technically less documented than the explicit default but it's a tradeoff i guess...

@GustavoWidman
Copy link
Author

GustavoWidman commented Nov 8, 2025

as for maintaining the flake itself, i can help in adding some github workflows that run on release to update the flake lockfile and maybe even build the releases and push them to their respective nix binary caches

@GustavoWidman
Copy link
Author

as for maintaining the flake itself, i can help in adding some github workflows that run on release to update the flake lockfile and maybe even build the releases and push them to their respective nix binary caches

as for the binary cache, it might be likely you'll have to configure something like cachix (create an account, create a binary cache for rift, get an api key and put it in github secrets) unless we open a PR to put this on nixpkgs (which will take god knows how long). i'll leave the code for this ambiguous for now...

acsandmann added a commit that referenced this pull request Nov 9, 2025
acsandmann added a commit that referenced this pull request Nov 9, 2025
this for some reason wasn't working before but now is okay??
@acsandmann
Copy link
Owner

@GustavoWidman im okay with no binary cache as long as we can make it pull from github releases. right now the homebrew release cycle uploads a fat/universal binary to github releases and thats where the brew formula/cask/whatever pulls from. so we could probably (idk, i assume so) pull from that for the nix flake.

@GustavoWidman
Copy link
Author

@GustavoWidman im okay with no binary cache as long as we can make it pull from github releases. right now the homebrew release cycle uploads a fat/universal binary to github releases and thats where the brew formula/cask/whatever pulls from. so we could probably (idk, i assume so) pull from that for the nix flake.

alright, yea, i can do that. i'll add a rift-bin package (that's the default) that fetches impure builds from the github releases and another that builds from scratch (like we do currently)

@GustavoWidman
Copy link
Author

okay, this should work but i can't really test it well, i dislike messing with github actions...

@acsandmann
Copy link
Owner

@GustavoWidman is this good to go? if so i will proceed with a merge and it will probably land in 0.3.0

@GustavoWidman
Copy link
Author

@GustavoWidman is this good to go? if so i will proceed with a merge and it will probably land in 0.3.0

yep yep, good to go

@GustavoWidman
Copy link
Author

by the way, @acsandmann i'll ask that in newer releases you also update the version key in the Cargo.toml file as the nix build uses the version from there when building the binary and versioning it internally.

[package]
name = "rift-wm"
version = "0.1.0"
version = "0.2.8-beta"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Nix convention to match GitHub release, or Git tag?

@disbolog
Copy link

disbolog commented Jan 2, 2026

Once this lands as flake, could this also be upstreamed to https://github.com/nix-darwin/nix-darwin ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants