file-browser: Add 'Delete' to context menu
This commit is contained in:
parent
89325bb409
commit
74b6dcc8e3
@ -1445,6 +1445,44 @@ static void _menu_action_paste(struct MenuEntry * entry) {
|
|||||||
yutani_special_request(yctx, NULL, YUTANI_SPECIAL_REQUEST_CLIPBOARD);
|
yutani_special_request(yctx, NULL, YUTANI_SPECIAL_REQUEST_CLIPBOARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _menu_action_delete(struct MenuEntry * entry) {
|
||||||
|
size_t filesToDelete = 0;
|
||||||
|
for (int i = 0; i < file_pointers_len; ++i) {
|
||||||
|
if (file_pointers[i]->selected) filesToDelete++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base_is_root = !strcmp(current_directory, "/"); /* avoid redundant slash */
|
||||||
|
char ** args = malloc(sizeof(char*) * (filesToDelete + 3));
|
||||||
|
args[0] = "/bin/prompt_and_delete.krk";
|
||||||
|
args[1] = malloc(100);
|
||||||
|
snprintf(args[1],100,"%d",getpid());
|
||||||
|
size_t counter = 2;
|
||||||
|
for (int i = 0; i < file_pointers_len; ++i) {
|
||||||
|
if (file_pointers[i]->selected) {
|
||||||
|
const char * name = file_pointers[i]->type == 2 ? file_pointers[i]->filename : file_pointers[i]->name;
|
||||||
|
size_t len = strlen(current_directory) + !base_is_root + strlen(name) + 1;
|
||||||
|
args[counter] = malloc(len);
|
||||||
|
snprintf(args[counter], len, "%s%s%s", current_directory, base_is_root ? "" : "/", name);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args[counter] = NULL;
|
||||||
|
|
||||||
|
pid_t child = fork();
|
||||||
|
|
||||||
|
if (!child) {
|
||||||
|
execv(args[0], args);
|
||||||
|
exit(1);
|
||||||
|
} else if (child < 0) {
|
||||||
|
fprintf(stderr, "Error forking.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 1; i < counter; ++i) {
|
||||||
|
free(args[i]);
|
||||||
|
}
|
||||||
|
free(args);
|
||||||
|
}
|
||||||
|
|
||||||
/* Help > About File Browser */
|
/* Help > About File Browser */
|
||||||
static void _menu_action_about(struct MenuEntry * entry) {
|
static void _menu_action_about(struct MenuEntry * entry) {
|
||||||
/* Show About dialog */
|
/* Show About dialog */
|
||||||
@ -1787,14 +1825,14 @@ static void _scroll_down(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int signalResponse = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Desktop mode responsds to sig_usr2 by returning to
|
* Desktop mode responsds to sig_usr2 by returning to
|
||||||
* the bottom of the Z-order stack.
|
* the bottom of the Z-order stack.
|
||||||
*/
|
*/
|
||||||
static void sig_usr2(int sig) {
|
static void sig_usr2(int sig) {
|
||||||
yutani_set_stack(yctx, main_window, YUTANI_ZORDER_BOTTOM);
|
signalResponse |= 1;
|
||||||
_menu_action_refresh(NULL);
|
|
||||||
signal(SIGUSR2, sig_usr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1802,8 +1840,11 @@ static void sig_usr2(int sig) {
|
|||||||
* to the current display size.
|
* to the current display size.
|
||||||
*/
|
*/
|
||||||
static void sig_usr1(int sig) {
|
static void sig_usr1(int sig) {
|
||||||
yutani_window_resize_offer(yctx, main_window, yctx->display_width, yctx->display_height);
|
signalResponse |= 2;
|
||||||
signal(SIGUSR1, sig_usr1);
|
}
|
||||||
|
|
||||||
|
static void sig_urg(int sig) {
|
||||||
|
signalResponse |= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1893,6 +1934,14 @@ static void show_context_menu(struct yutani_msg_window_mouse_event * me) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_signal_handler(int signum, void (*handler)(int)) {
|
||||||
|
struct sigaction action;
|
||||||
|
action.sa_handler = handler;
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_flags = 0; /* do not restart syscalls, do not reset handler */
|
||||||
|
sigaction(signum, &action, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
|
|
||||||
yctx = yutani_init();
|
yctx = yutani_init();
|
||||||
@ -1907,8 +1956,8 @@ int main(int argc, char * argv[]) {
|
|||||||
is_desktop_background = 1;
|
is_desktop_background = 1;
|
||||||
menu_bar_height = 0;
|
menu_bar_height = 0;
|
||||||
nav_bar_height = 0;
|
nav_bar_height = 0;
|
||||||
signal(SIGUSR1, sig_usr1);
|
set_signal_handler(SIGUSR1, sig_usr1);
|
||||||
signal(SIGUSR2, sig_usr2);
|
set_signal_handler(SIGUSR2, sig_usr2);
|
||||||
draw_background(yctx->display_width, yctx->display_height);
|
draw_background(yctx->display_width, yctx->display_height);
|
||||||
main_window = yutani_window_create_flags(yctx, yctx->display_width, yctx->display_height, YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS);
|
main_window = yutani_window_create_flags(yctx, yctx->display_width, yctx->display_height, YUTANI_WINDOW_FLAG_NO_STEAL_FOCUS);
|
||||||
yutani_window_move(yctx, main_window, 0, 0);
|
yutani_window_move(yctx, main_window, 0, 0);
|
||||||
@ -1930,6 +1979,8 @@ int main(int argc, char * argv[]) {
|
|||||||
set_view_mode(VIEW_MODE_TILES);
|
set_view_mode(VIEW_MODE_TILES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_signal_handler(SIGURG, sig_urg);
|
||||||
|
|
||||||
if (arg_ind < argc) {
|
if (arg_ind < argc) {
|
||||||
chdir(argv[arg_ind]);
|
chdir(argv[arg_ind]);
|
||||||
}
|
}
|
||||||
@ -1990,7 +2041,9 @@ int main(int argc, char * argv[]) {
|
|||||||
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Copy",_menu_action_copy));
|
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Copy",_menu_action_copy));
|
||||||
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Paste",_menu_action_paste));
|
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Paste",_menu_action_paste));
|
||||||
menu_insert(context_menu, menu_create_separator());
|
menu_insert(context_menu, menu_create_separator());
|
||||||
|
menu_insert(context_menu, menu_create_normal(NULL,NULL,"Delete",_menu_action_delete));
|
||||||
if (!is_desktop_background) {
|
if (!is_desktop_background) {
|
||||||
|
menu_insert(context_menu, menu_create_separator());
|
||||||
menu_insert(context_menu, menu_create_normal("up",NULL,"Up",_menu_action_up));
|
menu_insert(context_menu, menu_create_normal("up",NULL,"Up",_menu_action_up));
|
||||||
}
|
}
|
||||||
menu_insert(context_menu, menu_create_normal("refresh",NULL,"Refresh",_menu_action_refresh));
|
menu_insert(context_menu, menu_create_normal("refresh",NULL,"Refresh",_menu_action_refresh));
|
||||||
@ -2024,6 +2077,19 @@ int main(int argc, char * argv[]) {
|
|||||||
int fds[1] = {fileno(yctx->sock)};
|
int fds[1] = {fileno(yctx->sock)};
|
||||||
int index = fswait2(1,fds,wallpaper_old ? 10 : 200);
|
int index = fswait2(1,fds,wallpaper_old ? 10 : 200);
|
||||||
|
|
||||||
|
if (index < 0 && signalResponse) {
|
||||||
|
if (signalResponse & 1) {
|
||||||
|
yutani_set_stack(yctx, main_window, YUTANI_ZORDER_BOTTOM);
|
||||||
|
_menu_action_refresh(NULL);
|
||||||
|
} else if (signalResponse & 2) {
|
||||||
|
yutani_window_resize_offer(yctx, main_window, yctx->display_width, yctx->display_height);
|
||||||
|
} else if (signalResponse & 4) {
|
||||||
|
_menu_action_refresh(NULL);
|
||||||
|
}
|
||||||
|
signalResponse = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
maybe_blink_cursor();
|
maybe_blink_cursor();
|
||||||
|
|
||||||
if (index == 1) {
|
if (index == 1) {
|
||||||
|
38
apps/prompt_and_delete.krk
Executable file
38
apps/prompt_and_delete.krk
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/kuroko
|
||||||
|
import kuroko
|
||||||
|
import os
|
||||||
|
import _waitpid
|
||||||
|
let count = len(kuroko.argv)
|
||||||
|
|
||||||
|
if count < 3:
|
||||||
|
print("expected at least two arguments")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
let callbackPid = int(kuroko.argv[1])
|
||||||
|
if callbackPid < 1:
|
||||||
|
print("suspicious callback pid:", callbackPid)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
count -= 2
|
||||||
|
|
||||||
|
def show_dialog(msg,title="File Browser",icon="/usr/share/icons/48/folder.png"):
|
||||||
|
let pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
os.execvp('showdialog',['showdialog',title,icon,msg])
|
||||||
|
os.exit(1)
|
||||||
|
while True:
|
||||||
|
let result = _waitpid.waitpid(pid)
|
||||||
|
if result[0] != pid:
|
||||||
|
continue
|
||||||
|
return result[1] == 0
|
||||||
|
|
||||||
|
if show_dialog(f'This will permanently delete {count} file{"s" if count != 1 else ""}.'):
|
||||||
|
for file in kuroko.argv[2:]:
|
||||||
|
try:
|
||||||
|
os.remove(file)
|
||||||
|
except Exception as e:
|
||||||
|
if not show_dialog(f'An error occured while trying to delete "{file}":\n{e.arg}'):
|
||||||
|
break
|
||||||
|
os.kill(callbackPid, 21) # SIGURG
|
||||||
|
else:
|
||||||
|
return 1
|
Loading…
Reference in New Issue
Block a user