Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add window blur #1115

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ install: clean-build $(BINS)

$(OSAX_SRC): $(OSAX_PATH)/loader.m $(OSAX_PATH)/payload.m
xcrun clang $(OSAX_PATH)/loader.m -shared -O2 -mmacosx-version-min=10.13 -arch x86_64 -o $(OSAX_PATH)/loader -framework Foundation
xcrun clang $(OSAX_PATH)/payload.m -shared -fPIC -O2 -mmacosx-version-min=10.13 -arch x86_64 -arch arm64e -o $(OSAX_PATH)/payload -framework Foundation -framework Carbon
xcrun clang $(OSAX_PATH)/payload.m -shared -fPIC -O2 -mmacosx-version-min=10.13 -arch x86_64 -arch arm64e -o $(OSAX_PATH)/payload -framework Foundation -framework Carbon -F/System/Library/PrivateFrameworks -framework SkyLight
Copy link
Author

Choose a reason for hiding this comment

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

Because I'm using SLSSetWindowBackgroundBlurRadius in payload.m

xcrun clang $(OSAX_PATH)/mach_loader.m -O2 -mmacosx-version-min=10.13 -arch x86_64 -arch arm64e -o $(OSAX_PATH)/mach_loader -framework Cocoa
xxd -i -a $(OSAX_PATH)/loader $(OSAX_PATH)/loader_bin.c
xxd -i -a $(OSAX_PATH)/payload $(OSAX_PATH)/payload_bin.c
Expand Down
35 changes: 35 additions & 0 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extern bool g_verbose;
#define COMMAND_CONFIG_TOPMOST "window_topmost"
#define COMMAND_CONFIG_OPACITY "window_opacity"
#define COMMAND_CONFIG_OPACITY_DURATION "window_opacity_duration"
#define COMMAND_CONFIG_BLUR "window_blur"
#define COMMAND_CONFIG_BLUR_RADIUS "window_blur_radius"
#define COMMAND_CONFIG_BORDER "window_border"
#define COMMAND_CONFIG_BORDER_WIDTH "window_border_width"
#define COMMAND_CONFIG_BORDER_ACTIVE_COLOR "active_window_border_color"
Expand Down Expand Up @@ -128,6 +130,7 @@ extern bool g_verbose;
#define COMMAND_WINDOW_CLOSE "--close"
#define COMMAND_WINDOW_LAYER "--layer"
#define COMMAND_WINDOW_OPACITY "--opacity"
#define COMMAND_WINDOW_BLUR "--blur"
#define COMMAND_WINDOW_TOGGLE "--toggle"
#define COMMAND_WINDOW_DISPLAY "--display"
#define COMMAND_WINDOW_SPACE "--space"
Expand Down Expand Up @@ -174,6 +177,7 @@ extern bool g_verbose;
#define ARGUMENT_RULE_KEY_DISPLAY "display"
#define ARGUMENT_RULE_KEY_SPACE "space"
#define ARGUMENT_RULE_KEY_ALPHA "opacity"
#define ARGUMENT_RULE_KEY_BLUR "blur"
#define ARGUMENT_RULE_KEY_MANAGE "manage"
#define ARGUMENT_RULE_KEY_STICKY "sticky"
#define ARGUMENT_RULE_KEY_MFF "mouse_follows_focus"
Expand Down Expand Up @@ -1050,6 +1054,26 @@ static void handle_domain_config(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_CONFIG_BLUR)) {
struct token value = get_token(&message);
if (!token_is_valid(value)) {
fprintf(rsp, "%s\n", bool_str[g_window_manager.enable_window_blur]);
} else if (token_equals(value, ARGUMENT_COMMON_VAL_OFF)) {
window_manager_set_window_blur_enabled(&g_window_manager, false);
} else if (token_equals(value, ARGUMENT_COMMON_VAL_ON)) {
window_manager_set_window_blur_enabled(&g_window_manager, true);
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_CONFIG_BLUR_RADIUS)) {
struct token_value value = token_to_value(get_token(&message), false);
if (value.type == TOKEN_TYPE_INVALID) {
fprintf(rsp, "%d\n", g_window_manager.window_blur_radius);
} else if (value.type == TOKEN_TYPE_INT && value.int_value) {
g_window_manager.window_blur_radius = value.int_value;
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.token.length, value.token.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_CONFIG_OPACITY_DURATION)) {
struct token_value value = token_to_value(get_token(&message), false);
if (value.type == TOKEN_TYPE_INVALID) {
Expand Down Expand Up @@ -1904,6 +1928,17 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.token.length, value.token.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_WINDOW_BLUR)) {
struct token_value value = token_to_value(get_token(&message), false);
if (value.type == TOKEN_TYPE_U32 && value.u32_value) {
if (window_manager_set_blur_radius(&g_window_manager, acting_window, value.u32_value)) {
acting_window->blur_radius = value.u32_value;
} else {
daemon_fail(rsp, "could not change blur radius of window with id '%d' due to an error with the scripting-addition.\n", acting_window->id);
}
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.token.length, value.token.text, command.length, command.text, domain.length, domain.text);
}
} else if (token_equals(command, COMMAND_WINDOW_TOGGLE)) {
struct token value = get_token(&message);
if (token_equals(value, ARGUMENT_WINDOW_TOGGLE_FLOAT)) {
Expand Down
123 changes: 59 additions & 64 deletions src/osax/payload.m
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@
extern void CGSShowSpaces(int cid, CFArrayRef spaces);
extern void CGSHideSpaces(int cid, CFArrayRef spaces);

// extern CGError SLSSetSurfaceBackgroundBlur(int cid, uint32_t wid);
extern CGError SLSSetWindowBackgroundBlurRadius(int cid, uint32_t wid, uint32_t radius);
// extern CGError SLSSetWindowBackgroundBlurRadiusStyle(int cid, uint32_t wid, uint32_t radius);
// extern CGError SLSSetWindowBackgroundBlurRadiusWithOpacityHint(int cid, uint32_t wid, uint32_t radius);

static int _connection;
static id dock_spaces;
static id dp_desktop_picture_manager;
Expand Down Expand Up @@ -332,17 +337,22 @@ static void init_instances()
unsigned int length;
} Token;

static bool token_equals(Token token, const char *match)
static bool token_sub_equals(Token token, const char *match, unsigned int length)
{
const char *at = match;
for (int i = 0; i < token.length; ++i, ++at) {
for (int i = 0; i < length; ++i, ++at) {
if ((*at == 0) || (token.text[i] != *at)) {
return false;
}
}
return *at == 0;
}

static bool token_equals(Token token, const char *match)
{
return token_sub_equals(token, match, token.length);
}

static uint64_t token_to_uint64t(Token token)
{
uint64_t result = 0;
Expand Down Expand Up @@ -583,12 +593,8 @@ static void do_space_change(const char *message)
}
}

static void do_window_scale(const char *message)
static void do_window_scale(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

CGRect frame = {};
CGSGetWindowBounds(_connection, wid, &frame);
CGAffineTransform original_transform = CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y);
Expand Down Expand Up @@ -623,12 +629,8 @@ static void do_window_scale(const char *message)
}
}

static void do_window_move(const char *message)
static void do_window_move(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token x_token = get_token(&message);
int x = token_to_int(x_token);

Expand All @@ -643,47 +645,38 @@ static void do_window_move(const char *message)
[window_list release];
}

static void do_window_alpha(const char *message)
static void do_window_alpha(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token alpha_token = get_token(&message);
float alpha = token_to_float(alpha_token);
CGSSetWindowAlpha(_connection, wid, alpha);
}

static void do_window_alpha_fade(const char *message)
static void do_window_blur(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;
Token radius_token = get_token(&message);
uint32_t radius = token_to_uint32t(radius_token);
SLSSetWindowBackgroundBlurRadius(_connection, wid, radius);
}

static void do_window_alpha_fade(uint32_t wid, const char *message)
{
Token alpha_token = get_token(&message);
float alpha = token_to_float(alpha_token);
Token duration_token = get_token(&message);
float duration = token_to_float(duration_token);
CGSSetWindowListAlpha(_connection, &wid, 1, alpha, duration);
}

static void do_window_level(const char *message)
static void do_window_level(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token key_token = get_token(&message);
int key = token_to_int(key_token);
CGSSetWindowLevel(_connection, wid, CGWindowLevelForKey(key));
}

static void do_window_sticky(const char *message)
static void do_window_sticky(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token value_token = get_token(&message);
int value = token_to_int(value_token);
int tags[2] = { kCGSOnAllWorkspacesTagBit, 0 };
Expand All @@ -695,28 +688,21 @@ static void do_window_sticky(const char *message)
}

typedef void (*focus_window_call)(ProcessSerialNumber psn, uint32_t wid);
static void do_window_focus(const char *message)
static void do_window_focus(uint32_t wid, const char *message)
{
if (set_front_window_fp == 0) return;

int window_connection;
ProcessSerialNumber window_psn;

Token wid_token = get_token(&message);
uint32_t window_id = token_to_uint32t(wid_token);

CGSGetWindowOwner(_connection, window_id, &window_connection);
CGSGetWindowOwner(_connection, wid, &window_connection);
CGSGetConnectionPSN(window_connection, &window_psn);

((focus_window_call) set_front_window_fp)(window_psn, window_id);
((focus_window_call) set_front_window_fp)(window_psn, wid);
}

static void do_window_shadow(const char *message)
static void do_window_shadow(uint32_t wid, const char *message)
{
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token value_token = get_token(&message);
int value = token_to_int(value_token);
int tags[2] = { kCGSNoShadowTagBit, 0};
Expand All @@ -727,7 +713,7 @@ static void do_window_shadow(const char *message)
}
}

static void do_window_group_add(const char *message)
static void do_window_group_add(uint32_t wid, const char *message)
{
Token parent_token = get_token(&message);
uint32_t parent = token_to_uint32t(parent_token);
Expand All @@ -741,7 +727,7 @@ static void do_window_group_add(const char *message)
CGSAddWindowToWindowOrderingGroup(_connection, parent, child, 1);
}

static void do_window_group_remove(const char *message)
static void do_window_group_remove(uint32_t wid, const char *message)
{
Token parent_token = get_token(&message);
uint32_t parent = token_to_uint32t(parent_token);
Expand Down Expand Up @@ -792,26 +778,35 @@ static void handle_message(int sockfd, const char *message)
do_space_destroy(message);
} else if (token_equals(token, "space_move")) {
do_space_move(message);
} else if (token_equals(token, "window_scale")) {
do_window_scale(message);
} else if (token_equals(token, "window_move")) {
do_window_move(message);
} else if (token_equals(token, "window_alpha")) {
do_window_alpha(message);
} else if (token_equals(token, "window_alpha_fade")) {
do_window_alpha_fade(message);
} else if (token_equals(token, "window_level")) {
do_window_level(message);
} else if (token_equals(token, "window_sticky")) {
do_window_sticky(message);
} else if (token_equals(token, "window_focus")) {
do_window_focus(message);
} else if (token_equals(token, "window_shadow")) {
do_window_shadow(message);
} else if (token_equals(token, "window_group_add")) {
do_window_group_add(message);
} else if (token_equals(token, "window_group_remove")) {
do_window_group_remove(message);
} else if (token_sub_equals(token, "window_", 7)) {
Token wid_token = get_token(&message);
uint32_t wid = token_to_uint32t(wid_token);
if (!wid) return;

Token window_command = get_token(&message);
if (token_equals(window_command, "scale")) {
do_window_scale(wid, message);
} else if (token_equals(window_command, "move")) {
do_window_move(wid, message);
} else if (token_equals(window_command, "alpha")) {
do_window_alpha(wid, message);
} else if (token_equals(window_command, "alpha_fade")) {
do_window_alpha_fade(wid, message);
} else if (token_equals(window_command, "blur")) {
do_window_blur(wid, message);
} else if (token_equals(window_command, "level")) {
do_window_level(wid, message);
} else if (token_equals(window_command, "sticky")) {
do_window_sticky(wid, message);
} else if (token_equals(window_command, "focus")) {
do_window_focus(wid, message);
} else if (token_equals(window_command, "shadow")) {
do_window_shadow(wid, message);
} else if (token_equals(window_command, "group_add")) {
do_window_group_add(wid, message);
} else if (token_equals(window_command, "group_remove")) {
do_window_group_remove(wid, message);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/sa.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ bool scripting_addition_add_to_window_group(uint32_t child_wid, uint32_t parent_
bool scripting_addition_remove_from_window_group(uint32_t child_wid, uint32_t parent_wid);
bool scripting_addition_move_window(uint32_t wid, int x, int y);
bool scripting_addition_set_opacity(uint32_t wid, float opacity, float duration);
bool scripting_addition_set_blur(uint32_t wid, uint32_t radius);
bool scripting_addition_set_layer(uint32_t wid, int layer);
bool scripting_addition_set_sticky(uint32_t wid, bool sticky);
bool scripting_addition_set_shadow(uint32_t wid, bool shadow);
Expand Down
7 changes: 7 additions & 0 deletions src/sa.m
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,13 @@ bool scripting_addition_set_opacity(uint32_t wid, float opacity, float duration)
return scripting_addition_run_command(message);
}

bool scripting_addition_set_blur(uint32_t wid, uint32_t radius)
{
char message[MAXLEN];
snprintf(message, sizeof(message), "window_blur %d %d", wid, radius);
return scripting_addition_run_command(message);
}

bool scripting_addition_set_layer(uint32_t wid, int layer)
{
char message[MAXLEN];
Expand Down
3 changes: 3 additions & 0 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ void window_serialize(FILE *rsp, struct window *window)
bool visible = !is_minimized && !window->application->is_hidden && (window->is_sticky || space_is_visible(sid));
bool border = window->border.id ? 1 : 0;
float opacity = window_opacity(window);
uint32_t blur_radius = window->blur_radius;
bool grabbed = window == g_mouse_state.window;

CFStringRef cfrole = window_role(window);
Expand Down Expand Up @@ -143,6 +144,7 @@ void window_serialize(FILE *rsp, struct window *window)
"\t\"space\":%d,\n"
"\t\"level\":%d,\n"
"\t\"opacity\":%.4f,\n"
"\t\"blur-radius\":%d,\n"
"\t\"split-type\":\"%s\",\n"
"\t\"stack-index\":%d,\n"
"\t\"can-move\":%s,\n"
Expand Down Expand Up @@ -172,6 +174,7 @@ void window_serialize(FILE *rsp, struct window *window)
space,
window_level(window),
opacity,
blur_radius,
split,
stack_index,
json_bool(window_can_move(window)),
Expand Down
1 change: 1 addition & 0 deletions src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct window
bool is_floating;
bool is_sticky;
float opacity;
uint32_t blur_radius;
bool rule_manage;
bool rule_fullscreen;
bool rule_mff;
Expand Down
Loading