diff --git a/lib/widget/dialog.c b/lib/widget/dialog.c index a53c04696..1677a7047 100644 --- a/lib/widget/dialog.c +++ b/lib/widget/dialog.c @@ -362,7 +362,7 @@ dlg_mouse_event (WDialog * h, Gpm_Event * event) { Widget *wh = WIDGET (h); - GList *p, *first; + GList *p; /* close the dialog by mouse left click out of dialog area */ if (mouse_close_dialog && !h->fullscreen && ((event->buttons & GPM_B_LEFT) != 0) @@ -382,15 +382,12 @@ dlg_mouse_event (WDialog * h, Gpm_Event * event) return mou; } - first = h->current; - p = first; - + /* send the event to widgets in reverse Z-order */ + p = g_list_last (h->widgets); do { Widget *w = WIDGET (p->data); - p = dlg_widget_prev (h, p); - if ((w->options & W_DISABLED) == 0 && w->mouse != NULL) { /* put global cursor position to the widget */ @@ -400,8 +397,10 @@ dlg_mouse_event (WDialog * h, Gpm_Event * event) if (ret != MOU_UNHANDLED) return ret; } + + p = g_list_previous (p); } - while (p != first); + while (p != NULL); return MOU_UNHANDLED; } @@ -1072,12 +1071,8 @@ dlg_select_widget (void *w) /* --------------------------------------------------------------------------------------------- */ -/** - * Set widget at top of widget list and make it current. - */ - -void -dlg_set_top_widget (void *w) +static void +dlg_set_top_or_bottom_widget (void *w, gboolean set_top) { Widget *widget = WIDGET (w); WDialog *h = widget->owner; @@ -1088,13 +1083,37 @@ dlg_set_top_widget (void *w) abort (); /* widget is not in dialog, this should not happen */ /* unfocus prevoius widget and focus current one before widget reordering */ - if (h->state == DLG_ACTIVE) + if (set_top && h->state == DLG_ACTIVE) do_select_widget (h, l, SELECT_EXACT); /* widget reordering */ h->widgets = g_list_remove_link (h->widgets, l); - h->widgets = g_list_concat (h->widgets, l); - h->current = l; + if (set_top) + h->widgets = g_list_concat (h->widgets, l); + else + h->widgets = g_list_concat (l, h->widgets); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Set widget at top of widget list and make it current. + */ + +void +dlg_set_top_widget (void *w) +{ + dlg_set_top_or_bottom_widget (w, TRUE); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Set widget at bottom of widget list. + */ + +void +dlg_set_bottom_widget (void *w) +{ + dlg_set_top_or_bottom_widget (w, FALSE); } /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/widget/dialog.h b/lib/widget/dialog.h index 97a6cf5f4..25b672db7 100644 --- a/lib/widget/dialog.h +++ b/lib/widget/dialog.h @@ -171,6 +171,7 @@ void dlg_stop (WDialog * h); /* Widget selection */ void dlg_select_widget (void *w); void dlg_set_top_widget (void *w); +void dlg_set_bottom_widget (void *w); void dlg_one_up (WDialog * h); void dlg_one_down (WDialog * h); gboolean dlg_focus (WDialog * h); diff --git a/lib/widget/menu.c b/lib/widget/menu.c index b6e9ad531..2cbe96a16 100644 --- a/lib/widget/menu.c +++ b/lib/widget/menu.c @@ -309,6 +309,10 @@ menubar_finish (WMenuBar * menubar) w->lines = 1; widget_want_hotkey (w, 0); + /* Move the menubar to the bottom so that widgets displayed on top of + * an "invisible" menubar get the first chance to respond to mouse events. */ + dlg_set_bottom_widget (w); + dlg_select_by_id (w->owner, menubar->previous_widget); do_refresh (); } @@ -716,15 +720,7 @@ menubar_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) unsigned int selected; selected = menubar_get_menu_by_x_coord (menubar, event->x); - - if (!menubar->is_active) - { - /* menu bar is not active -- activate it */ - menubar->previous_widget = dlg_get_current_widget_id (w->owner); - menubar->is_active = TRUE; - dlg_select_widget (w); - } - + menubar_activate (menubar, TRUE, selected); menubar_remove (menubar); /* if already shown */ menubar_drop (menubar, selected); } @@ -1019,7 +1015,10 @@ menubar_activate (WMenuBar * menubar, gboolean dropped, int which) menubar->selected = (guint) which; menubar->previous_widget = dlg_get_current_widget_id (w->owner); - dlg_select_widget (w); + + /* Bring it to the top so it receives all mouse events before any other widget. + * See also comment in menubar_finish(). */ + dlg_set_top_widget (w); } } diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index fad964c28..975f12224 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -1575,42 +1575,6 @@ midnight_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void } } -/* --------------------------------------------------------------------------------------------- */ - -static int -midnight_event (Gpm_Event * event, void *data) -{ - Widget *wh = WIDGET (data); - int ret = MOU_UNHANDLED; - - if (event->y == wh->y + 1) - { - /* menubar */ - if (menubar_visible || the_menubar->is_active) - ret = WIDGET (the_menubar)->mouse (event, the_menubar); - else - { - Widget *w; - - w = get_panel_widget (0); - if (w->mouse != NULL) - ret = w->mouse (event, w); - - if (ret == MOU_UNHANDLED) - { - w = get_panel_widget (1); - if (w->mouse != NULL) - ret = w->mouse (event, w); - } - - if (ret == MOU_UNHANDLED) - ret = WIDGET (the_menubar)->mouse (event, the_menubar); - } - } - - return ret; -} - /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -1793,8 +1757,8 @@ do_nc (void) edit_stack_init (); #endif - midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback, - midnight_event, "[main]", NULL, DLG_NONE); + midnight_dlg = dlg_create (FALSE, 0, 0, LINES, COLS, dialog_colors, midnight_callback, NULL, + "[main]", NULL, DLG_NONE); /* Check if we were invoked as an editor or file viewer */ if (mc_global.mc_run_mode != MC_RUN_FULL)