yabai icon indicating copy to clipboard operation
yabai copied to clipboard

Feature Request: support window vibrancy and blur

Open yorhodes opened this issue 2 years ago • 15 comments

This is a feature in other window manager ecosystems https://www.reddit.com/r/unixporn/comments/rqjrls/i3gaps_local_man_install_arch_tells_no_one/ https://www.reddit.com/r/unixporn/comments/nkxagu/bspwm_i_quite_like_blur/

It looks like this can be implemented in macos fairly easily? https://developer.apple.com/documentation/uikit/uivibrancyeffect?language=objc https://developer.apple.com/documentation/appkit/nsvisualeffectview?language=objc

I would love to contribute this feature but not sure how feasible and I couldn't find much useful documentation. It seems like the Core Graphics API in use does not match what I found in Apple's docs.

https://github.com/koekeishiya/yabai/blob/846723a2629daf995882359f26967889654a0b4d/src/osax/payload.m#L654

versus

https://developer.apple.com/documentation/coregraphics/1456404-cgcontextsetalpha?language=objc

What are your thoughts @koekeishiya

yorhodes avatar Dec 29 '21 05:12 yorhodes

This would be for background blur:

extern CGError SLSSetWindowBackgroundBlurRadius(int cid, uint32_t wid, uint32_t radius);

and the other things needed for vibrancy effects I think are listed in the bottom of this file: https://github.com/NUIKit/CGSInternal/blob/master/CGSWindow.h

FelixKratz avatar Dec 29 '21 07:12 FelixKratz

where the hell is the Core Graphics Skylight framework documented?

yorhodes avatar Dec 29 '21 21:12 yorhodes

https://developer.apple.com/documentation/appkit/nsvisualeffectview?language=objc

yorhodes avatar Dec 30 '21 00:12 yorhodes

I looked at blur a long time ago and did not like the result: https://github.com/koekeishiya/yabai/issues/493 Maybe I'll revisit in the future.

koekeishiya avatar Jan 03 '22 17:01 koekeishiya

I don't think #1115 is the way to go about this. Windows with modified alpha will deactivate the background blur. I have quickly hacked together something with limelight: Screen Shot 2022-01-13 at 17 53 57

The way my quick and dirty hack works is by creating a new transparent window behind the actual window where I set SLSSetWindowBackgroundBlurRadius, such that when the window receives an alpha it will be in front of a blurred "backdrop". Theoretically this can also be implemented in yabai directly, but the window ordering groups are broken on monterey.

FelixKratz avatar Jan 13 '22 17:01 FelixKratz

Window ordering groups work fine on Monterey, it is the movement group that causes the issues as far as I remember, so I do believe your version for enabling window blurs could work.

koekeishiya avatar Apr 14 '22 13:04 koekeishiya

@FelixKratz @koekeishiya any way I can help ship this to yabai or will this only be possible with limelight?

yorhodes avatar Apr 14 '22 18:04 yorhodes

Any update on this?

ghost avatar Jun 10 '22 05:06 ghost

@FelixKratz @koekeishiya any way I can help ship this to yabai or will this only be possible with limelight?

It is a fairly minor change that can be incorporated the exact same way current window borders are implemented. Create a new window, „glue“ this window to the host, always keep it ordered behind the host and give the window a background blur. Then all inactive windows, which receive an alpha via the scripting addition appear to have a blurred background.

This is exactly what I have done in my above screenshots.

FelixKratz avatar Jun 19 '22 19:06 FelixKratz

It can be done even easier than described above: The borders have no reason to be in front of the window. Rather, I have chosen to glue them below the window and apply a negative inset to them. This way rounded borders can also be implemented and the distracting border flickering is a non problem, additionally content from the window is not truncated.

When doing it this way it is as simple as giving the border a fill color and a background blur. This is my implementation of it: https://github.com/FelixKratz/yabai/commit/fb48e7617f7e75d246684b9a3cdce37560f835fe including rounded borders as you can see here: Screen Shot 2022-06-20 at 09 17 59

FelixKratz avatar Jun 20 '22 07:06 FelixKratz

I see that a previous pull request #1115 was made for window blurring, but it was closed. But has this new solution been made into a pull request yet?

Would love to see @FelixKratz 's solution come to fruition! :)

kevinmonisit avatar Aug 19 '22 14:08 kevinmonisit

I think I have read somewhere that pull requests are generally not welcome on this project. Just create a fork and patch these changes in, thats why I have linked my fork for most of the changes I have made (e.g. the mach ipc for the scripting addition).

This being said, I noticed some people are actually using my fork. Please don't, it is full of things I have changed only for my personal preference and for experimenting. It is only linked so you can cherry-pick changes you like to your own fork.

FelixKratz avatar Aug 19 '22 14:08 FelixKratz

FelixKratz@fb48e76

what do you use for desktop customization? It looks amazing

weeebdev avatar Sep 08 '22 15:09 weeebdev

@weeebdev https://github.com/FelixKratz/SketchyBar

yorhodes avatar Sep 08 '22 17:09 yorhodes

@weeebdev https://github.com/FelixKratz/SketchyBar

Thanks. Do you consider adding a rounded corners on the border?

weeebdev avatar Sep 08 '22 17:09 weeebdev

This will be fixed with the changes being made for #1430

koekeishiya avatar Sep 20 '22 10:09 koekeishiya

how do I install my own fork of yabai?

Tushar1729-k avatar Oct 13 '22 04:10 Tushar1729-k

It is possible to bind a CAContext to an SLSSurface and add a CABackdropLayer with CAFilters to create further backdrop effects, i.e. stronger blur, vibrancy, saturation, darken, lighten, etc.... is this something worth discussing for yabai?

FelixKratz avatar Jan 11 '23 12:01 FelixKratz

If it can be added to an arbitrary window using the scripting-addition, yes. If it is going to work in the same way as the current version that relies on the borders, then I'm not particularly interested in making adjustments at this time.

koekeishiya avatar Jan 11 '23 13:01 koekeishiya

Yeah, that is possible -- I just tried it and I am able to add arbitrary surfaces to arbitrary windows. The surface moves and orders with the window fully automatically. This could also be used to make a more robust border system.

But it has to be handled with caution, because these surfaces will continue to exist even after yabai exits.

FelixKratz avatar Jan 11 '23 13:01 FelixKratz

But it has to be handled with caution, because these surfaces will continue to exist even after yabai exits.

Maybe it is time to work on having fully persistent state, which would also solve this new issue.

koekeishiya avatar Jan 11 '23 14:01 koekeishiya

@FelixKratz

I assume this works more or less in the following way?

  1. Create a new CAContext
  2. Create a new CALayer and set up filters
  3. Set the CALayer as the layer for the CAContext
  4. Create and setup a surface for the arbitrary window.
  5. Bind the surface to the CAContext we created using its id?

koekeishiya avatar Jan 11 '23 22:01 koekeishiya

@FelixKratz

I assume this works more or less in the following way?

  1. Create a new CAContext
  2. Create a new CALayer and set up filters
  3. Set the CALayer as the layer for the CAContext
  4. Create and setup a surface for the arbitrary window.
  5. Bind the surface to the CAContext we created using its id?

Yes, this is what I was testing with:

  [CATransaction begin];
  CAContext* context = [CAContext contextWithCGSConnection:_connection options:nil];
  CABackdropLayer* layer = [[CABackdropLayer alloc] init];
  layer.frame = bounds;
  layer.windowServerAware = true;
  layer.cornerRadius = 10;
  layer.borderWidth = 2;
  layer.borderColor = CGColorCreateGenericRGB(1, 1, 1, 1);
  CAFilter* blur = [[CAFilter alloc] init];
  [blur initWithType:kCAFilterGaussianBlur];

  NSNumber *normalize = [NSNumber numberWithBool:true];
  [blur setValue:normalize forKey:@"inputNormalizeEdges"];
  NSNumber *radius = [NSNumber numberWithFloat:100.0f];
  [blur setValue:radius forKey:@"inputRadius"];

  CAFilter* saturate = [[CAFilter alloc] init];
  [saturate initWithType:kCAFilterColorSaturate];

  NSNumber *saturation = [NSNumber numberWithFloat:1.2f];
  [saturate setValue:saturation forKey:@"inputAmount"];

  NSArray* filters = @[saturate, blur];
  [layer setFilters:filters];

  context.layer = layer;

  uint32_t sid = 0;

  SLSAddSurface(_connection, wid, &sid);
  SLSSetSurfaceBounds(_connection, wid, sid, bounds);
  SLSSetSurfaceResolution(_connection, wid, sid, 2.0);
  SLSSetSurfaceColorSpace(_connection, wid, sid, context.colorSpace);

  SLSBindSurface(_connection, wid, sid, 4, 0, context.contextId);
  SLSOrderSurface(_connection, wid, sid, 1, 0);

  [CATransaction commit];

FelixKratz avatar Jan 11 '23 22:01 FelixKratz

Can we at least get rid of the gray(alpha channel) background appearing while animations are on?

Bellavene avatar Sep 11 '23 20:09 Bellavene

@FelixKratz after https://github.com/koekeishiya/yabai/issues/1889 what has been your solution for this? I'd completely forgotten to update for a while and missed that announcement much to my surprsie. Does your Janky Borders project facilitate blurred windows?

JoshSald avatar Jan 12 '24 20:01 JoshSald