Skip to content

Commit

Permalink
actions: Implement passing the active window xid to exec strings.
Browse files Browse the repository at this point in the history
This can be used to launch a program that accepts another window's
xid to be transient for.
  • Loading branch information
mtwebster committed Apr 2, 2021
1 parent 1b38f76 commit d903a29
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 33 deletions.
12 changes: 11 additions & 1 deletion eel/eel-gtk-extensions.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include <X11/Xatom.h>
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <math.h>
Expand Down Expand Up @@ -340,3 +339,14 @@ eel_gtk_message_dialog_set_details_label (GtkMessageDialog *dialog,
gtk_widget_show (label);
gtk_widget_show (expander);
}

XID
eel_gtk_get_window_xid (GtkWindow *window)
{
g_return_val_if_fail (GTK_IS_WINDOW (window), 0);

GdkWindow *gdkw = gtk_widget_get_window (GTK_WIDGET (window));
g_return_val_if_fail (GDK_IS_X11_WINDOW (gdkw), 0);

return gdk_x11_window_get_xid (gdkw);
}
2 changes: 2 additions & 0 deletions eel/eel-gtk-extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <eel/eel-gdk-extensions.h>

/* GtkWindow */
Expand All @@ -52,4 +53,5 @@ GtkMenuItem * eel_gtk_menu_insert_separator (GtkMenu
void eel_gtk_message_dialog_set_details_label (GtkMessageDialog *dialog,
const gchar *details_text);

XID eel_gtk_get_window_xid (GtkWindow *window);
#endif /* EEL_GTK_EXTENSIONS_H */
1 change: 1 addition & 0 deletions files/usr/share/nemo/actions/sample.nemo_action
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Active=false
# %D - insert device path of file (i.e. /dev/sdb1)
# %e - insert display name of first selected file with the extension stripped
# %% - insert a literal percent sign, don't treat the next character as a token
# %X - insert the XID for the NemoWindow this action is being activated in.

# The name to show in the menu, locale supported with standard desktop spec.
# **** REQUIRED ****
Expand Down
58 changes: 43 additions & 15 deletions libnemo-private/nemo-action.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "nemo-action.h"
#include <eel/eel-string.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-gtk-extensions.h>
#include <glib/gi18n.h>
#include <gdk/gdk.h>
#include "nemo-file-utilities.h"
Expand Down Expand Up @@ -1167,6 +1168,10 @@ find_token_type (const gchar *str, TokenType *token_type)
*token_type = TOKEN_LITERAL_PERCENT;
return ptr;
}
if (g_str_has_prefix (ptr, TOKEN_EXEC_XID)) {
*token_type = TOKEN_XID;
return ptr;
}
}

return NULL;
Expand Down Expand Up @@ -1266,7 +1271,11 @@ get_device_path (NemoAction *action, NemoFile *file)
}

static gchar *
get_insertion_string (NemoAction *action, TokenType token_type, GList *selection, NemoFile *parent)
get_insertion_string (NemoAction *action,
TokenType token_type,
GList *selection,
NemoFile *parent,
GtkWindow *window)
{
GList *l;

Expand All @@ -1277,6 +1286,9 @@ get_insertion_string (NemoAction *action, TokenType token_type, GList *selection
case TOKEN_LITERAL_PERCENT:
str = g_string_append(str, "%");
break;
case TOKEN_XID:
g_string_append_printf (str, "%lu", eel_gtk_get_window_xid (window));
break;
case TOKEN_PATH_LIST:
if (g_list_length (selection) > 0) {
for (l = selection; l != NULL; l = l->next) {
Expand Down Expand Up @@ -1392,7 +1404,11 @@ get_insertion_string (NemoAction *action, TokenType token_type, GList *selection
}

static GString *
expand_action_string (NemoAction *action, GList *selection, NemoFile *parent, GString *str)
expand_action_string (NemoAction *action,
GList *selection,
NemoFile *parent,
GString *str,
GtkWindow *window)
{
gchar *ptr;
TokenType token_type;
Expand All @@ -1402,7 +1418,7 @@ expand_action_string (NemoAction *action, GList *selection, NemoFile *parent, GS
while (ptr != NULL) {
gint shift = ptr - str->str;

gchar *insertion = get_insertion_string (action, token_type, selection, parent);
gchar *insertion = get_insertion_string (action, token_type, selection, parent, window);
str = g_string_erase (str, shift, 2);
str = g_string_insert (str, shift, insertion);

Expand All @@ -1423,7 +1439,10 @@ expand_action_string (NemoAction *action, GList *selection, NemoFile *parent, GS
}

void
nemo_action_activate (NemoAction *action, GList *selection, NemoFile *parent)
nemo_action_activate (NemoAction *action,
GList *selection,
NemoFile *parent,
GtkWindow *window)
{
GError *error;
GString *exec = g_string_new (action->exec);
Expand All @@ -1432,7 +1451,7 @@ nemo_action_activate (NemoAction *action, GList *selection, NemoFile *parent)

action->escape_underscores = FALSE;

exec = expand_action_string (action, selection, parent, exec);
exec = expand_action_string (action, selection, parent, exec, window);

if (action->use_parent_dir) {
exec = g_string_prepend (exec, G_DIR_SEPARATOR_S);
Expand Down Expand Up @@ -1594,7 +1613,10 @@ nemo_action_get_orig_tt (NemoAction *action)


gchar *
nemo_action_get_label (NemoAction *action, GList *selection, NemoFile *parent)
nemo_action_get_label (NemoAction *action,
GList *selection,
NemoFile *parent,
GtkWindow *window)
{
const gchar *orig_label = nemo_action_get_orig_label (action);

Expand All @@ -1605,7 +1627,7 @@ nemo_action_get_label (NemoAction *action, GList *selection, NemoFile *parent)

GString *str = g_string_new (orig_label);

str = expand_action_string (action, selection, parent, str);
str = expand_action_string (action, selection, parent, str, window);

DEBUG ("Action Label: %s", str->str);

Expand All @@ -1615,7 +1637,10 @@ nemo_action_get_label (NemoAction *action, GList *selection, NemoFile *parent)
}

gchar *
nemo_action_get_tt (NemoAction *action, GList *selection, NemoFile *parent)
nemo_action_get_tt (NemoAction *action,
GList *selection,
NemoFile *parent,
GtkWindow *window)
{
const gchar *orig_tt = nemo_action_get_orig_tt (action);

Expand All @@ -1626,7 +1651,7 @@ nemo_action_get_tt (NemoAction *action, GList *selection, NemoFile *parent)

GString *str = g_string_new (orig_tt);

str = expand_action_string (action, selection, parent, str);
str = expand_action_string (action, selection, parent, str, window);

DEBUG ("Action Tooltip: %s", str->str);

Expand All @@ -1651,7 +1676,8 @@ static gboolean
check_exec_condition (NemoAction *action,
const gchar *condition,
GList *selection,
NemoFile *parent)
NemoFile *parent,
GtkWindow *window)
{
GString *exec;
GError *error;
Expand Down Expand Up @@ -1684,7 +1710,7 @@ check_exec_condition (NemoAction *action,

action->escape_underscores = FALSE;

exec = expand_action_string (action, selection, parent, exec);
exec = expand_action_string (action, selection, parent, exec, window);

if (use_parent_dir) {
exec = g_string_prepend (exec, G_DIR_SEPARATOR_S);
Expand Down Expand Up @@ -1734,9 +1760,10 @@ get_is_dir (NemoFile *file)

gboolean
nemo_action_get_visibility (NemoAction *action,
GList *selection,
NemoFile *parent,
gboolean for_places)
GList *selection,
NemoFile *parent,
gboolean for_places,
GtkWindow *window)
{
// Check DBUS
if (!get_dbus_satisfied (action))
Expand Down Expand Up @@ -1911,7 +1938,8 @@ nemo_action_get_visibility (NemoAction *action,
condition_type_show = check_exec_condition (action,
condition,
selection,
parent);
parent,
window);
}

if (!condition_type_show)
Expand Down
12 changes: 7 additions & 5 deletions libnemo-private/nemo-action.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define TOKEN_EXEC_DEVICE "%D"
#define TOKEN_EXEC_FILE_NO_EXT "%e"
#define TOKEN_EXEC_LITERAL_PERCENT "%%"
#define TOKEN_EXEC_XID "%X"

#define TOKEN_LABEL_FILE_NAME "%N" // Leave in for compatibility, same as TOKEN_EXEC_FILE_NAME

Expand Down Expand Up @@ -101,7 +102,8 @@ typedef enum {
TOKEN_PARENT_PATH,
TOKEN_DEVICE,
TOKEN_FILE_DISPLAY_NAME_NO_EXT,
TOKEN_LITERAL_PERCENT
TOKEN_LITERAL_PERCENT,
TOKEN_XID
} TokenType;

struct _NemoAction {
Expand Down Expand Up @@ -138,12 +140,12 @@ struct _NemoActionClass {

GType nemo_action_get_type (void);
NemoAction *nemo_action_new (const gchar *name, const gchar *path);
void nemo_action_activate (NemoAction *action, GList *selection, NemoFile *parent);
void nemo_action_activate (NemoAction *action, GList *selection, NemoFile *parent, GtkWindow *window);

const gchar *nemo_action_get_orig_label (NemoAction *action);
const gchar *nemo_action_get_orig_tt (NemoAction *action);
gchar *nemo_action_get_label (NemoAction *action, GList *selection, NemoFile *parent);
gchar *nemo_action_get_tt (NemoAction *action, GList *selection, NemoFile *parent);
gboolean nemo_action_get_visibility (NemoAction *action, GList *selection, NemoFile *parent, gboolean for_places);
gchar *nemo_action_get_label (NemoAction *action, GList *selection, NemoFile *parent, GtkWindow *window);
gchar *nemo_action_get_tt (NemoAction *action, GList *selection, NemoFile *parent, GtkWindow *window);
gboolean nemo_action_get_visibility (NemoAction *action, GList *selection, NemoFile *parent, gboolean for_places, GtkWindow *window);

#endif /* NEMO_ACTION_H */
6 changes: 4 additions & 2 deletions src/nemo-blank-desktop-window.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ action_activated_callback (GtkMenuItem *item, NemoAction *action)
{
GFile *desktop_location = nemo_get_desktop_location ();
NemoFile *desktop_file = nemo_file_get (desktop_location);
GtkWindow *window = g_object_get_data (G_OBJECT (item), "nemo-window");
g_object_unref (desktop_location);

nemo_action_activate (NEMO_ACTION (action), NULL, desktop_file);
nemo_action_activate (NEMO_ACTION (action), NULL, desktop_file, GTK_WINDOW (window));
}

static void
Expand Down Expand Up @@ -121,7 +122,7 @@ build_menu (NemoBlankDesktopWindow *window)
action = l->data;

if (action->show_in_blank_desktop && action->dbus_satisfied && action->gsettings_satisfied) {
gchar *label = nemo_action_get_label (action, NULL, NULL);
gchar *label = nemo_action_get_label (action, NULL, NULL, GTK_WINDOW (window));
item = gtk_image_menu_item_new_with_mnemonic (label);
g_free (label);

Expand All @@ -137,6 +138,7 @@ build_menu (NemoBlankDesktopWindow *window)
}

gtk_widget_set_visible (item, TRUE);
g_object_set_data (G_OBJECT (item), "nemo-window", window);
g_signal_connect (item, "activate", G_CALLBACK (action_activated_callback), action);
gtk_menu_shell_append (GTK_MENU_SHELL (window->details->popup_menu), item);
}
Expand Down
6 changes: 3 additions & 3 deletions src/nemo-places-sidebar.c
Original file line number Diff line number Diff line change
Expand Up @@ -2351,8 +2351,8 @@ bookmarks_check_popup_sensitivity (NemoPlacesSidebar *sidebar)

for (l = sidebar->action_items; l != NULL; l = l->next) {
p = l->data;
if (nemo_action_get_visibility (p->action, tmp, parent, TRUE)) {
gchar *action_label = nemo_action_get_label (p->action, tmp, parent);
if (nemo_action_get_visibility (p->action, tmp, parent, TRUE, GTK_WINDOW (sidebar->window))) {
gchar *action_label = nemo_action_get_label (p->action, tmp, parent, GTK_WINDOW (sidebar->window));

gtk_menu_item_set_label (GTK_MENU_ITEM (p->item), action_label);
gtk_widget_set_visible (p->item, TRUE);
Expand Down Expand Up @@ -3380,7 +3380,7 @@ action_activated_callback (GtkMenuItem *item, ActionPayload *payload)
GList *tmp = NULL;
tmp = g_list_append (tmp, file);

nemo_action_activate (NEMO_ACTION (payload->action), tmp, parent);
nemo_action_activate (NEMO_ACTION (payload->action), tmp, parent, GTK_WINDOW (sidebar->window));

nemo_file_list_free (tmp);

Expand Down
6 changes: 3 additions & 3 deletions src/nemo-tree-sidebar.c
Original file line number Diff line number Diff line change
Expand Up @@ -806,10 +806,10 @@ button_pressed_callback (GtkTreeView *treeview, GdkEventButton *event,

for (l = view->details->action_items; l != NULL; l = l->next) {
p = l->data;
if (nemo_action_get_visibility (p->action, tmp, parent, FALSE)) {
if (nemo_action_get_visibility (p->action, tmp, parent, FALSE, GTK_WINDOW (view->details->window))) {
gchar *action_label;

action_label = nemo_action_get_label (p->action, tmp, parent);
action_label = nemo_action_get_label (p->action, tmp, parent, GTK_WINDOW (view->details->window));
gtk_menu_item_set_label (GTK_MENU_ITEM (p->item), action_label);
g_free (action_label);

Expand Down Expand Up @@ -1208,7 +1208,7 @@ action_activated_callback (GtkMenuItem *item, ActionPayload *payload)
GList *tmp = NULL;
tmp = g_list_append (tmp, file);

nemo_action_activate (NEMO_ACTION (payload->action), tmp, parent);
nemo_action_activate (NEMO_ACTION (payload->action), tmp, parent, GTK_WINDOW (view->details->window));

nemo_file_list_free (tmp);

Expand Down
8 changes: 4 additions & 4 deletions src/nemo-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -6453,7 +6453,7 @@ run_action_callback (NemoAction *action, gpointer callback_data)
selected_files = nemo_view_get_selection (view);
NemoFile *parent = nemo_view_get_directory_as_file (view);

nemo_action_activate (action, selected_files, parent);
nemo_action_activate (action, selected_files, parent, GTK_WINDOW (view->details->window));

nemo_file_list_free (selected_files);
}
Expand All @@ -6476,11 +6476,11 @@ determine_visibility (gpointer data, gpointer callback_data)

NemoFile *parent = nemo_view_get_directory_as_file (view);

if (nemo_action_get_visibility (action, selection, parent, FALSE)) {
if (nemo_action_get_visibility (action, selection, parent, FALSE, GTK_WINDOW (view->details->window))) {
gchar *label, *tt;

label = nemo_action_get_label (action, selection, parent);
tt = nemo_action_get_tt (action, selection, parent);
label = nemo_action_get_label (action, selection, parent, GTK_WINDOW (view->details->window));
tt = nemo_action_get_tt (action, selection, parent, GTK_WINDOW (view->details->window));

gtk_action_set_label (GTK_ACTION (action), label);
gtk_action_set_tooltip (GTK_ACTION (action), tt);
Expand Down

0 comments on commit d903a29

Please sign in to comment.