[DMenu] Fix 'loading' overlay.

This commit is contained in:
Dave Davenport 2022-06-29 16:09:26 +02:00
parent 670a2445f4
commit c6456d2c1b

View file

@ -107,6 +107,7 @@ typedef struct {
int pipefd[2]; int pipefd[2];
int pipefd2[2]; int pipefd2[2];
guint wake_source; guint wake_source;
gboolean loading;
} DmenuModePrivateData; } DmenuModePrivateData;
#define BLOCK_LINES_SIZE 2048 #define BLOCK_LINES_SIZE 2048
@ -193,25 +194,31 @@ static gboolean dmenu_async_read_proc(gint fd, GIOCondition condition,
char command; char command;
// Read the entry from the pipe that was used to signal this action. // Read the entry from the pipe that was used to signal this action.
if (read(fd, &command, 1) == 1) { if (read(fd, &command, 1) == 1) {
Block *block = NULL; if ( command == 'r' ){
gboolean changed = FALSE; Block *block = NULL;
// Empty out the AsyncQueue (that is thread safe) from all blocks pushed gboolean changed = FALSE;
// into it. // Empty out the AsyncQueue (that is thread safe) from all blocks pushed
while ((block = g_async_queue_try_pop(pd->async_queue)) != NULL) { // into it.
while ((block = g_async_queue_try_pop(pd->async_queue)) != NULL) {
if (pd->cmd_list_real_length < (pd->cmd_list_length + block->length)) { if (pd->cmd_list_real_length < (pd->cmd_list_length + block->length)) {
pd->cmd_list_real_length = MAX(pd->cmd_list_real_length * 2, 4096); pd->cmd_list_real_length = MAX(pd->cmd_list_real_length * 2, 4096);
pd->cmd_list = g_realloc(pd->cmd_list, sizeof(DmenuScriptEntry) * pd->cmd_list = g_realloc(pd->cmd_list, sizeof(DmenuScriptEntry) *
pd->cmd_list_real_length); pd->cmd_list_real_length);
}
memcpy(&(pd->cmd_list[pd->cmd_list_length]), &(block->values[0]),
sizeof(DmenuScriptEntry) * block->length);
pd->cmd_list_length += block->length;
g_free(block);
changed = TRUE;
}
if (changed) {
rofi_view_reload();
}
} else if ( command == 'q' ){
if ( pd->loading ) {
rofi_view_set_overlay(rofi_view_get_active(), NULL);
} }
memcpy(&(pd->cmd_list[pd->cmd_list_length]), &(block->values[0]),
sizeof(DmenuScriptEntry) * block->length);
pd->cmd_list_length += block->length;
g_free(block);
changed = TRUE;
}
if (changed) {
rofi_view_reload();
} }
} }
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
@ -315,6 +322,7 @@ static gpointer read_input_thread(gpointer userdata) {
} }
} }
free(line); free(line);
write(pd->pipefd2[1], "q", 1);
return NULL; return NULL;
} }
@ -549,6 +557,7 @@ static int dmenu_mode_init(Mode *sw) {
g_unix_fd_add(pd->pipefd2[0], G_IO_IN, dmenu_async_read_proc, pd); g_unix_fd_add(pd->pipefd2[0], G_IO_IN, dmenu_async_read_proc, pd);
pd->reading_thread = pd->reading_thread =
g_thread_new("dmenu-read", (GThreadFunc)read_input_thread, pd); g_thread_new("dmenu-read", (GThreadFunc)read_input_thread, pd);
pd->loading = TRUE;
} else { } else {
pd->fd_file = stdin; pd->fd_file = stdin;
str = NULL; str = NULL;
@ -641,7 +650,34 @@ static cairo_surface_t *dmenu_get_icon(const Mode *sw,
return rofi_icon_fetcher_get(uid); return rofi_icon_fetcher_get(uid);
} }
static void dmenu_finish(RofiViewState *state, int retv) { static void dmenu_finish(DmenuModePrivateData *pd, RofiViewState *state, int retv) {
if (pd->reading_thread) {
// Stop listinig to new messages from reading thread.
if (pd->wake_source > 0) {
g_source_remove(pd->wake_source);
}
// signal stop.
write(pd->pipefd[1], "q", 1);
g_thread_join(pd->reading_thread);
pd->reading_thread = NULL;
/* empty the queue, remove idle callbacks if still pending. */
g_async_queue_lock(pd->async_queue);
Block *block = NULL;
while ((block = g_async_queue_try_pop_unlocked(pd->async_queue)) != NULL) {
g_free(block);
}
g_async_queue_unlock(pd->async_queue);
g_async_queue_unref(pd->async_queue);
pd->async_queue = NULL;
close(pd->pipefd[0]);
close(pd->pipefd[1]);
}
if (pd->fd_file != NULL) {
if (pd->fd_file != stdin) {
fclose(pd->fd_file);
}
}
if (retv == FALSE) { if (retv == FALSE) {
rofi_set_return_code(EXIT_FAILURE); rofi_set_return_code(EXIT_FAILURE);
} else if (retv >= 10) { } else if (retv >= 10) {
@ -681,32 +717,6 @@ static void dmenu_finalize(RofiViewState *state) {
DmenuModePrivateData *pd = DmenuModePrivateData *pd =
(DmenuModePrivateData *)rofi_view_get_mode(state)->private_data; (DmenuModePrivateData *)rofi_view_get_mode(state)->private_data;
if (pd->reading_thread) {
// Stop listinig to new messages from reading thread.
if (pd->wake_source > 0) {
g_source_remove(pd->wake_source);
}
// signal stop.
write(pd->pipefd[1], "q", 1);
g_thread_join(pd->reading_thread);
pd->reading_thread = NULL;
/* empty the queue, remove idle callbacks if still pending. */
g_async_queue_lock(pd->async_queue);
Block *block = NULL;
while ((block = g_async_queue_try_pop_unlocked(pd->async_queue)) != NULL) {
g_free(block);
}
g_async_queue_unlock(pd->async_queue);
g_async_queue_unref(pd->async_queue);
pd->async_queue = NULL;
close(pd->pipefd[0]);
close(pd->pipefd[1]);
}
if (pd->fd_file != NULL) {
if (pd->fd_file != stdin) {
fclose(pd->fd_file);
}
}
unsigned int cmd_list_length = pd->cmd_list_length; unsigned int cmd_list_length = pd->cmd_list_length;
DmenuScriptEntry *cmd_list = pd->cmd_list; DmenuScriptEntry *cmd_list = pd->cmd_list;
@ -729,6 +739,7 @@ static void dmenu_finalize(RofiViewState *state) {
} else if (pd->selected_line != UINT32_MAX) { } else if (pd->selected_line != UINT32_MAX) {
if ((mretv & MENU_CUSTOM_ACTION) && pd->multi_select) { if ((mretv & MENU_CUSTOM_ACTION) && pd->multi_select) {
restart = TRUE; restart = TRUE;
pd->loading = FALSE;
if (pd->selected_list == NULL) { if (pd->selected_list == NULL) {
pd->selected_list = pd->selected_list =
g_malloc0(sizeof(uint32_t) * (pd->cmd_list_length / 32 + 1)); g_malloc0(sizeof(uint32_t) * (pd->cmd_list_length / 32 + 1));
@ -758,7 +769,7 @@ static void dmenu_finalize(RofiViewState *state) {
retv = 10 + (mretv & MENU_LOWER_MASK); retv = 10 + (mretv & MENU_LOWER_MASK);
} }
g_free(input); g_free(input);
dmenu_finish(state, retv); dmenu_finish(pd, state, retv);
return; return;
} else { } else {
pd->selected_line = next_pos - 1; pd->selected_line = next_pos - 1;
@ -768,7 +779,7 @@ static void dmenu_finalize(RofiViewState *state) {
rofi_view_restart(state); rofi_view_restart(state);
rofi_view_set_selected_line(state, pd->selected_line); rofi_view_set_selected_line(state, pd->selected_line);
if (!restart) { if (!restart) {
dmenu_finish(state, retv); dmenu_finish(pd,state, retv);
} }
return; return;
} }
@ -824,7 +835,7 @@ static void dmenu_finalize(RofiViewState *state) {
rofi_view_restart(state); rofi_view_restart(state);
rofi_view_set_selected_line(state, pd->selected_line); rofi_view_set_selected_line(state, pd->selected_line);
} else { } else {
dmenu_finish(state, retv); dmenu_finish(pd,state, retv);
} }
} }
@ -899,6 +910,9 @@ int dmenu_mode_dialog(void) {
} }
rofi_view_set_selected_line(state, pd->selected_line); rofi_view_set_selected_line(state, pd->selected_line);
rofi_view_set_active(state); rofi_view_set_active(state);
if (pd->loading) {
rofi_view_set_overlay(state, "Loading.. ");
}
return FALSE; return FALSE;
} }