window: menu leak fixes
When a menu self-destructs, free also the widget and struct menu.
As menus are self-destructing, it does not make sense to store the
window pointer, since we cannot clear it automatically. Therefore,
rename window_create_menu() to window_show_menu() that does not return
the window pointer. It also calls window_schedule_redraw() internally.
Fixes Valgrind reported memory leaks.
The alternative would be to explicitly destroy the menu in application's
menu callback.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index e2e2433..642e92a 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -59,7 +59,6 @@
struct surface base;
struct window *window;
struct widget *widget;
- struct window *menu;
struct wl_list launcher_list;
};
@@ -141,11 +140,9 @@
};
input_get_position(input, &x, &y);
- panel->menu = window_create_menu(window_get_display(panel->window),
- input, time, panel->window,
- x - 10, y - 10, NULL, entries, 4);
-
- window_schedule_redraw(panel->menu);
+ window_show_menu(window_get_display(panel->window),
+ input, time, panel->window,
+ x - 10, y - 10, NULL, entries, 4);
}
static void
diff --git a/clients/resizor.c b/clients/resizor.c
index 5eeb8ea..15900fc 100644
--- a/clients/resizor.c
+++ b/clients/resizor.c
@@ -171,12 +171,8 @@
};
input_get_position(input, &x, &y);
- resizor->menu = window_create_menu(resizor->display,
- input, time, resizor->window,
- x - 10, y - 10,
- menu_func, entries, 4);
-
- window_schedule_redraw(resizor->menu);
+ window_show_menu(resizor->display, input, time, resizor->window,
+ x - 10, y - 10, menu_func, entries, 4);
}
static void
diff --git a/clients/window.c b/clients/window.c
index d1833af..6cd9300 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -132,7 +132,6 @@
struct frame *frame;
struct widget *widget;
- struct window *menu;
void *user_data;
struct wl_list link;
@@ -1394,13 +1393,8 @@
}
} else if (button == BTN_RIGHT && state == 1) {
input_get_position(input, &x, &y);
- window->menu = window_create_menu(window->display,
- input, time,
- window,
- x - 10, y - 10,
- frame_menu_func,
- entries, 4);
- window_schedule_redraw(window->menu);
+ window_show_menu(window->display, input, time, window,
+ x - 10, y - 10, frame_menu_func, entries, 4);
}
}
@@ -2082,6 +2076,14 @@
}
static void
+menu_destroy(struct menu *menu)
+{
+ widget_destroy(menu->widget);
+ window_destroy(menu->window);
+ free(menu);
+}
+
+static void
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
{
struct window *window = data;
@@ -2094,7 +2096,7 @@
menu->func(window->parent, menu->current, window->parent->user_data);
input_ungrab(menu->input, 0);
- window_destroy(window);
+ menu_destroy(menu);
}
static const struct wl_shell_surface_listener shell_surface_listener = {
@@ -2393,7 +2395,7 @@
menu->func(menu->window->parent,
menu->current, menu->window->parent->user_data);
input_ungrab(input, time);
- window_destroy(menu->widget->window);
+ menu_destroy(menu);
}
}
@@ -2437,11 +2439,11 @@
cairo_destroy(cr);
}
-struct window *
-window_create_menu(struct display *display,
- struct input *input, uint32_t time, struct window *parent,
- int32_t x, int32_t y,
- menu_func_t func, const char **entries, int count)
+void
+window_show_menu(struct display *display,
+ struct input *input, uint32_t time, struct window *parent,
+ int32_t x, int32_t y,
+ menu_func_t func, const char **entries, int count)
{
struct window *window;
struct menu *menu;
@@ -2449,12 +2451,12 @@
menu = malloc(sizeof *menu);
if (!menu)
- return NULL;
+ return;
window = window_create_internal(parent->display, parent,
200, count * 20 + margin * 2);
if (!window)
- return NULL;
+ return;
menu->window = window;
menu->widget = window_add_widget(menu->window, menu);
@@ -2480,8 +2482,7 @@
widget_set_button_handler(menu->widget, menu_button_handler);
input_grab(input, menu->widget, 0);
-
- return window;
+ window_schedule_redraw(window);
}
void
diff --git a/clients/window.h b/clients/window.h
index 4ff2fc8..e35d657 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -200,11 +200,11 @@
typedef void (*menu_func_t)(struct window *window, int index, void *data);
-struct window *
-window_create_menu(struct display *display,
- struct input *input, uint32_t time, struct window *parent,
- int32_t x, int32_t y,
- menu_func_t func, const char **entries, int count);
+void
+window_show_menu(struct display *display,
+ struct input *input, uint32_t time, struct window *parent,
+ int32_t x, int32_t y,
+ menu_func_t func, const char **entries, int count);
void
window_destroy(struct window *window);