Skip to content
Permalink
Browse files

pathbar: fix random segfaults on opening mounts from Desktop

Adapt and apply these four relevent Nautilus commits, which remove the code responsible for the segfaults:
*GNOME/nautilus@e1ad3c0#diff-f896071d07d34e87af94a18de95e4ea2
 "pathbar: add a path-event signal"

*GNOME/nautilus@875efc3#diff-f896071d07d34e87af94a18de95e4ea2
 "pathbar: remove unused code"

*GNOME/nautilus@cfa51e6
 "window-pane: use the path-event signal from NautilusPathBar" (now CajaPathBar)

*GNOME/nautilus@2759def
 "pathbar: add a return value from path-event signal"
  • Loading branch information...
lukefromdc authored and sc0w committed Apr 6, 2018
1 parent 94c2f1c commit 017b058c8a209f1d5d39ff0ef346eb69ce0e0748
Showing with 84 additions and 121 deletions.
  1. +23 −105 src/caja-navigation-window-pane.c
  2. +55 −14 src/caja-pathbar.c
  3. +6 −2 src/caja-pathbar.h
@@ -262,63 +262,21 @@ location_button_create (CajaNavigationWindowPane *pane)
}

static gboolean
path_bar_button_pressed_callback (GtkWidget *widget,
GdkEventButton *event,
CajaNavigationWindowPane *pane)
{
CajaWindowSlot *slot;
CajaView *view;
GFile *location;
char *uri;

caja_window_set_active_pane (CAJA_WINDOW_PANE (pane)->window, CAJA_WINDOW_PANE (pane));

g_object_set_data (G_OBJECT (widget), "handle-button-release",
GINT_TO_POINTER (TRUE));

if (event->button == 3)
{
slot = caja_window_get_active_slot (CAJA_WINDOW_PANE (pane)->window);
view = slot->content_view;
if (view != NULL)
{
location = caja_path_bar_get_path_for_button (
CAJA_PATH_BAR (pane->path_bar), widget);
if (location != NULL)
{
uri = g_file_get_uri (location);
caja_view_pop_up_location_context_menu (
view, event, uri);
g_object_unref (G_OBJECT (location));
g_free (uri);
return TRUE;
}
}
}
path_bar_path_event_callback (CajaPathBar *path_bar,
GFile *location,
GdkEventButton *event,
CajaWindowPane *pane)

return FALSE;
}

static gboolean
path_bar_button_released_callback (GtkWidget *widget,
GdkEventButton *event,
CajaNavigationWindowPane *pane)
{
CajaWindowSlot *slot;
CajaWindowOpenFlags flags;
GFile *location;
int mask;
gboolean handle_button_release;

mask = event->state & gtk_accelerator_get_default_mod_mask ();
flags = 0;

handle_button_release = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
"handle-button-release"));
CajaView *view;
char *uri;

if (event->type == GDK_BUTTON_RELEASE && handle_button_release)
{
location = caja_path_bar_get_path_for_button (CAJA_PATH_BAR (pane->path_bar), widget);
if (event->type == GDK_BUTTON_RELEASE) {
mask = event->state & gtk_accelerator_get_default_mod_mask ();
flags = 0;

if (event->button == 2 && mask == 0)
{
@@ -335,25 +293,24 @@ path_bar_button_released_callback (GtkWidget *widget,
caja_window_slot_info_open_location (slot, location,
CAJA_WINDOW_OPEN_ACCORDING_TO_MODE,
flags, NULL);
g_object_unref (location);
return TRUE;
}

g_object_unref (location);
return FALSE;
}

if (event->button == 3) {
slot = caja_window_get_active_slot (pane->window);
view = slot->content_view;
if (view != NULL) {
uri = g_file_get_uri (location);
caja_view_pop_up_location_context_menu (view, event, uri);
g_free (uri);
}
return TRUE;
}
return FALSE;
}

static void
path_bar_button_drag_begin_callback (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
g_object_set_data (G_OBJECT (widget), "handle-button-release",
GINT_TO_POINTER (FALSE));
}

static void
notebook_popup_menu_new_tab_cb (GtkMenuItem *menuitem,
gpointer user_data)
@@ -364,46 +321,6 @@ notebook_popup_menu_new_tab_cb (GtkMenuItem *menuitem,
caja_window_new_tab (pane->window);
}

static void
path_bar_path_set_callback (GtkWidget *widget,
GFile *location,
CajaNavigationWindowPane *pane)
{
GList *children, *l;
GtkWidget *child;

children = gtk_container_get_children (GTK_CONTAINER (widget));

for (l = children; l != NULL; l = l->next)
{
child = GTK_WIDGET (l->data);

if (!GTK_IS_TOGGLE_BUTTON (child))
{
continue;
}

if (!g_signal_handler_find (child,
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
0, 0, NULL,
path_bar_button_pressed_callback,
pane))
{
g_signal_connect (child, "button-press-event",
G_CALLBACK (path_bar_button_pressed_callback),
pane);
g_signal_connect (child, "button-release-event",
G_CALLBACK (path_bar_button_released_callback),
pane);
g_signal_connect (child, "drag-begin",
G_CALLBACK (path_bar_button_drag_begin_callback),
pane);
}
}

g_list_free (children);
}

static void
notebook_popup_menu_move_left_cb (GtkMenuItem *menuitem,
gpointer user_data)
@@ -767,8 +684,9 @@ caja_navigation_window_pane_setup (CajaNavigationWindowPane *pane)

g_signal_connect_object (pane->path_bar, "path_clicked",
G_CALLBACK (path_bar_location_changed_callback), pane, 0);
g_signal_connect_object (pane->path_bar, "path_set",
G_CALLBACK (path_bar_path_set_callback), pane, 0);

g_signal_connect_object (pane->path_bar, "path-event",
G_CALLBACK (path_bar_path_event_callback), pane, 0);

gtk_box_pack_start (GTK_BOX (hbox),
pane->path_bar,
@@ -31,14 +31,11 @@
#include <libcaja-private/caja-dnd.h>
#include <libcaja-private/caja-icon-dnd.h>
#include "caja-pathbar.h"
#include "caja-window.h"
#include "caja-window-private.h"
#include "caja-window-slot.h"

enum
{
PATH_CLICKED,
PATH_SET,
PATH_EVENT,
LAST_SIGNAL
};

@@ -412,15 +409,16 @@ caja_path_bar_class_init (CajaPathBarClass *path_bar_class)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_FILE);
path_bar_signals [PATH_SET] =
g_signal_new ("path-set",

path_bar_signals [PATH_EVENT] =
g_signal_new ("path-event",
G_OBJECT_CLASS_TYPE (path_bar_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (CajaPathBarClass, path_set),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_FILE);
G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (CajaPathBarClass, path_event),
NULL, NULL, NULL,
G_TYPE_BOOLEAN, 2,
G_TYPE_FILE,
GDK_TYPE_EVENT);

gtk_container_class_handle_border_width (container_class);
}
@@ -1338,6 +1336,48 @@ button_clicked_cb (GtkWidget *button,
g_signal_emit (path_bar, path_bar_signals [PATH_CLICKED], 0, button_data->path);
}

static gboolean
button_event_cb (GtkWidget *button,
GdkEventButton *event,
gpointer data)
{
ButtonData *button_data;
CajaPathBar *path_bar;
GList *button_list;
gboolean retval;

button_data = BUTTON_DATA (data);
path_bar = CAJA_PATH_BAR (gtk_widget_get_parent (button));

if (event->type == GDK_BUTTON_PRESS) {
g_object_set_data (G_OBJECT (button), "handle-button-release",
GINT_TO_POINTER (TRUE));
}

if (event->type == GDK_BUTTON_RELEASE &&
!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button),
"handle-button-release"))) {
return FALSE;
}

button_list = g_list_find (path_bar->button_list, button_data);
g_assert (button_list != NULL);

g_signal_emit (path_bar, path_bar_signals [PATH_EVENT], 0, button_data->path, event, &retval);

return retval;
}

static void
button_drag_begin_cb (GtkWidget *widget,
GdkDragContext *drag_context,
gpointer user_data)
{
g_object_set_data (G_OBJECT (widget), "handle-button-release",
GINT_TO_POINTER (FALSE));
}


static CajaIconInfo *
get_type_icon_info (ButtonData *button_data)
{
@@ -1910,6 +1950,9 @@ make_directory_button (CajaPathBar *path_bar,
caja_path_bar_update_button_state (button_data, current_dir);

g_signal_connect (button_data->button, "clicked", G_CALLBACK (button_clicked_cb), button_data);
g_signal_connect (button_data->button, "button-press-event", G_CALLBACK (button_event_cb), button_data);
g_signal_connect (button_data->button, "button-release-event", G_CALLBACK (button_event_cb), button_data);
g_signal_connect (button_data->button, "drag-begin", G_CALLBACK (button_drag_begin_cb), button_data);
g_object_weak_ref (G_OBJECT (button_data->button), (GWeakNotify) button_data_free, button_data);

setup_button_drag_source (button_data);
@@ -2063,8 +2106,6 @@ caja_path_bar_update_path (CajaPathBar *path_bar,
path_bar->current_path = g_object_ref (file_path);
path_bar->current_button_data = current_button_data;

g_signal_emit (path_bar, path_bar_signals [PATH_SET], 0, file_path);

return result;
}

@@ -71,15 +71,19 @@ struct _CajaPathBarClass

void (* path_clicked) (CajaPathBar *path_bar,
GFile *location);
void (* path_set) (CajaPathBar *path_bar,
GFile *location);

void (* path_event) (CajaPathBar *path_bar,
GdkEventButton *event,
GFile *location);
};

GType caja_path_bar_get_type (void) G_GNUC_CONST;

gboolean caja_path_bar_set_path (CajaPathBar *path_bar, GFile *file);

GFile * caja_path_bar_get_path_for_button (CajaPathBar *path_bar,
GtkWidget *button);

void caja_path_bar_clear_buttons (CajaPathBar *path_bar);

GtkWidget * caja_path_bar_get_button_from_button_list_entry (gpointer entry);

0 comments on commit 017b058

Please sign in to comment.
You can’t perform that action at this time.