Ticket #4256: 0001-Scrollbox-with-skin-support.patch

File 0001-Scrollbox-with-skin-support.patch, 21.7 KB (added by psprint, 2 years ago)

Skin support for arrow and other chars. Implement the middle type from the example png.

  • doc/man/mc.1.in

    From acdce880794c375224aed939cd32cf92895866bb Mon Sep 17 00:00:00 2001
    From: Sebastian Gniazdowski <sgniazdowski@gmail.com>
    Date: Tue, 14 Dec 2021 14:59:57 +0100
    Subject: [PATCH] Scrollbox with skin support
    
    ---
     doc/man/mc.1.in          |   3 +
     lib/skin/lines.c         |  17 +++-
     lib/tty/tty.h            |   6 ++
     lib/widget.h             |   1 +
     lib/widget/Makefile.am   |   1 +
     lib/widget/listbox.c     |  50 ++----------
     lib/widget/listbox.h     |   3 +-
     lib/widget/scrollbar.c   | 165 +++++++++++++++++++++++++++++++++++++++
     lib/widget/scrollbar.h   |  37 +++++++++
     src/filemanager/layout.c |  11 ++-
     src/filemanager/layout.h |   1 +
     src/filemanager/panel.c  |  25 +++++-
     src/filemanager/panel.h  |   1 +
     src/setup.c              |   1 +
     14 files changed, 272 insertions(+), 50 deletions(-)
     create mode 100644 lib/widget/scrollbar.c
     create mode 100644 lib/widget/scrollbar.h
    
    diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in
    index ec473568e..3e4012333 100644
    a b Enabled by default. 
    19861986.I Show free space. 
    19871987If enabled, free space and total space of current file system is shown 
    19881988at the bottom frame of panel. Enabled by default. 
     1989.PP 
     1990.I Panel scrollbars. 
     1991Show scrollbars in main panels (on the right side). Enabled by default. 
    19891992.\"NODE "    Panel options" 
    19901993.SH "    Panel options" 
    19911994.B Main panel options 
  • lib/skin/lines.c

    diff --git a/lib/skin/lines.c b/lib/skin/lines.c
    index ddf13c451..8b71f63b2 100644
    a b mc_skin_lines_load_frm (mc_skin_t * mc_skin, const char *name) 
    6060void 
    6161mc_skin_lines_parse_ini_file (mc_skin_t * mc_skin) 
    6262{ 
     63    int ch; 
     64 
     65 
     66    ch = mc_skin_lines_load_frm (mc_skin, "uparrow"); 
     67    mc_tty_frm[MC_TTY_FRM_UP_ARROW] = ch == ' ' ? L'▲' : ch; 
     68    ch = mc_skin_lines_load_frm (mc_skin, "uparrowempty"); 
     69    mc_tty_frm[MC_TTY_FRM_UP_ARROW_EMPTY] = ch == ' ' ? L'△' : ch; 
     70    ch = mc_skin_lines_load_frm (mc_skin, "dnarrow"); 
     71    mc_tty_frm[MC_TTY_FRM_DN_ARROW] = ch == ' ' ? L'▼' : ch; 
     72    ch = mc_skin_lines_load_frm (mc_skin, "dnarrowempty"); 
     73    mc_tty_frm[MC_TTY_FRM_DN_ARROW_EMPTY] = ch == ' ' ? L'▽' : ch; 
     74    ch = mc_skin_lines_load_frm (mc_skin, "box"); 
     75    mc_tty_frm[MC_TTY_FRM_BOX] = ch == ' ' ? L'▓' : ch; 
     76    ch = mc_skin_lines_load_frm (mc_skin, "uparrow"); 
     77    mc_tty_frm[MC_TTY_FRM_BOX_LIGHT] = ch == ' ' ? L'░' : ch; 
     78 
    6379    if (mc_global.tty.slow_terminal) 
    6480        mc_skin_hardcoded_space_lines (mc_skin); 
    6581    else if (mc_global.tty.ugly_line_drawing) 
    mc_skin_lines_parse_ini_file (mc_skin_t * mc_skin) 
    90106    mc_tty_frm[MC_TTY_FRM_DLEFTMIDDLE] = mc_skin_lines_load_frm (mc_skin, "dleftmiddle"); 
    91107    mc_tty_frm[MC_TTY_FRM_DRIGHTMIDDLE] = mc_skin_lines_load_frm (mc_skin, "drightmiddle"); 
    92108} 
    93  
    94109/* --------------------------------------------------------------------------------------------- */ 
  • lib/tty/tty.h

    diff --git a/lib/tty/tty.h b/lib/tty/tty.h
    index 90cbbc6c9..780907187 100644
    a b typedef enum 
    5454    MC_TTY_FRM_DLEFTMIDDLE, 
    5555    MC_TTY_FRM_DRIGHTMIDDLE, 
    5656 
     57    MC_TTY_FRM_UP_ARROW, 
     58    MC_TTY_FRM_UP_ARROW_EMPTY, 
     59    MC_TTY_FRM_DN_ARROW, 
     60    MC_TTY_FRM_DN_ARROW_EMPTY, 
     61    MC_TTY_FRM_BOX, 
     62    MC_TTY_FRM_BOX_LIGHT, 
    5763    MC_TTY_FRM_MAX 
    5864} mc_tty_frm_t; 
    5965 
  • lib/widget.h

    diff --git a/lib/widget.h b/lib/widget.h
    index e3bb5cac2..89104c784 100644
    a b typedef struct WGroup WGroup; 
    2929#include "lib/widget/gauge.h" 
    3030#include "lib/widget/groupbox.h" 
    3131#include "lib/widget/label.h" 
     32#include "lib/widget/scrollbar.h" 
    3233#include "lib/widget/listbox.h" 
    3334#include "lib/widget/menu.h" 
    3435#include "lib/widget/radio.h" 
  • lib/widget/Makefile.am

    diff --git a/lib/widget/Makefile.am b/lib/widget/Makefile.am
    index 90f023bbc..c45398d35 100644
    a b libmcwidget_la_SOURCES = \ 
    2424        quick.c quick.h \ 
    2525        radio.c radio.h \ 
    2626        rect.c rect.h \ 
     27        scrollbar.c scrollbar.h \ 
    2728        widget-common.c widget-common.h \ 
    2829        wtools.c wtools.h 
    2930 
  • lib/widget/listbox.c

    diff --git a/lib/widget/listbox.c b/lib/widget/listbox.c
    index 198193e4a..460dbee66 100644
    a b listbox_entry_free (void *data) 
    8585 
    8686/* --------------------------------------------------------------------------------------------- */ 
    8787 
    88 static void 
    89 listbox_drawscroll (WListbox * l) 
    90 { 
    91     Widget *w = WIDGET (l); 
    92     int max_line = w->lines - 1; 
    93     int line = 0; 
    94     int i; 
    95     int length; 
    96  
    97     /* Are we at the top? */ 
    98     widget_gotoyx (w, 0, w->cols); 
    99     if (l->top == 0) 
    100         tty_print_one_vline (TRUE); 
    101     else 
    102         tty_print_char ('^'); 
    103  
    104     length = g_queue_get_length (l->list); 
    105  
    106     /* Are we at the bottom? */ 
    107     widget_gotoyx (w, max_line, w->cols); 
    108     if (l->top + w->lines == length || w->lines >= length) 
    109         tty_print_one_vline (TRUE); 
    110     else 
    111         tty_print_char ('v'); 
    112  
    113     /* Now draw the nice relative pointer */ 
    114     if (!g_queue_is_empty (l->list)) 
    115         line = 1 + ((l->pos * (w->lines - 2)) / length); 
    116  
    117     for (i = 1; i < max_line; i++) 
    118     { 
    119         widget_gotoyx (w, i, w->cols); 
    120         if (i != line) 
    121             tty_print_one_vline (TRUE); 
    122         else 
    123             tty_print_char ('*'); 
    124     } 
    125 } 
    126  
    127 /* --------------------------------------------------------------------------------------------- */ 
    128  
    12988static void 
    13089listbox_draw (WListbox * l, gboolean focused) 
    13190{ 
    listbox_draw (WListbox * l, gboolean focused) 
    183142 
    184143    l->cursor_y = sel_line; 
    185144 
    186     if (l->scrollbar && length > w->lines) 
     145    if (l->draw_scrollbar) 
    187146    { 
    188147        tty_setcolor (normalc); 
    189         listbox_drawscroll (l); 
     148        scrollbar_set_state (l->scrollbar, w->y - 1, w->x + w->cols, w->lines + 2, g_queue_get_length (l->list), w->lines, l->top); 
     149        WIDGET (l->scrollbar)->callback (WIDGET (l->scrollbar), NULL, MSG_DRAW, 0, NULL); 
    190150    } 
    191151} 
    192152 
    listbox_run_hotkey (WListbox * l, int pos) 
    440400static inline void 
    441401listbox_destroy (WListbox * l) 
    442402{ 
     403    widget_destroy (WIDGET (l->scrollbar)); 
    443404    listbox_remove_list (l); 
    444405} 
    445406 
    listbox_new (int y, int x, int height, int width, gboolean deletable, lcback_fn 
    564525    l->deletable = deletable; 
    565526    l->callback = callback; 
    566527    l->allow_duplicates = TRUE; 
    567     l->scrollbar = !mc_global.tty.slow_terminal; 
     528    l->draw_scrollbar = !mc_global.tty.slow_terminal; 
     529    l->scrollbar = scrollbar_new (y, x + width - 1, height, TRUE); 
    568530 
    569531    return l; 
    570532} 
  • lib/widget/listbox.h

    diff --git a/lib/widget/listbox.h b/lib/widget/listbox.h
    index 8b2236eff..96dd4afc4 100644
    a b typedef struct WListbox 
    4848    int pos;                    /* The current element displayed */ 
    4949    int top;                    /* The first element displayed */ 
    5050    gboolean allow_duplicates;  /* Do we allow duplicates on the list? */ 
    51     gboolean scrollbar;         /* Draw a scrollbar? */ 
     51    gboolean draw_scrollbar;    /* Draw a scrollbar? */ 
     52    WScrollbar *scrollbar;      /* Scrollbar widget */ 
    5253    gboolean deletable;         /* Can list entries be deleted? */ 
    5354    lcback_fn callback;         /* The callback function */ 
    5455    int cursor_x, cursor_y;     /* Cache the values */ 
  • new file lib/widget/scrollbar.c

    diff --git a/lib/widget/scrollbar.c b/lib/widget/scrollbar.c
    new file mode 100644
    index 000000000..8b68d0893
    - +  
     1/* 
     2   Widgets for the Midnight Commander 
     3 
     4   Copyright (C) 2021 
     5   Free Software Foundation, Inc. 
     6 
     7   This file is part of the Midnight Commander. 
     8 
     9   The Midnight Commander is free software: you can redistribute it 
     10   and/or modify it under the terms of the GNU General Public License as 
     11   published by the Free Software Foundation, either version 3 of the License, 
     12   or (at your option) any later version. 
     13 
     14   The Midnight Commander is distributed in the hope that it will be useful, 
     15   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     17   GNU General Public License for more details. 
     18 
     19   You should have received a copy of the GNU General Public License 
     20   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
     21 */ 
     22 
     23/** \file scrollbar.c 
     24 *  \brief Source: WScrollbar widget 
     25 */ 
     26 
     27#include <config.h> 
     28 
     29#include <stdarg.h> 
     30#include <stdlib.h> 
     31#include <string.h> 
     32 
     33#include "lib/global.h" 
     34 
     35#include "lib/tty/tty.h" 
     36#include "lib/tty/color.h" 
     37#include "lib/skin.h" 
     38#include "lib/strutil.h" 
     39#include "lib/widget.h" 
     40 
     41/*** global variables ****************************************************************************/ 
     42 
     43/*** file scope macro definitions ****************************************************************/ 
     44 
     45/*** file scope type declarations ****************************************************************/ 
     46 
     47/*** file scope variables ************************************************************************/ 
     48 
     49/*** file scope functions ************************************************************************/ 
     50 
     51static cb_ret_t 
     52scrollbar_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) 
     53{ 
     54    WScrollbar *s = SCROLLBAR (w); 
     55    switch (msg) 
     56    { 
     57    case MSG_RESIZE: 
     58        { 
     59            widget_default_callback (w, NULL, MSG_RESIZE, 0, data); 
     60            return MSG_HANDLED; 
     61        } 
     62 
     63    case MSG_DRAW: 
     64        { 
     65            int scrollbar_values_per_char; 
     66            int scrollbar_values_total; 
     67            int scrollbox_length; 
     68            int top_possibilities; 
     69            int scrollbox_pos_start; 
     70            int i; 
     71            int visible_scrollbar_position, scrollbar_position; 
     72 
     73            if (s->data_items <= s->data_visible_items) 
     74                return MSG_HANDLED; 
     75 
     76            /* Are we at the top? */ 
     77            widget_gotoyx (w, 1, 0); 
     78            visible_scrollbar_position = s->data_visible_start_position / 2 * 2; 
     79            if (visible_scrollbar_position == 0) 
     80                tty_print_char (mc_global.tty.ugly_line_drawing ?' ':mc_tty_frm[MC_TTY_FRM_UP_ARROW_EMPTY]); 
     81            else 
     82                tty_print_char (mc_global.tty.ugly_line_drawing ?'^':mc_tty_frm[MC_TTY_FRM_UP_ARROW]); 
     83 
     84            /* Are we at the bottom? */ 
     85            widget_gotoyx (w, w->lines - 2, 0); 
     86            if (visible_scrollbar_position + s->data_visible_items >= s->data_items-1) 
     87                tty_print_char (mc_global.tty.ugly_line_drawing ?' ':mc_tty_frm[MC_TTY_FRM_DN_ARROW_EMPTY]); 
     88            else 
     89                tty_print_char (mc_global.tty.ugly_line_drawing ?' ':mc_tty_frm[MC_TTY_FRM_DN_ARROW]); 
     90 
     91            if (w->lines <= 2)           /* there is no enough space for actual scrollbar */ 
     92                return MSG_HANDLED; 
     93 
     94            /* Now draw the nice relative pointer */ 
     95            scrollbar_values_per_char = (s->has_subchars && !mc_global.tty.ugly_line_drawing ? 2 : 1); 
     96            scrollbar_values_total = (w->lines - 4) * scrollbar_values_per_char; 
     97            scrollbox_length = MAX (1, scrollbar_values_total * s->data_visible_items / s->data_items) / 2 * 2; 
     98            top_possibilities = s->data_items - s->data_visible_items + 1; 
     99            scrollbox_pos_start = (2 * visible_scrollbar_position*(scrollbar_values_total-scrollbox_length) 
     100                    / (top_possibilities - 1) + 1) / 2; 
     101            scrollbox_pos_start *= 2; 
     102            scrollbox_pos_start /= 2; 
     103 
     104            for (i = 0; i < w->lines - 4; i++) 
     105            { 
     106                widget_gotoyx (w, i + 2, 0); 
     107                scrollbar_position = i * scrollbar_values_per_char / 2 * 2; 
     108 
     109                if (scrollbar_position >= scrollbox_pos_start 
     110                        && scrollbar_position + scrollbar_values_per_char <= 
     111                             scrollbox_pos_start + scrollbox_length+1) 
     112                    tty_print_char (mc_global.tty.ugly_line_drawing ?'#':mc_tty_frm[MC_TTY_FRM_BOX]); 
     113                else 
     114                    tty_print_char (mc_global.tty.ugly_line_drawing ?' ':mc_tty_frm[MC_TTY_FRM_BOX_LIGHT]); 
     115            } 
     116 
     117            return MSG_HANDLED; 
     118        } 
     119 
     120    default: 
     121        return widget_default_callback (w, sender, msg, parm, data); 
     122    } 
     123} 
     124 
     125/* --------------------------------------------------------------------------------------------- */ 
     126/*** public functions ****************************************************************************/ 
     127/* --------------------------------------------------------------------------------------------- */ 
     128 
     129WScrollbar * 
     130scrollbar_new (int y, int x, int lines, gboolean has_subchars) 
     131{ 
     132    WScrollbar *scrollbar; 
     133    Widget *w; 
     134 
     135    scrollbar = g_new (WScrollbar, 1); 
     136    w = WIDGET (scrollbar); 
     137    widget_init (w, y, x, lines, 1, scrollbar_callback, NULL); 
     138 
     139    scrollbar->has_subchars = has_subchars; 
     140    scrollbar->data_items = 0; 
     141    scrollbar->data_visible_items = 0; 
     142    scrollbar->data_visible_start_position = 0; 
     143 
     144    return scrollbar; 
     145} 
     146 
     147/* --------------------------------------------------------------------------------------------- */ 
     148 
     149void 
     150scrollbar_set_state(WScrollbar * scrollbar, int y, int x, int lines, int data_length, 
     151                    int data_visible_length, int data_position) 
     152{ 
     153    Widget *w = WIDGET (scrollbar); 
     154 
     155    w->y = y; 
     156    w->x = x; 
     157    w->lines = lines; 
     158    scrollbar->data_items = data_length; 
     159    scrollbar->data_visible_items = data_visible_length; 
     160    scrollbar->data_visible_start_position = data_position; 
     161 
     162    widget_draw (w); 
     163} 
     164 
     165/* --------------------------------------------------------------------------------------------- */ 
  • new file lib/widget/scrollbar.h

    diff --git a/lib/widget/scrollbar.h b/lib/widget/scrollbar.h
    new file mode 100644
    index 000000000..f0ee5b2a1
    - +  
     1 
     2/** \file scrollbar.h 
     3 *  \brief Header: WScrollbar widget 
     4 */ 
     5 
     6#ifndef MC__WIDGET_SCROLLBAR_H 
     7#define MC__WIDGET_SCROLLBAR_H 
     8 
     9/*** typedefs(not structures) and defined constants **********************************************/ 
     10 
     11#define SCROLLBAR(x) ((WScrollbar *)(x)) 
     12 
     13/*** enums ***************************************************************************************/ 
     14 
     15/*** structures declarations (and typedefs of structures)*****************************************/ 
     16 
     17typedef struct 
     18{ 
     19    Widget widget; 
     20    gboolean has_subchars;   /* if uses sub-characters (2 states per character). Also, this 
     21                                turns off scrollbar background */ 
     22    int data_items;         /* how many items are in the background data */ 
     23    int data_visible_items; /* how many items from data are actually visible */ 
     24    int data_visible_start_position;       /* position of first visible item in data */ 
     25} WScrollbar; 
     26 
     27/*** global variables defined in .c file *********************************************************/ 
     28 
     29/*** declarations of public functions ************************************************************/ 
     30 
     31WScrollbar *scrollbar_new (int y, int x, int height, gboolean has_subchars); 
     32void scrollbar_set_state (WScrollbar * scrollbar, int y, int x, int lines, int data_length, 
     33                          int data_visible_length, int data_position); 
     34 
     35/*** inline functions ****************************************************************************/ 
     36 
     37#endif /* MC__WIDGET_SCROLLBAR_H */ 
  • src/filemanager/layout.c

    diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c
    index 9118c7848..ce8db9d77 100644
    a b gboolean xterm_title = TRUE; 
    100100/* Set to show free space on device assigned to current directory */ 
    101101gboolean free_space = TRUE; 
    102102 
     103/* Set to show scrollbars on main panels */ 
     104gboolean panel_scrollbars = TRUE; 
     105 
    103106/* The starting line for the output of the subprogram */ 
    104107int output_start_y = 0; 
    105108 
    typedef struct 
    133136    gboolean message_visible; 
    134137    gboolean xterm_title; 
    135138    gboolean free_space; 
     139    gboolean panel_scrollbars; 
    136140    int output_lines; 
    137141} layout_t; 
    138142 
    static struct 
    176180    { N_("&Keybar visible"), &mc_global.keybar_visible, NULL }, 
    177181    { N_("H&intbar visible"), &mc_global.message_visible, NULL }, 
    178182    { N_("&XTerm window title"), &xterm_title, NULL }, 
    179     { N_("&Show free space"), &free_space, NULL } 
     183    { N_("&Show free space"), &free_space, NULL }, 
     184    { N_("&Panel scrollbars"), &panel_scrollbars, NULL } 
    180185    /* *INDENT-ON* */ 
    181186}; 
    182187 
    layout_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * 
    466471                xterm_title = check_options[5].widget->state; 
    467472            else if (sender == WIDGET (check_options[6].widget)) 
    468473                free_space = check_options[6].widget->state; 
     474            else if (sender == WIDGET (check_options[7].widget)) 
     475                panel_scrollbars = check_options[7].widget->state; 
    469476            else 
    470477                ok = FALSE; 
    471478 
    layout_save (void) 
    678685    old_layout.message_visible = mc_global.message_visible; 
    679686    old_layout.xterm_title = xterm_title; 
    680687    old_layout.free_space = free_space; 
     688    old_layout.panel_scrollbars = panel_scrollbars; 
    681689    old_layout.output_lines = -1; 
    682690 
    683691    _output_lines = output_lines; 
    layout_restore (void) 
    696704    mc_global.message_visible = old_layout.message_visible; 
    697705    xterm_title = old_layout.xterm_title; 
    698706    free_space = old_layout.free_space; 
     707    panel_scrollbars = old_layout.panel_scrollbars; 
    699708    output_lines = old_layout.output_lines; 
    700709 
    701710    panels_layout = old_panels_layout; 
  • src/filemanager/layout.h

    diff --git a/src/filemanager/layout.h b/src/filemanager/layout.h
    index 2566cfa32..152ee5210 100644
    a b extern gboolean menubar_visible; 
    4646extern int output_start_y; 
    4747extern gboolean xterm_title; 
    4848extern gboolean free_space; 
     49extern gboolean panel_scrollbars; 
    4950extern gboolean nice_rotating_dash; 
    5051 
    5152extern int ok_to_refresh; 
  • src/filemanager/panel.c

    diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c
    index b91f303bb..21afb3bf7 100644
    a b show_dir (const WPanel * panel) 
    12571257{ 
    12581258    const Widget *w = CONST_WIDGET (panel); 
    12591259    gchar *tmp; 
     1260    int lines; 
    12601261 
    12611262    set_colors (panel); 
    12621263    tty_draw_box (w->y, w->x, w->lines, w->cols, FALSE); 
     1264    lines = panel_lines (panel); 
    12631265 
    12641266    if (panels_options.show_mini_info) 
    12651267    { 
    12661268        int y; 
    12671269 
    1268         y = panel_lines (panel) + 2; 
     1270        y = lines + 2; 
    12691271 
    12701272        widget_gotoyx (w, y, 0); 
    12711273        tty_print_alt_char (ACS_LTEE, FALSE); 
    show_dir (const WPanel * panel) 
    12731275        tty_print_alt_char (ACS_RTEE, FALSE); 
    12741276    } 
    12751277 
     1278    if (panel_scrollbars) { 
     1279        scrollbar_set_state (panel->scrollbar, w->y + 1, w->x + w->cols - 1, lines + 2, panel->dir.len, 
     1280                             lines * panel->list_cols, panel->top_file); 
     1281    } 
     1282 
    12761283    widget_gotoyx (w, 0, 1); 
    12771284    tty_print_string (panel_history_prev_item_char); 
    12781285 
    show_dir (const WPanel * panel) 
    13131320    { 
    13141321        if (panel->marked == 0) 
    13151322        { 
    1316             /* Show size of curret file in the bottom of panel */ 
     1323            /* Show size of current file in the bottom of panel */ 
    13171324            if (S_ISREG (panel->dir.list[panel->selected].st.st_mode)) 
    13181325            { 
    13191326                char buffer[BUF_SMALL]; 
    panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d 
    36493656        mc_event_add (h->event_group, MCEVENT_HISTORY_LOAD, panel_load_history, w, NULL); 
    36503657        /* subscribe to "history_save" event */ 
    36513658        mc_event_add (h->event_group, MCEVENT_HISTORY_SAVE, panel_save_history, w, NULL); 
     3659        panel->scrollbar = scrollbar_new (w->y + 1, w->x + w->cols - 1, w->lines, FALSE); 
     3660        return MSG_HANDLED; 
     3661 
     3662    case MSG_RESIZE: 
     3663        widget_default_callback (w, NULL, MSG_RESIZE, 0, data); 
     3664        if (panel->scrollbar != NULL) 
     3665            WIDGET (panel->scrollbar)->callback (WIDGET (panel->scrollbar), NULL, MSG_RESIZE, 0, NULL); 
    36523666        return MSG_HANDLED; 
    36533667 
    36543668    case MSG_DRAW: 
    36553669        /* Repaint everything, including frame and separator */ 
    36563670        widget_erase (w); 
    36573671        show_dir (panel); 
     3672        mini_info_separator (panel); 
    36583673        panel_print_header (panel); 
    36593674        adjust_top_file (panel); 
    36603675        paint_dir (panel); 
    3661         mini_info_separator (panel); 
    36623676        display_mini_info (panel); 
     3677 
     3678        if (panel_scrollbars) 
     3679            WIDGET (panel->scrollbar)->callback (WIDGET (panel->scrollbar), NULL, MSG_DRAW, 0, NULL); 
     3680 
    36633681        panel->dirty = FALSE; 
    36643682        return MSG_HANDLED; 
    36653683 
    panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d 
    37073725        mc_event_del (h->event_group, MCEVENT_HISTORY_LOAD, panel_load_history, w); 
    37083726        /* unsubscribe from "history_save" event */ 
    37093727        mc_event_del (h->event_group, MCEVENT_HISTORY_SAVE, panel_save_history, w); 
     3728        widget_destroy (WIDGET (panel->scrollbar)); 
    37103729        panel_destroy (panel); 
    37113730        free_my_statfs (); 
    37123731        return MSG_HANDLED; 
  • src/filemanager/panel.h

    diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h
    index 039950486..3270b371a 100644
    a b typedef struct 
    105105 
    106106    dir_list dir;               /* Directory contents */ 
    107107    struct stat dir_stat;       /* Stat of current dir: used by execute () */ 
     108    WScrollbar *scrollbar;      /* scrollbar of panel */ 
    108109 
    109110    vfs_path_t *cwd_vpath;      /* Current Working Directory */ 
    110111    vfs_path_t *lwd_vpath;      /* Last Working Directory */ 
  • src/setup.c

    diff --git a/src/setup.c b/src/setup.c
    index 7fdabdc01..3b926172f 100644
    a b static const struct 
    274274    { "command_prompt", &command_prompt }, 
    275275    { "menubar_visible", &menubar_visible }, 
    276276    { "free_space", &free_space }, 
     277    { "panel_scrollbars", &panel_scrollbars }, 
    277278    { "horizontal_split", &panels_layout.horizontal_split }, 
    278279    { "vertical_equal", &panels_layout.vertical_equal }, 
    279280    { "horizontal_equal", &panels_layout.horizontal_equal },