diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..527a0dfe --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,145 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..105ce2da --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..450fc790 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..a6bbb61e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/swaylock-effects.iml b/.idea/swaylock-effects.iml new file mode 100644 index 00000000..d0876a78 --- /dev/null +++ b/.idea/swaylock-effects.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/swaylock-effects2.iml b/.idea/swaylock-effects2.iml new file mode 100644 index 00000000..4c942354 --- /dev/null +++ b/.idea/swaylock-effects2.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..5d36ab40 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "ext-session-lock-v1-client-protocol.h": "c" + } +} \ No newline at end of file diff --git a/README.md b/README.md index a3758e42..3aab8cd1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ -# swaylock-effects +# swaylock-effects-script + +Swaylock-effects-script is a fork of [swaylock-effects](https://github.com/jirutka/swaylock-effects) +which adds a script output display feature. Swaylock-effects is a fork of [swaylock](https://github.com/swaywm/swaylock) which adds built-in screenshots and image manipulation effects like blurring. It's inspired by [i3lock-color](https://github.com/PandorasFox/i3lock-color), although the feature sets aren't perfectly overlapping. -This repository ([jirutka/swaylock-effects](https://github.com/jirutka/swaylock-effects)) +This repository ([sidharthmrao/swaylock-effects-script](https://github.com/sidharthmrao/swaylock-effects-script)) +is a fork of ([jirutka/swaylock-effects](https://github.com/jirutka/swaylock-effects)) which is a fork of [mortie/swaylock-effects](https://github.com/mortie/swaylock-effects) which is no longer maintained. @@ -15,6 +19,7 @@ which is no longer maintained. swaylock \ --screenshots \ + --script `path_to_script` \ --clock \ --indicator \ --indicator-radius 100 \ @@ -33,6 +38,7 @@ which is no longer maintained. The main new features compared to upstream swaylock are: +* `--script` to display the script output * `--screenshots` to use screenshots instead of an image on disk or a color * `--clock` to show date/time in the indicator * Use `--indicator` to make the indicator always active @@ -130,6 +136,10 @@ Run these commands: ninja -C build sudo ninja -C build install +On systems with PAM, copy pam/swaylock to /etc/pam.d/swaylock + + sudo cp pam/swaylock /etc/pam.d/swaylock + On systems without PAM, you need to suid the swaylock binary: sudo chmod a+s /usr/local/bin/swaylock diff --git a/include/swaylock.h b/include/swaylock.h index daa6f754..1a0e399d 100644 --- a/include/swaylock.h +++ b/include/swaylock.h @@ -82,6 +82,10 @@ struct swaylock_args { bool password_grace_no_mouse; bool password_grace_no_touch; + bool display_script; + char *script_str; + char *script_path; + char *text_cleared; char *text_caps_lock; char *text_verifying; diff --git a/main.c b/main.c index 9e055176..a6f19969 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,37 @@ #include "wlr-screencopy-unstable-v1-client-protocol.h" #include "ext-session-lock-v1-client-protocol.h" +#define MAX_OUTPUT_SIZE 1024 + +static struct swaylock_state state; + +void update_script() { + FILE *pipe; + char path[1035]; + char output[MAX_OUTPUT_SIZE]; + char *script_str = (char *)malloc((MAX_OUTPUT_SIZE + 1) * sizeof(char)); + + pipe = popen(state.args.script_path, "r"); + + if (pipe == NULL) { + fprintf(stderr, "Failed to run script.\n"); + return; + } + + memset(output, 0, sizeof(output)); + + while (fgets(path, sizeof(path), pipe) != NULL) { + path[strcspn(path, "\r\n")] = '\0'; + strcat(output, path); + } + + pclose(pipe); + + snprintf(script_str, MAX_OUTPUT_SIZE, "%s", output); + + state.args.script_str = script_str; +} + // returns a positive integer in milliseconds static uint32_t parse_seconds(const char *seconds) { char *endptr; @@ -397,6 +428,11 @@ static const struct wl_callback_listener surface_frame_listener; static void surface_frame_handle_done(void *data, struct wl_callback *callback, uint32_t time) { + + if (state.args.display_script) { + update_script(); + }; + struct swaylock_surface *surface = data; wl_callback_destroy(callback); @@ -975,6 +1011,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state, LO_TIME_EFFECTS, LO_INDICATOR, LO_CLOCK, + LO_SCRIPT, LO_TIMESTR, LO_DATESTR, LO_FADE_IN, @@ -1055,6 +1092,7 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state, {"time-effects", no_argument, NULL, LO_TIME_EFFECTS}, {"indicator", no_argument, NULL, LO_INDICATOR}, {"clock", no_argument, NULL, LO_CLOCK}, + {"script", required_argument, NULL, LO_SCRIPT}, {"timestr", required_argument, NULL, LO_TIMESTR}, {"datestr", required_argument, NULL, LO_DATESTR}, {"fade-in", required_argument, NULL, LO_FADE_IN}, @@ -1114,6 +1152,8 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state, "Disable the unlock indicator.\n" " --indicator " "Always show the indicator.\n" + " --script " + "Show the script output.\n" " --clock " "Show time and date.\n" " --timestr " @@ -1619,6 +1659,13 @@ static int parse_options(int argc, char **argv, struct swaylock_state *state, state->args.clock = true; } break; + case LO_SCRIPT: + if (state) { + state->args.script_path = strdup(optarg); + state->args.display_script = true; + } + update_script(); + break; case LO_TIMESTR: if (state) { free(state->args.timestr); @@ -1741,8 +1788,6 @@ static int load_config(char *path, struct swaylock_state *state, return 0; } -static struct swaylock_state state; - static void display_in(int fd, short mask, void *data) { if (wl_display_dispatch(state.display) == -1) { state.run_display = false; @@ -1823,8 +1868,8 @@ int main(int argc, char **argv) { .mode = BACKGROUND_MODE_FILL, .font = strdup("sans-serif"), .font_size = 0, - .radius = 75, - .thickness = 10, + .radius = 100, + .thickness = 9, .indicator_x_position = 0, .indicator_y_position = 0, .override_indicator_x_position = false, @@ -1848,6 +1893,10 @@ int main(int argc, char **argv) { .allow_fade = true, .password_grace_period = 0, + .display_script = false, + .script_str = NULL, + .script_path = NULL, + .text_cleared = strdup("Cleared"), .text_caps_lock = strdup("Caps Lock"), .text_verifying = strdup("Verifying"), diff --git a/render.c b/render.c index f92b3c1f..19711236 100644 --- a/render.c +++ b/render.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include "cairo.h" #include "background-image.h" @@ -40,9 +42,10 @@ static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, } } -static void timetext(struct swaylock_surface *surface, char **tstr, char **dstr) { +static void subtext(struct swaylock_surface *surface, char **tstr, char **dstr, char **bstr) { static char dbuf[256]; static char tbuf[256]; + static char bbuf[256]; // Use user's locale for strftime calls char *prevloc = setlocale(LC_TIME, NULL); @@ -51,20 +54,28 @@ static void timetext(struct swaylock_surface *surface, char **tstr, char **dstr) time_t t = time(NULL); struct tm *tm = localtime(&t); - if (surface->state->args.timestr[0]) { + if (surface->state->args.clock && surface->state->args.timestr[0]) { strftime(tbuf, sizeof(tbuf), surface->state->args.timestr, tm); *tstr = tbuf; } else { *tstr = NULL; } - if (surface->state->args.datestr[0]) { + if (surface->state->args.clock && surface->state->args.datestr[0]) { strftime(dbuf, sizeof(dbuf), surface->state->args.datestr, tm); *dstr = dbuf; } else { *dstr = NULL; } + if (surface->state->args.display_script) { + // Write script output + snprintf(bbuf, sizeof(bbuf), "%s", surface->state->args.script_str); + *bstr = bbuf; + } else { + *bstr = NULL; + } + // Set it back, so we don't break stuff setlocale(LC_TIME, prevloc); } @@ -252,6 +263,7 @@ void render_frame(struct swaylock_surface *surface) { char *text = NULL; char *text_l1 = NULL; char *text_l2 = NULL; + char *text_l3 = NULL; const char *layout_text = NULL; double font_size; char attempts[4]; // like i3lock: count no more than 999 @@ -288,8 +300,8 @@ void render_frame(struct swaylock_surface *surface) { snprintf(attempts, sizeof(attempts), "%d", state->failed_attempts); text = attempts; } - } else if (state->args.clock) { - timetext(surface, &text_l1, &text_l2); + } else if (state->args.clock || state->args.display_script) { + subtext(surface, &text_l1, &text_l2, &text_l3); } xkb_layout_index_t num_layout = xkb_keymap_num_layouts(state->xkb.keymap); @@ -308,15 +320,25 @@ void render_frame(struct swaylock_surface *surface) { } break; default: - if (state->args.clock) - timetext(surface, &text_l1, &text_l2); + if (state->args.clock || state->args.display_script) + subtext(surface, &text_l1, &text_l2, &text_l3); break; } - if (text_l1 && !text_l2) + if (text_l1 && !text_l2 && !text_l3) { text = text_l1; - if (text_l2 && !text_l1) + } + if (text_l2 && !text_l1 && !text_l3) { text = text_l2; + } + if (text_l3 && !text_l1 && !text_l2) { + text = text_l3; + } + + if (text_l1 && text_l3 && !text_l2) { + text_l2 = text_l3; + text_l3 = NULL; + } if (text) { cairo_text_extents_t extents; @@ -344,6 +366,7 @@ void render_frame(struct swaylock_surface *surface) { /* Top */ + cairo_set_font_size(cairo, arc_radius / 3.0f); cairo_text_extents(cairo, text_l1, &extents_l1); cairo_font_extents(cairo, &fe_l1); x_l1 = (buffer_width / 2) - @@ -358,13 +381,13 @@ void render_frame(struct swaylock_surface *surface) { /* Bottom */ - cairo_set_font_size(cairo, arc_radius / 6.0f); + cairo_set_font_size(cairo, arc_radius / 5.5f); cairo_text_extents(cairo, text_l2, &extents_l2); cairo_font_extents(cairo, &fe_l2); x_l2 = (buffer_width / 2) - (extents_l2.width / 2 + extents_l2.x_bearing); y_l2 = (buffer_diameter / 2) + - (fe_l2.height / 2 - fe_l2.descent) + arc_radius / 3.5f; + (fe_l2.height / 2 - fe_l2.descent) + arc_radius / 4.0f; cairo_move_to(cairo, x_l2, y_l2); cairo_show_text(cairo, text_l2); @@ -378,6 +401,30 @@ void render_frame(struct swaylock_surface *surface) { cairo_set_font_size(cairo, font_size); + + if (text_l3) { + cairo_text_extents_t extents_l3; + cairo_font_extents_t fe_l3; + double x_l3, y_l3; + + /* Even more Bottom */ + + cairo_set_font_size(cairo, arc_radius / 5.0f); + cairo_text_extents(cairo, text_l3, &extents_l3); + cairo_font_extents(cairo, &fe_l3); + x_l3 = (buffer_width / 2) - + (extents_l3.width / 2 + extents_l3.x_bearing); + y_l3 = (buffer_diameter / 2) + + (fe_l3.height / 2 - fe_l3.descent) + arc_radius / 1.9f; + + cairo_move_to(cairo, x_l3, y_l3); + cairo_show_text(cairo, text_l3); + cairo_close_path(cairo); + cairo_new_sub_path(cairo); + + if (new_width < extents_l3.width) + new_width = extents_l3.width; + } } // Typing indicator: Highlight random part on keypress diff --git a/scripts/battery_script.sh b/scripts/battery_script.sh new file mode 100755 index 00000000..d080b74c --- /dev/null +++ b/scripts/battery_script.sh @@ -0,0 +1 @@ +echo $(cat /sys/class/power_supply/BAT0/capacity)% \ No newline at end of file