mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
Ticket #3700: fix segfault after switch left panel to info mode.
(widget_replace): if new widget cannot take focus, move focus to other widget before widget replacement. In our case, the focused file panel is replaced by Info one. Info panel a) isn't selectable (it never takes focus) and b) uses CWD of current panel. Therefore focus must be moved to other file panel to make it current and correctly set up it's CWD before first draw of Info panel. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
755447b96e
commit
716479ba4f
@ -419,6 +419,7 @@ widget_replace (Widget * old_w, Widget * new_w)
|
|||||||
{
|
{
|
||||||
WDialog *h = old_w->owner;
|
WDialog *h = old_w->owner;
|
||||||
gboolean should_focus = FALSE;
|
gboolean should_focus = FALSE;
|
||||||
|
GList *holder;
|
||||||
|
|
||||||
if (h->widgets == NULL)
|
if (h->widgets == NULL)
|
||||||
return;
|
return;
|
||||||
@ -426,25 +427,43 @@ widget_replace (Widget * old_w, Widget * new_w)
|
|||||||
if (h->current == NULL)
|
if (h->current == NULL)
|
||||||
h->current = h->widgets;
|
h->current = h->widgets;
|
||||||
|
|
||||||
|
/* locate widget position in the list */
|
||||||
if (old_w == h->current->data)
|
if (old_w == h->current->data)
|
||||||
should_focus = TRUE;
|
holder = h->current;
|
||||||
|
else
|
||||||
|
holder = g_list_find (h->widgets, old_w);
|
||||||
|
|
||||||
|
/* if old widget is focused, we should focus the new one... */
|
||||||
|
if (widget_get_state (old_w, WST_FOCUSED))
|
||||||
|
should_focus = TRUE;
|
||||||
|
/* ...but if new widget isn't selectable, we cannot focus it */
|
||||||
|
if (!widget_get_options (new_w, WOP_SELECTABLE))
|
||||||
|
should_focus = FALSE;
|
||||||
|
|
||||||
|
/* if new widget isn't selectable, select other widget before replace */
|
||||||
|
if (!should_focus)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = dlg_get_widget_next_of (holder);
|
||||||
|
!widget_get_options (WIDGET (l->data), WOP_SELECTABLE)
|
||||||
|
&& !widget_get_state (WIDGET (l->data), WST_DISABLED); l = dlg_get_widget_next_of (l))
|
||||||
|
;
|
||||||
|
|
||||||
|
widget_select (WIDGET (l->data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* replace widget */
|
||||||
new_w->owner = h;
|
new_w->owner = h;
|
||||||
new_w->id = old_w->id;
|
new_w->id = old_w->id;
|
||||||
|
holder->data = new_w;
|
||||||
if (should_focus)
|
|
||||||
h->current->data = new_w;
|
|
||||||
else
|
|
||||||
g_list_find (h->widgets, old_w)->data = new_w;
|
|
||||||
|
|
||||||
send_message (old_w, NULL, MSG_DESTROY, 0, NULL);
|
send_message (old_w, NULL, MSG_DESTROY, 0, NULL);
|
||||||
send_message (new_w, NULL, MSG_INIT, 0, NULL);
|
send_message (new_w, NULL, MSG_INIT, 0, NULL);
|
||||||
|
|
||||||
if (should_focus)
|
if (should_focus)
|
||||||
widget_select (new_w);
|
widget_select (new_w);
|
||||||
|
else
|
||||||
/* draw inactive widget */
|
|
||||||
if (!widget_get_state (new_w, WST_FOCUSED))
|
|
||||||
widget_redraw (new_w);
|
widget_redraw (new_w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user