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>
This commit is contained in:
@@ -59,7 +59,6 @@ struct panel {
|
|||||||
struct surface base;
|
struct surface base;
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct widget *widget;
|
struct widget *widget;
|
||||||
struct window *menu;
|
|
||||||
struct wl_list launcher_list;
|
struct wl_list launcher_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,11 +140,9 @@ show_menu(struct panel *panel, struct input *input, uint32_t time)
|
|||||||
};
|
};
|
||||||
|
|
||||||
input_get_position(input, &x, &y);
|
input_get_position(input, &x, &y);
|
||||||
panel->menu = window_create_menu(window_get_display(panel->window),
|
window_show_menu(window_get_display(panel->window),
|
||||||
input, time, panel->window,
|
input, time, panel->window,
|
||||||
x - 10, y - 10, NULL, entries, 4);
|
x - 10, y - 10, NULL, entries, 4);
|
||||||
|
|
||||||
window_schedule_redraw(panel->menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+2
-6
@@ -171,12 +171,8 @@ show_menu(struct resizor *resizor, struct input *input, uint32_t time)
|
|||||||
};
|
};
|
||||||
|
|
||||||
input_get_position(input, &x, &y);
|
input_get_position(input, &x, &y);
|
||||||
resizor->menu = window_create_menu(resizor->display,
|
window_show_menu(resizor->display, input, time, resizor->window,
|
||||||
input, time, resizor->window,
|
x - 10, y - 10, menu_func, entries, 4);
|
||||||
x - 10, y - 10,
|
|
||||||
menu_func, entries, 4);
|
|
||||||
|
|
||||||
window_schedule_redraw(resizor->menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+20
-19
@@ -132,7 +132,6 @@ struct window {
|
|||||||
|
|
||||||
struct frame *frame;
|
struct frame *frame;
|
||||||
struct widget *widget;
|
struct widget *widget;
|
||||||
struct window *menu;
|
|
||||||
|
|
||||||
void *user_data;
|
void *user_data;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
@@ -1394,13 +1393,8 @@ frame_button_handler(struct widget *widget,
|
|||||||
}
|
}
|
||||||
} else if (button == BTN_RIGHT && state == 1) {
|
} else if (button == BTN_RIGHT && state == 1) {
|
||||||
input_get_position(input, &x, &y);
|
input_get_position(input, &x, &y);
|
||||||
window->menu = window_create_menu(window->display,
|
window_show_menu(window->display, input, time, window,
|
||||||
input, time,
|
x - 10, y - 10, frame_menu_func, entries, 4);
|
||||||
window,
|
|
||||||
x - 10, y - 10,
|
|
||||||
frame_menu_func,
|
|
||||||
entries, 4);
|
|
||||||
window_schedule_redraw(window->menu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2081,6 +2075,14 @@ handle_configure(void *data, struct wl_shell_surface *shell_surface,
|
|||||||
window_resize(window, width, height);
|
window_resize(window, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_destroy(struct menu *menu)
|
||||||
|
{
|
||||||
|
widget_destroy(menu->widget);
|
||||||
|
window_destroy(menu->window);
|
||||||
|
free(menu);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
||||||
{
|
{
|
||||||
@@ -2094,7 +2096,7 @@ handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
|
|||||||
|
|
||||||
menu->func(window->parent, menu->current, window->parent->user_data);
|
menu->func(window->parent, menu->current, window->parent->user_data);
|
||||||
input_ungrab(menu->input, 0);
|
input_ungrab(menu->input, 0);
|
||||||
window_destroy(window);
|
menu_destroy(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||||
@@ -2393,7 +2395,7 @@ menu_button_handler(struct widget *widget,
|
|||||||
menu->func(menu->window->parent,
|
menu->func(menu->window->parent,
|
||||||
menu->current, menu->window->parent->user_data);
|
menu->current, menu->window->parent->user_data);
|
||||||
input_ungrab(input, time);
|
input_ungrab(input, time);
|
||||||
window_destroy(menu->widget->window);
|
menu_destroy(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2437,11 +2439,11 @@ menu_redraw_handler(struct widget *widget, void *data)
|
|||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct window *
|
void
|
||||||
window_create_menu(struct display *display,
|
window_show_menu(struct display *display,
|
||||||
struct input *input, uint32_t time, struct window *parent,
|
struct input *input, uint32_t time, struct window *parent,
|
||||||
int32_t x, int32_t y,
|
int32_t x, int32_t y,
|
||||||
menu_func_t func, const char **entries, int count)
|
menu_func_t func, const char **entries, int count)
|
||||||
{
|
{
|
||||||
struct window *window;
|
struct window *window;
|
||||||
struct menu *menu;
|
struct menu *menu;
|
||||||
@@ -2449,12 +2451,12 @@ window_create_menu(struct display *display,
|
|||||||
|
|
||||||
menu = malloc(sizeof *menu);
|
menu = malloc(sizeof *menu);
|
||||||
if (!menu)
|
if (!menu)
|
||||||
return NULL;
|
return;
|
||||||
|
|
||||||
window = window_create_internal(parent->display, parent,
|
window = window_create_internal(parent->display, parent,
|
||||||
200, count * 20 + margin * 2);
|
200, count * 20 + margin * 2);
|
||||||
if (!window)
|
if (!window)
|
||||||
return NULL;
|
return;
|
||||||
|
|
||||||
menu->window = window;
|
menu->window = window;
|
||||||
menu->widget = window_add_widget(menu->window, menu);
|
menu->widget = window_add_widget(menu->window, menu);
|
||||||
@@ -2480,8 +2482,7 @@ window_create_menu(struct display *display,
|
|||||||
widget_set_button_handler(menu->widget, menu_button_handler);
|
widget_set_button_handler(menu->widget, menu_button_handler);
|
||||||
|
|
||||||
input_grab(input, menu->widget, 0);
|
input_grab(input, menu->widget, 0);
|
||||||
|
window_schedule_redraw(window);
|
||||||
return window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
+5
-5
@@ -200,11 +200,11 @@ window_create_transient(struct display *display, struct window *parent,
|
|||||||
|
|
||||||
typedef void (*menu_func_t)(struct window *window, int index, void *data);
|
typedef void (*menu_func_t)(struct window *window, int index, void *data);
|
||||||
|
|
||||||
struct window *
|
void
|
||||||
window_create_menu(struct display *display,
|
window_show_menu(struct display *display,
|
||||||
struct input *input, uint32_t time, struct window *parent,
|
struct input *input, uint32_t time, struct window *parent,
|
||||||
int32_t x, int32_t y,
|
int32_t x, int32_t y,
|
||||||
menu_func_t func, const char **entries, int count);
|
menu_func_t func, const char **entries, int count);
|
||||||
|
|
||||||
void
|
void
|
||||||
window_destroy(struct window *window);
|
window_destroy(struct window *window);
|
||||||
|
|||||||
Reference in New Issue
Block a user