Skip to content

Commit

Permalink
Add support for multiple actions
Browse files Browse the repository at this point in the history
Allows to bind more than one action to the keyboard or mouse event.

Resolves #137.

Signed-off-by: Artem Senichev <artemsen@gmail.com>
  • Loading branch information
artemsen committed Jun 12, 2024
1 parent df7d9fc commit 5dc13e4
Show file tree
Hide file tree
Showing 10 changed files with 509 additions and 322 deletions.
5 changes: 3 additions & 2 deletions extra/swayimgrc.5
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ Set display scheme for the \fIfull\fR mode, top left corner of the window.
.\" ****************************************************************************
.SS "Key bindings"
The key bindings are described in the \fB[keys]\fR section.
Each line associates a key with some action and optional parameters.
Each line associates a key with a list of actions and optional parameters.
Actions are separated by semicolons.
The key name can be obtained with the \fIxkbcli\fR tool:
`xkbcli interactive-wayland`.
One or more key modifiers (\fICtrl\fR, \fIAlt\fR, \fIShift\fR) can be specified
Expand Down Expand Up @@ -239,7 +240,7 @@ order = random
[font]
size = 16
[keys]
Delete = exec rm "%"
Delete = exec rm "%"; reload
Ctrl+Alt+e = exec echo "%" > mylist.txt
.EE
.PP
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ endif

# source files
sources = [
'src/action.c',
'src/config.c',
'src/font.c',
'src/image.c',
Expand Down
123 changes: 123 additions & 0 deletions src/action.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: MIT
// Actions: set of predefined commands to execute.
// Copyright (C) 2024 Artem Senichev <artemsen@gmail.com>

#include "action.h"

#include "str.h"

#include <ctype.h>
#include <stdlib.h>

/** Action names. */
static const char* action_names[] = {
[action_none] = "none",
[action_help] = "help",
[action_first_file] = "first_file",
[action_last_file] = "last_file",
[action_prev_dir] = "prev_dir",
[action_next_dir] = "next_dir",
[action_prev_file] = "prev_file",
[action_next_file] = "next_file",
[action_skip_file] = "skip_file",
[action_prev_frame] = "prev_frame",
[action_next_frame] = "next_frame",
[action_animation] = "animation",
[action_slideshow] = "slideshow",
[action_fullscreen] = "fullscreen",
[action_step_left] = "step_left",
[action_step_right] = "step_right",
[action_step_up] = "step_up",
[action_step_down] = "step_down",
[action_zoom] = "zoom",
[action_rotate_left] = "rotate_left",
[action_rotate_right] = "rotate_right",
[action_flip_vertical] = "flip_vertical",
[action_flip_horizontal] = "flip_horizontal",
[action_reload] = "reload",
[action_antialiasing] = "antialiasing",
[action_info] = "info",
[action_exec] = "exec",
[action_exit] = "exit",
};

bool action_load(struct action* action, const char* source, size_t len)
{
ssize_t action_type;
const char* action_name;
size_t action_len;
const char* params;
size_t params_len;
size_t pos = 0;

// skip spaces
while (pos < len && isspace(source[pos])) {
++pos;
}

action_name = &source[pos];

// get action type
action_len = pos;
while (pos < len && !isspace(source[pos])) {
++pos;
}
action_len = pos - action_len;
action_type = str_index(action_names, action_name, action_len);
if (action_type < 0) {
return false;
}
action->type = action_type;

// skip spaces
while (pos < len && isspace(source[pos])) {
++pos;
}

// rest part: parameters
params = &source[pos];
params_len = len - pos;
if (params_len) {
action->params = str_append(params, params_len, NULL);
if (!action->params) {
return false;
}
} else {
action->params = NULL;
}

return true;
}

void action_free(struct action* action)
{
if (action) {
free(action->params);
action->params = NULL;
}
}

bool action_dup(const struct action* src, struct action* dst)
{
if (!src->params) {
dst->params = NULL;
} else {
char* buf = str_dup(src->params, NULL);
if (!buf) {
return false;
}
dst->params = buf;
}

dst->type = src->type;

return true;
}

const char* action_typename(const struct action* action)
{
if (action->type < ARRAY_SIZE(action_names)) {
return action_names[action->type];
}
return NULL;
}
76 changes: 76 additions & 0 deletions src/action.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: MIT
// Actions: set of predefined commands to execute.
// Copyright (C) 2024 Artem Senichev <artemsen@gmail.com>

#pragma once

#include <stdbool.h>
#include <stddef.h>

/** Supported actions. */
enum action_type {
action_none,
action_help,
action_first_file,
action_last_file,
action_prev_dir,
action_next_dir,
action_prev_file,
action_next_file,
action_skip_file,
action_prev_frame,
action_next_frame,
action_animation,
action_slideshow,
action_fullscreen,
action_step_left,
action_step_right,
action_step_up,
action_step_down,
action_zoom,
action_rotate_left,
action_rotate_right,
action_flip_vertical,
action_flip_horizontal,
action_reload,
action_antialiasing,
action_info,
action_exec,
action_exit,
};

/** Action instance. */
struct action {
enum action_type type; ///< Action type
char* params; ///< Custom parameters for the action
};

/**
* Load action from config string.
* @param action target instance, caller should free resources
* @param source action command with parameters as text string
* @param len length of the source string
* @return true if action loaded
*/
bool action_load(struct action* action, const char* source, size_t len);

/**
* Free action instance.
* @param action to release
*/
void action_free(struct action* action);

/**
* Duplicate action.
* @param src source action
* @param dst destination buffer
* @return true if action duplicated
*/
bool action_dup(const struct action* src, struct action* dst);

/**
* Get action's type name.
* @param action to get type
* @return type name
*/
const char* action_typename(const struct action* action);
2 changes: 1 addition & 1 deletion src/imagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ static void on_notify(void)
pos += sizeof(struct inotify_event) + event->len;
}
if (updated) {
viewer_reset();
viewer_reload();
}
}
}
Expand Down
Loading

0 comments on commit 5dc13e4

Please sign in to comment.