Sway: RFE: transparency of inactive windows

Created on 7 Oct 2018  Â·  18Comments  Â·  Source: swaywm/sway

As the title says.

I'm open to work on this in my spare time (I don't have much, so don't expect it got get ready quickly, but I'm interested in that work), and here's the report to make sure nobody is against implementing that.

There's a demand, and even though there're more important issues, but it's my personal show-stopper for migrating from i3+Compton over to Sway.

I'm new to Sway codebase, and would be glad if someone outlined the steps needed to implement this.

All 18 comments

You could accomplish this with a little Python script that connects to IPC and issues opacity commands as focus changes.

Oh, that's interesting, thanks, I'll look at that.

@SirCmpwn Is that actually possible with the implementation of opacity as it is today? Afaik you can only ever issue opacity commands for the currently focused window. So you could set the opacity to something when the window gets focus and that's all. It doesn't seem possible to set the opacity to something else when the window loses focus.

You can use criteria to apply opacity to other windows.

So, for the most part I've figured how to do it (I'll document it when it's complete, but basically one have to use i3ipc-python library, which needs to be modified to search for sway instead of i3; and then bind a small function to focus event to traverse windows in search for unfocused ones). One thing I don't see is: how to apply opacity command to a particular window? Looking at opacity.c it takes just a single argument, the opacity value.

Use criteria.

Use criteria.

But which criteria do I have to use? There doesn't seem to be "focused" criteria — do I need to extract window id in python script, and then issue a command for that id? Is that id unique?

You can use [con_id=__focused__]

I'd use the window id, since you also need to reset the opacity of the window which was just unfocused. Yes, it's unique.

Thank you all!

So, in short, the steps are:

  1. Install via package manager or pip the i3ipc-python library.
  2. Find in the file i3ipc.pyof its installation the line:

    ['i3', '--get-socketpath'],
    

    and replace with

    ['sway', '--get-socketpath'],
    
  3. run the following script:

    import i3ipc
    
    ipc = i3ipc.Connection()
    
    def on_window_focus(ipc, e):
        for c in ipc.get_tree():
            if c.focused:
                c.command('opacity 1')
            else:
                c.command('opacity 0.8')
    
    ipc.on("window::focus", on_window_focus)
    ipc.main() # enter command loop
    

gotchas:

  • --get-socketpath of sway only works within its session, so be sure to execute it from there.

I'll make a PR to have it in Sway documentation, but I'll probably get to that around next weekend.

You should send a PR for i3ipc-python to connect to sway if i3 isn't running.

Good point, will do.

I use i3ipc-python on sway without any patches...

I use i3ipc-python on sway without any patches...

Oh, it's probably because sway sets SWAYSOCK variable, which is respected by i3ipc-python. Granted, I didn't check it because the analogous I3SOCK is never set by i3 themselves, and I thought it works the same for sway. Oh, well.

As changing wiki does not require PRs, I'm posting a text here, and if nobody has any objections I'm planning to add it somewhere around tomorrow.

As ATM there's just one effect, I'd create a new page Transparency with following content:


On X11, transparency of inactive windows required a compositor, like compton, compmgr, etc. Since on Wayland sway is the compositor, it's implemented here.

Inactive windows can be made transparent by binding opacity α commands to focus events, where α is the opacity value. This can be accomplished with a simple script. An example with python:

  1. Install from a system package manager or pip a python library to talk to sway through i3 ipc protocol, i3ipc-python.
  2. Save the following as inactive-windows-transparency.py:

    import i3ipc
    
    ipc = i3ipc.Connection()
    prev_focused = None
    
    for window in ipc.get_tree():
        if window.focused:
            prev_focused = window
        else:
            window.command('opacity 0.8')
    
    def on_window_focus(ipc, focused):
        global prev_focused
        if focused.container.id != prev_focused.id: # https://github.com/swaywm/sway/issues/2859
            focused.container.command('opacity 1')
            prev_focused.command('opacity 0.8')
            prev_focused = focused.container
    
    ipc.on("window::focus", on_window_focus)
    ipc.main()
    
  3. Add to autostart exec --no-startup-id python ~/Path-to-script/inactive-window-transparency.py

(upd: removed unnecessary comment, and fixed library name i3ipc→i3ipc-python).

Can you make a pull request adding something to contrib/ instead?

Sure, will do. I was thinking too that it would be nice to have such scripts somewhere in source repo, so people could fix bugs in them if they found something. Not to say they can't do it in wiki, just git-repository has a better interface for it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

J0nnyMak0 picture J0nnyMak0  Â·  3Comments

DpoBoceka picture DpoBoceka  Â·  4Comments

soymjolk picture soymjolk  Â·  3Comments

ghost picture ghost  Â·  4Comments

cauebs picture cauebs  Â·  3Comments