mirror of
https://github.com/swaywm/sway.git
synced 2024-12-28 07:56:31 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
013df6a8a5
6 changed files with 158 additions and 20 deletions
|
@ -14,6 +14,7 @@ struct bar {
|
||||||
int ipc_event_socketfd;
|
int ipc_event_socketfd;
|
||||||
int ipc_socketfd;
|
int ipc_socketfd;
|
||||||
int status_read_fd;
|
int status_read_fd;
|
||||||
|
int status_write_fd;
|
||||||
pid_t status_command_pid;
|
pid_t status_command_pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct status_line {
|
||||||
list_t *block_line;
|
list_t *block_line;
|
||||||
const char *text_line;
|
const char *text_line;
|
||||||
command_protocol protocol;
|
command_protocol protocol;
|
||||||
|
bool click_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct status_block {
|
struct status_block {
|
||||||
|
@ -31,6 +32,10 @@ struct status_block {
|
||||||
int border_bottom;
|
int border_bottom;
|
||||||
int border_left;
|
int border_left;
|
||||||
int border_right;
|
int border_right;
|
||||||
|
|
||||||
|
// Set during rendering
|
||||||
|
int x;
|
||||||
|
int width;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +48,11 @@ struct status_line *init_status_line();
|
||||||
*/
|
*/
|
||||||
bool handle_status_line(struct bar *bar);
|
bool handle_status_line(struct bar *bar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle mouse clicks.
|
||||||
|
*/
|
||||||
|
bool status_line_mouse_event(struct bar *bar, int x, int y, uint32_t button);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free status line struct.
|
* Free status line struct.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#ifdef ENABLE_TRAY
|
#ifdef ENABLE_TRAY
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
#include "swaybar/tray/sni_watcher.h"
|
#include "swaybar/tray/sni_watcher.h"
|
||||||
|
@ -31,16 +32,30 @@ static void bar_init(struct bar *bar) {
|
||||||
|
|
||||||
static void spawn_status_cmd_proc(struct bar *bar) {
|
static void spawn_status_cmd_proc(struct bar *bar) {
|
||||||
if (bar->config->status_command) {
|
if (bar->config->status_command) {
|
||||||
int pipefd[2];
|
int pipe_read_fd[2];
|
||||||
if (pipe(pipefd) != 0) {
|
int pipe_write_fd[2];
|
||||||
sway_log(L_ERROR, "Unable to create pipe for status_command fork");
|
|
||||||
|
if (pipe(pipe_read_fd) != 0) {
|
||||||
|
sway_log(L_ERROR, "Unable to create pipes for status_command fork");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (pipe(pipe_write_fd) != 0) {
|
||||||
|
sway_log(L_ERROR, "Unable to create pipe for status_command fork (write)");
|
||||||
|
close(pipe_read_fd[0]);
|
||||||
|
close(pipe_read_fd[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bar->status_command_pid = fork();
|
bar->status_command_pid = fork();
|
||||||
if (bar->status_command_pid == 0) {
|
if (bar->status_command_pid == 0) {
|
||||||
close(pipefd[0]);
|
close(pipe_read_fd[0]);
|
||||||
dup2(pipefd[1], STDOUT_FILENO);
|
dup2(pipe_read_fd[1], STDOUT_FILENO);
|
||||||
close(pipefd[1]);
|
close(pipe_read_fd[1]);
|
||||||
|
|
||||||
|
dup2(pipe_write_fd[0], STDIN_FILENO);
|
||||||
|
close(pipe_write_fd[0]);
|
||||||
|
close(pipe_write_fd[1]);
|
||||||
|
|
||||||
char *const cmd[] = {
|
char *const cmd[] = {
|
||||||
"sh",
|
"sh",
|
||||||
"-c",
|
"-c",
|
||||||
|
@ -51,9 +66,13 @@ static void spawn_status_cmd_proc(struct bar *bar) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(pipefd[1]);
|
close(pipe_read_fd[1]);
|
||||||
bar->status_read_fd = pipefd[0];
|
bar->status_read_fd = pipe_read_fd[0];
|
||||||
fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK);
|
fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
|
close(pipe_write_fd[0]);
|
||||||
|
bar->status_write_fd = pipe_write_fd[1];
|
||||||
|
fcntl(bar->status_write_fd, F_SETFL, O_NONBLOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +122,22 @@ static void mouse_button_notify(struct window *window, int x, int y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (button) {
|
||||||
|
case BTN_LEFT:
|
||||||
|
status_line_mouse_event(&swaybar, x, y, 1);
|
||||||
|
break;
|
||||||
|
case BTN_MIDDLE:
|
||||||
|
status_line_mouse_event(&swaybar, x, y, 2);
|
||||||
|
break;
|
||||||
|
case BTN_RIGHT:
|
||||||
|
status_line_mouse_event(&swaybar, x, y, 3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_TRAY
|
#ifdef ENABLE_TRAY
|
||||||
tray_mouse_event(clicked_output, x, y, button, state_w);
|
tray_mouse_event(clicked_output, x, y, button, state_w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) {
|
static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) {
|
||||||
|
@ -318,6 +350,10 @@ void bar_teardown(struct bar *bar) {
|
||||||
close(bar->status_read_fd);
|
close(bar->status_read_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bar->status_write_fd) {
|
||||||
|
close(bar->status_write_fd);
|
||||||
|
}
|
||||||
|
|
||||||
if (bar->ipc_socketfd) {
|
if (bar->ipc_socketfd) {
|
||||||
close(bar->ipc_socketfd);
|
close(bar->ipc_socketfd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,9 @@ static void render_block(struct window *window, struct config *config, struct st
|
||||||
|
|
||||||
double pos = *x;
|
double pos = *x;
|
||||||
|
|
||||||
|
block->x = (int)pos;
|
||||||
|
block->width = (int)block_width;
|
||||||
|
|
||||||
// render background
|
// render background
|
||||||
if (block->background != 0x0) {
|
if (block->background != 0x0) {
|
||||||
cairo_set_source_u32(window->cairo, block->background);
|
cairo_set_source_u32(window->cairo, block->background);
|
||||||
|
|
|
@ -27,6 +27,8 @@ struct {
|
||||||
static char line[1024];
|
static char line[1024];
|
||||||
static char line_rest[1024];
|
static char line_rest[1024];
|
||||||
|
|
||||||
|
static char event_buff[1024];
|
||||||
|
|
||||||
static void free_status_block(void *item) {
|
static void free_status_block(void *item) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
|
@ -391,6 +393,66 @@ static int i3json_handle_fd(struct bar *bar) {
|
||||||
return i3json_parse(bar);
|
return i3json_parse(bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool status_line_mouse_event(struct bar *bar, int x, int y, uint32_t button) {
|
||||||
|
sway_log(L_DEBUG, "status_line_mouse_event.");
|
||||||
|
if (!bar->status->click_events) {
|
||||||
|
sway_log(L_DEBUG, "click_events are not enabled.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar->status->protocol == I3BAR) {
|
||||||
|
sway_log(L_DEBUG, "Sending click event.");
|
||||||
|
|
||||||
|
// find clicked block
|
||||||
|
struct status_block *clicked_block = NULL;
|
||||||
|
struct status_block *current_block = NULL;
|
||||||
|
int num_blocks = bar->status->block_line->length;
|
||||||
|
|
||||||
|
if (num_blocks == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
current_block = bar->status->block_line->items[0];
|
||||||
|
if (x < current_block->x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_blocks; i++) {
|
||||||
|
current_block = bar->status->block_line->items[i];
|
||||||
|
if (x < (current_block->x + current_block->width)) {
|
||||||
|
clicked_block = current_block;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!clicked_block || !clicked_block->name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// event example {"name":"capture","instance":"label","button":1,"x":3431,"y":18}
|
||||||
|
|
||||||
|
struct json_object *event_json = json_object_new_object();
|
||||||
|
json_object_object_add(event_json, "name", json_object_new_string(clicked_block->name));
|
||||||
|
if (clicked_block->instance) {
|
||||||
|
json_object_object_add(event_json, "instance", json_object_new_string(clicked_block->instance));
|
||||||
|
}
|
||||||
|
json_object_object_add(event_json, "button", json_object_new_int(button));
|
||||||
|
json_object_object_add(event_json, "x", json_object_new_int(x));
|
||||||
|
json_object_object_add(event_json, "y", json_object_new_int(y));
|
||||||
|
|
||||||
|
int len = snprintf(event_buff, sizeof(event_buff), "%s,\n", json_object_to_json_string(event_json));
|
||||||
|
|
||||||
|
json_object_put(event_json);
|
||||||
|
|
||||||
|
if (len <= (int)sizeof(event_buff)) { // if not truncated
|
||||||
|
write(bar->status_write_fd, event_buff, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool handle_status_line(struct bar *bar) {
|
bool handle_status_line(struct bar *bar) {
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
|
||||||
|
@ -418,15 +480,29 @@ bool handle_status_line(struct bar *bar) {
|
||||||
if (line[0] == '{') {
|
if (line[0] == '{') {
|
||||||
// detect i3bar json protocol
|
// detect i3bar json protocol
|
||||||
json_object *proto = json_tokener_parse(line);
|
json_object *proto = json_tokener_parse(line);
|
||||||
json_object *version;
|
|
||||||
if (proto) {
|
if (proto) {
|
||||||
|
|
||||||
|
json_object *version;
|
||||||
if (json_object_object_get_ex(proto, "version", &version)
|
if (json_object_object_get_ex(proto, "version", &version)
|
||||||
&& json_object_get_int(version) == 1
|
&& json_object_get_int(version) == 1
|
||||||
) {
|
) {
|
||||||
sway_log(L_DEBUG, "Switched to i3bar protocol.");
|
sway_log(L_DEBUG, "Switched to i3bar protocol.");
|
||||||
bar->status->protocol = I3BAR;
|
bar->status->protocol = I3BAR;
|
||||||
i3json_handle_data(bar, line_rest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
json_object *click_events;
|
||||||
|
if (json_object_object_get_ex(proto, "click_events", &click_events)
|
||||||
|
&& json_object_get_boolean(click_events)) {
|
||||||
|
|
||||||
|
sway_log(L_DEBUG, "Enabling click events.");
|
||||||
|
bar->status->click_events = true;
|
||||||
|
|
||||||
|
const char *events_array = "[\n";
|
||||||
|
write(bar->status_write_fd, events_array, strlen(events_array));
|
||||||
|
}
|
||||||
|
|
||||||
|
i3json_handle_data(bar, line_rest);
|
||||||
|
|
||||||
json_object_put(proto);
|
json_object_put(proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,6 +517,7 @@ struct status_line *init_status_line() {
|
||||||
line->block_line = create_list();
|
line->block_line = create_list();
|
||||||
line->text_line = NULL;
|
line->text_line = NULL;
|
||||||
line->protocol = UNDEF;
|
line->protocol = UNDEF;
|
||||||
|
line->click_events = false;
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <json-c/json.h>
|
#include <json-c/json.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "ipc-client.h"
|
#include "ipc-client.h"
|
||||||
|
@ -47,17 +48,27 @@ void grab_and_apply_magick(const char *file, const char *payload,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *fmt = "convert -depth 8 -size %dx%d+0 rgba:- -flip %s";
|
char size[10 + 1 + 10 + 2 + 1]; // int32_t are max 10 digits
|
||||||
char *cmd = malloc(strlen(fmt) - 6 /*args*/
|
sprintf(size, "%dx%d+0", width, height);
|
||||||
+ numlen(width) + numlen(height) + strlen(file) + 1);
|
|
||||||
sprintf(cmd, fmt, width, height, file);
|
|
||||||
|
|
||||||
FILE *f = popen(cmd, "w");
|
pid_t child;
|
||||||
fwrite(pixels, 1, len, f);
|
int fd[2];
|
||||||
fflush(f);
|
pipe(fd);
|
||||||
fclose(f);
|
|
||||||
free(pixels - 9);
|
if ((child = fork()) < 0) {
|
||||||
free(cmd);
|
sway_log(L_ERROR, "Swaygrab failed to fork.");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else if (child == 0) {
|
||||||
|
close(fd[1]);
|
||||||
|
write(fd[0], pixels, len);
|
||||||
|
free(pixels - 9);
|
||||||
|
waitpid(child, NULL, 0);
|
||||||
|
} else {
|
||||||
|
close(fd[0]);
|
||||||
|
execlp("convert", "-depth", "8", "-size", size, "rgba:-", "-flip", file, NULL);
|
||||||
|
sway_log(L_ERROR, "Swaygrab could not run convert.");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void grab_and_apply_movie_magic(const char *file, const char *payload,
|
void grab_and_apply_movie_magic(const char *file, const char *payload,
|
||||||
|
|
Loading…
Reference in a new issue