diff --git a/src/fsearch.c b/src/fsearch.c index e2b991e97..0565b1b28 100644 --- a/src/fsearch.c +++ b/src/fsearch.c @@ -33,6 +33,7 @@ #include "fsearch_window.h" #include "icon_resources.h" #include "ui_resources.h" +#include "fsearch_preview.h" #include #include #include @@ -556,6 +557,9 @@ fsearch_application_shutdown(GApplication *app) { g_debug("[app] database thread finished."); } + // close the preview + fsearch_preview_call_close(); + g_clear_pointer(&fsearch->db, db_unref); g_clear_object(&fsearch->db_thread_cancellable); diff --git a/src/fsearch_preview.c b/src/fsearch_preview.c new file mode 100644 index 000000000..c444d9084 --- /dev/null +++ b/src/fsearch_preview.c @@ -0,0 +1,83 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + */ + +#include "fsearch_preview.h" +#include "fsearch.h" + +#include + +#define PREVIEWER_DBUS_NAME "org.gnome.NautilusPreviewer" +#define PREVIEWER_DBUS_IFACE "org.gnome.NautilusPreviewer" +#define PREVIEWER_DBUS_PATH "/org/gnome/NautilusPreviewer" + +static void +preview_show_file_ready_cb(GObject *source, GAsyncResult *res, gpointer user_data) { + g_autoptr(GError) error = NULL; + g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); + + if (error != NULL) { + g_debug("Unable to call ShowFile on NautilusPreviewer: %s", error->message); + } +} + +static void +preview_close_ready_cb(GObject *source, GAsyncResult *res, gpointer user_data) { + g_autoptr(GError) error = NULL; + g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); + + if (error != NULL) { + g_debug("Unable to call Close on NautilusPreviewer: %s", error->message); + } +} + +void +fsearch_preview_call_show_file(const gchar *uri, guint xid, gboolean close_if_already_visible) { + GDBusConnection *connection = g_application_get_dbus_connection(G_APPLICATION(FSEARCH_APPLICATION_DEFAULT)); + GVariant *variant = g_variant_new("(sib)", uri, xid, close_if_already_visible); + + g_dbus_connection_call(connection, + PREVIEWER_DBUS_NAME, + PREVIEWER_DBUS_PATH, + PREVIEWER_DBUS_IFACE, + "ShowFile", + variant, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + preview_show_file_ready_cb, + NULL); +} + +void +fsearch_preview_call_close(void) { + GDBusConnection *connection = g_application_get_dbus_connection(G_APPLICATION(FSEARCH_APPLICATION_DEFAULT)); + + g_dbus_connection_call(connection, + PREVIEWER_DBUS_NAME, + PREVIEWER_DBUS_PATH, + PREVIEWER_DBUS_IFACE, + "Close", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + preview_close_ready_cb, + NULL); +} diff --git a/src/fsearch_preview.h b/src/fsearch_preview.h new file mode 100644 index 000000000..400219cba --- /dev/null +++ b/src/fsearch_preview.h @@ -0,0 +1,27 @@ +/* + FSearch - A fast file search utility + Copyright © 2020 Christian Boxdörfer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + */ + +#pragma once + +#include + +void +fsearch_preview_call_show_file(const gchar *uri, guint xid, gboolean close_if_already_visible); + +void +fsearch_preview_call_close(void); \ No newline at end of file diff --git a/src/fsearch_window.c b/src/fsearch_window.c index f4c517d55..70196a945 100644 --- a/src/fsearch_window.c +++ b/src/fsearch_window.c @@ -508,6 +508,9 @@ on_listview_key_press_event(GtkWidget *widget, GdkEvent *event, gpointer user_da case GDK_KEY_KP_Enter: g_action_group_activate_action(group, "open", NULL); return GDK_EVENT_STOP; + case GDK_KEY_space: + g_action_group_activate_action(group, "preview", NULL); + return GDK_EVENT_STOP; default: return GDK_EVENT_PROPAGATE; } diff --git a/src/fsearch_window_actions.c b/src/fsearch_window_actions.c index b086ab6cc..b8d4d0743 100644 --- a/src/fsearch_window_actions.c +++ b/src/fsearch_window_actions.c @@ -26,6 +26,11 @@ #include #include +#include + +#ifdef GDK_WINDOWING_X11 +#include +#endif #include "fsearch_clipboard.h" #include "fsearch_config.h" @@ -35,6 +40,7 @@ #include "fsearch_statusbar.h" #include "fsearch_ui_utils.h" #include "fsearch_window_actions.h" +#include "fsearch_preview.h" static void action_set_active_int(GActionGroup *group, const gchar *action_name, int32_t value) { @@ -584,6 +590,30 @@ fsearch_window_action_open_folder(GSimpleAction *action, GVariant *variant, gpoi fsearch_window_action_open_generic(self, true, false); } +static void +fsearch_window_action_preview(GSimpleAction *action, GVariant *variant, gpointer user_data) { + FsearchApplicationWindow *self = user_data; + guint xid = 0; + GList *file_list = NULL; + + fsearch_application_window_selection_for_each(self, prepend_full_path_to_list, &file_list); + if (!file_list) { + return; + } + + GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(self)); +#ifdef GDK_WINDOWING_X11 + GdkWindow *window = gtk_widget_get_window (toplevel); + if (GDK_IS_X11_WINDOW(window)) { + xid = gdk_x11_window_get_xid(gtk_widget_get_window(toplevel)); + } +#endif + + g_autofree gchar *first_selected_uri = g_filename_to_uri((char *)file_list->data, NULL, NULL); + fsearch_preview_call_show_file(first_selected_uri, xid, TRUE); + g_list_free_full(g_steal_pointer(&file_list), g_free); +} + static void on_fsearch_window_action_open_with_response(GtkDialog *dialog, gint response_id, gpointer user_data) { if (response_id != GTK_RESPONSE_OK) { @@ -825,6 +855,7 @@ static GActionEntry FsearchWindowActions[] = { {"open_with", fsearch_window_action_open_with, "s"}, {"open_with_other", fsearch_window_action_open_with_other, "s"}, {"open_folder", fsearch_window_action_open_folder}, + {"preview", fsearch_window_action_preview}, {"close_window", fsearch_window_action_close_window}, {"copy_clipboard", fsearch_window_action_copy}, {"copy_as_text_path_and_name_clipboard", fsearch_window_action_copy_full_path}, diff --git a/src/meson.build b/src/meson.build index f6b0a890e..e340b4832 100644 --- a/src/meson.build +++ b/src/meson.build @@ -51,6 +51,7 @@ libfsearch_sources = [ 'fsearch_utf.c', 'fsearch_window.c', 'fsearch_window_actions.c', + 'fsearch_preview.c', ] if build_machine.system()=='darwin'