diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 49eea8730..bf4b30385 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.395 $ $NHDT-Date: 1596785362 2020/08/07 07:29:22 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.398 $ $NHDT-Date: 1605618309 2020/11/17 13:05:09 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "October 2, 2020 +.ds f2 "November 16, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4241,8 +4241,33 @@ If NetHack can, it should display an opening splash screen when it starts up (default yes). .lp statuslines Number of lines for traditional below-the-map status display. -Acceptable values are 2 and 3 (default is 2). -Curses and tty interfaces only. +Acceptable values are \f(CR2\fP and \f(CR3\fP (default is \f(CR2\fP). +.lp "" +For \f(CR3\fP, the \f(CRtty\fP interface moves some fields around and +mainly shows status conditions on their own line. +A display capable of showing at least 25 lines is recommended. +The value can be toggled back and forth during the game with the \(oqO\(cq +command. +.lp "" +The \f(CRcurses\fP interface does likewise if the +.op align_status +option is set to \fItop\fP or \fIbottom\fP but ignores +.op statuslines +when set to \fIleft\fP or \fIright\fP. +.lp "" +The \f(CRQt\fP interface already displays more than 3 lines for status +so uses the +.op statuslines +value differently. +A value of \f(CR3\fP renders status in the \f(CRQt\fP interface's +original format, with the status window spread out vertically. +A value of \f(CR2\fP makes status be slightly condensed, moving some +fields to different lines to eliminate one whole line, reducing the +height needed. +For \f(CRQt\fP, +.op statuslines +can only be set in the configuration file or via NETHACKOPTIONS, not +with the \(oqO\(cq command. .lp "term_cols\ \ \fIand\fP" .lp term_rows Curses interface only. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 00154f042..df603a3ae 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{October 2, 2020} +\date{November 16, 2020} \maketitle @@ -4621,8 +4621,36 @@ it starts up (default yes). %.lp \item[\ib{statuslines}] Number of lines for traditional below-the-map status display. -Acceptable values are 2 and 3 (default is 2). -Curses and tty interfaces only. +Acceptable values are {\tt 2} and {\tt 3} (default is {\tt 2}). + +%.lp "" +For {\tt 3}, the {\tt tty} interface moves some fields around and +mainly shows status conditions on their own line. +A display capable of showing at least 25 lines is recommended. +The value can be toggled back and forth during the game with the `O' +command. + +%.lp "" +The {\tt curses} interface does likewise if the +{\it align\verb+_+status\/} +option is set to {\it top\/} or {\it bottom\/} but ignores +{\it statuslines\/} +when set to {\it left\/} or {\it right}. + +%.lp "" +The {\tt Qt} interface already displays more than 3 lines for status +so uses the +{\it statuslines\/} +value differently. +A value of {\tt 3} renders status in the {\tt Qt} interface's +original format, with the status window spread out vertically. +A value of {\tt 2} makes status be slightly condensed, moving some +fields to different lines to eliminate one whole line, reducing the +height needed. +For {\tt Qt}, +{\it statuslines\/} +can only be set in the configuration file or via NETHACKOPTIONS, not +with the `O' command. %.lp \item[\ib{term\verb+_+cols} {\normalfont and}] %.lp diff --git a/include/optlist.h b/include/optlist.h index 12b9f3a47..5bc7ec31e 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -425,13 +425,8 @@ pfx_##a, NHOPTC(statushilites, 20, opt_in, set_in_config, Yes, Yes, Yes, No, NoAlias, "highlight control") #endif -#ifdef CURSES_GRAPHICS NHOPTC(statuslines, 20, opt_in, set_in_game, No, Yes, No, No, NoAlias, - "2 or 3 lines for horizontal (bottom or top) status display") -#else - NHOPTC(statuslines, 20, opt_in, set_in_config, No, Yes, No, No, NoAlias, "2 or 3 lines for status display") -#endif #ifdef WIN32 NHOPTC(subkeyvalue, 7, opt_in, set_in_config, No, Yes, Yes, No, NoAlias, "override keystroke value") diff --git a/src/options.c b/src/options.c index 8172cc398..1b946f29d 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1603666043 2020/10/25 22:47:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.478 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1605618310 2020/11/17 13:05:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.480 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3381,9 +3381,9 @@ char *op; itmp = atoi(op); } if (itmp < 2 || itmp > 3) { - config_error_add("'%s' requires a value of 2 or 3", - allopt[optidx].name); - retval = optn_err; + config_error_add("'%s:%s' is invalid; must be 2 or 3", + allopt[optidx].name, op); + retval = optn_silenterr; } else { iflags.wc2_statuslines = itmp; if (!g.opt_initial) @@ -4212,13 +4212,9 @@ char *op; if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE)) != empty_optstr) { + nmcpy(g.chosen_windowtype, op, WINTYPELEN); if (!iflags.windowtype_deferred) { - char buf[WINTYPELEN]; - - nmcpy(buf, op, WINTYPELEN); - choose_windows(buf); - } else { - nmcpy(g.chosen_windowtype, op, WINTYPELEN); + choose_windows(g.chosen_windowtype); } } else return optn_err; diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 3a64002ee..7969fa5e8 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -167,6 +167,11 @@ void NetHackQtBind::qt_init_nhwindows(int* argc, char** argv) // This nethack engine feature should be moved into windowport API nt_kbhit = NetHackQtBind::qt_kbhit; #endif + +#ifndef DYNAMIC_STATUSLINES + // 'statuslines' option can be set in config file but not via 'O' + set_wc2_option_mod_status(WC2_STATUSLINES, set_gameview); +#endif } int NetHackQtBind::qt_kbhit() @@ -443,7 +448,7 @@ int NetHackQtBind::qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list) void NetHackQtBind::qt_update_inventory() { if (main) - main->updateInventory(); + main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet if (g.program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, false); @@ -820,6 +825,18 @@ void NetHackQtBind::qt_outrip(winid wid, int how, time_t when) window->UseRIP(how, when); } +void NetHackQtBind::qt_preference_update(const char *optname) +{ +#ifdef DYNAMIC_STATUSLINES // leave disabled; redoStatus() doesn't work + if (!strcmp(optname, "statuslines")) { + // delete and recreate status window + main->redoStatus(); + } +#else + nhUse(optname); +#endif +} + char *NetHackQtBind::qt_getmsghistory(BOOLEAN_P init) { NetHackQtMessageWindow *window = main->GetMessageWindow(); @@ -954,7 +971,7 @@ struct window_procs Qt_procs = { | WC_ASCII_MAP | WC_TILED_MAP | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_POPUP_DIALOG | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN), - (WC2_HITPOINTBAR), + (WC2_HITPOINTBAR | WC2_STATUSLINES), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ nethack_qt_::NetHackQtBind::qt_init_nhwindows, nethack_qt_::NetHackQtBind::qt_player_selection, @@ -1012,8 +1029,7 @@ struct window_procs Qt_procs = { #else genl_outrip, #endif - genl_preference_update, - + nethack_qt_::NetHackQtBind::qt_preference_update, nethack_qt_::NetHackQtBind::qt_getmsghistory, nethack_qt_::NetHackQtBind::qt_putmsghistory, genl_status_init, diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index 295fafc57..bc3f2d647 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -81,6 +81,7 @@ public: static void qt_start_screen(); static void qt_end_screen(); + static void qt_preference_update(const char *optname); static char *qt_getmsghistory(BOOLEAN_P init); static void qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring); diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 3920a610f..b4f3822f9 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1148,6 +1148,24 @@ void NetHackQtMainWindow::layout() } } +#ifdef DYNAMIC_STATUSLINES // leave disabled; this doesn't work as intended +// called when 'statuslines' changes from 2 to 3 or vice versa; simpler to +// destroy and recreate the status window than to adjust existing fields +void NetHackQtMainWindow::redoStatus() +{ + NetHackQtStatusWindow *oldstatus = this->status; + if (!oldstatus) + return; // not ready yet? + this->status = new NetHackQtStatusWindow; + + if (!qt_compact_mode) + hsplitter->replaceWidget(2, this->status->Widget()); + + delete oldstatus; + ShowIfReady(); +} +#endif + void NetHackQtMainWindow::resizePaperDoll(bool showdoll) { #ifdef ENHANCED_PAPERDOLL diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index e998e63dd..d01d09558 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -52,6 +52,10 @@ public: void FuncAsCommand(int NDECL((*func))); // this is unconditional in case qt_main.h comes before qt_set.h void resizePaperDoll(bool); // ENHANCED_PAPERDOLL +#ifdef DYNAMIC_STATUSLINES + // called when 'statuslines' option has been changed + void redoStatus(); +#endif public slots: void doMenuItem(QAction *); diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 79b83c486..6c6bf9ce9 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -41,6 +41,8 @@ // (Caused by specifying min-width and max-width constraints in the // style sheets used to control color, but removing those constraints // causes the bar display to get screwed up.) +// There are separate icons for Satiated and Hungry, but Weak, Fainting, +// and Fainted all share the Hungry one when they should be different. // // TODO: // If/when status conditions become too wide for the status window, scale @@ -56,11 +58,12 @@ // judgement, for alignment and dungeon location) and "ignore" (don't // highlight, to suppress the bogus highlighting that currently happens // when toggling 'showexp' or 'showscore'). -// Maybe: if Alignment was moved to the characteristics line, giving that -// seven columns, then Time and Score could replace the one blank field -// on the HP line, giving it seven fields too and eliminating a whole -// line. [Maybe handle this dynamically, controlled via existing -// 'statuslines' 2 vs 3 that's currently a no-op for Qt?] +// The condensed display (statuslines:2; Alignment with Characteristics +// instead of with Conditions and Time,Score on HP,...,Gold row) has +// vertical padding when the Conditions row is empty, but having the +// first Cond come On or the last one go Off still makes the rest of +// status shift a little as if the padding (same size icon plus empty +// text label) was slightly taller than a regular Cond. // extern "C" { @@ -111,6 +114,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : score(this,"Score"), // if SCORE_ON_BOTL defined and 'showscore' option On /* last two rows: alignment followed by conditions (icons over text) */ align(this,"Alignment"), + blank2(this, ""), // used to prevent Conditions row from being empty hunger(this,""), encumber(this,""), stoned(this,"Stone"), // major conditions @@ -150,6 +154,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : p_chaotic = QPixmap(chaotic_xpm); p_neutral = QPixmap(neutral_xpm); p_lawful = QPixmap(lawful_xpm); + p_blank2 = QPixmap(blank_xpm); p_satiated = QPixmap(satiated_xpm); p_hungry = QPixmap(hungry_xpm); @@ -182,6 +187,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : cha.setIcon(p_cha); align.setIcon(p_neutral); + blank2.setIcon(p_blank2); // used for spacing when Conditions row is empty hunger.setIcon(p_hungry); encumber.setIcon(p_encumber[0]); @@ -210,60 +216,98 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : // set up last but shown first (above name) via layout below */ QHBoxLayout *hpbar = InitHitpointBar(); + // 'statuslines' takes a value of 2 or 3; we use 3 as a request to put + // Alignment in front of status conditions so that line is never empty + // and to show Time and/or Score on their own line which might be empty + boolean spreadout = (::iflags.wc2_statuslines != 2); + #if 1 //RLC name.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); dlevel.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QVBoxLayout *vbox = new QVBoxLayout(); vbox->setSpacing(0); - vbox->addLayout(hpbar); + vbox->addLayout(hpbar); // when 'hitpointbar' is enabled, it comes first vbox->addWidget(&name); vbox->addWidget(&dlevel); vbox->addWidget(&hline1); - QHBoxLayout *atr1box = new QHBoxLayout(); - atr1box->addWidget(&str); - atr1box->addWidget(&dex); - atr1box->addWidget(&con); - atr1box->addWidget(&intel); - atr1box->addWidget(&wis); - atr1box->addWidget(&cha); - vbox->addLayout(atr1box); + QHBoxLayout *charbox = new QHBoxLayout(); // Characteristics + charbox->addWidget(&str); + charbox->addWidget(&dex); + charbox->addWidget(&con); + charbox->addWidget(&intel); + charbox->addWidget(&wis); + charbox->addWidget(&cha); + if (!spreadout) { + // when condensed, include Alignment with Characteristics + charbox->addWidget(&align); + } + vbox->addLayout(charbox); vbox->addWidget(&hline2); - QHBoxLayout *atr2box = new QHBoxLayout(); - atr2box->addWidget(&hp); - atr2box->addWidget(&power); - atr2box->addWidget(&ac); - atr2box->addWidget(&level); - atr2box->addWidget(&blank1); // empty column #5 - atr2box->addWidget(&gold); - vbox->addLayout(atr2box); - vbox->addWidget(&hline3); - QHBoxLayout *timebox = new QHBoxLayout(); - timebox->addWidget(&time); - timebox->addWidget(&score); - vbox->addLayout(timebox); - QHBoxLayout *statbox = new QHBoxLayout(); - statbox->addWidget(&align); - statbox->addWidget(&hunger); - statbox->addWidget(&encumber); - statbox->addWidget(&stoned); - statbox->addWidget(&slimed); - statbox->addWidget(&strngld); - statbox->addWidget(&sick_fp); - statbox->addWidget(&sick_il); - statbox->addWidget(&stunned); - statbox->addWidget(&confused); - statbox->addWidget(&hallu); - statbox->addWidget(&blind); - statbox->addWidget(&deaf); - statbox->addWidget(&lev); - statbox->addWidget(&fly); - statbox->addWidget(&ride); - statbox->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + QHBoxLayout *statbox = new QHBoxLayout(); // core status fields + statbox->addWidget(&hp); + statbox->addWidget(&power); + statbox->addWidget(&ac); + statbox->addWidget(&level); + if (spreadout) { + // when not condensed, put a blank field in front of Gold; + // Time and Score will be shown on their own separate line + statbox->addWidget(&blank1); // empty column #5 of 6 + statbox->addWidget(&gold); + } else { + // when condensed, display Time and Score on HP,...,Gold row +#ifndef SCORE_ON_BOTL + statbox->addWidget(&blank1); // empty column #5 of 7 +#else + statbox->addWidget(&score); // usually empty column #5 +#endif + statbox->addWidget(&gold); // columns 6 and maybe empty 7 + statbox->addWidget(&time); + } vbox->addLayout(statbox); + vbox->addWidget(&hline3); // separtor before Time+Score or Conditions + if (spreadout) { + // when not condensed, put Time and Score on an extra row; since + // they're both optionally displayed, their row might be empty + // TODO? when neither will be shown, set their heights smaller + // and if either gets toggled On, set height back to normal + QHBoxLayout *timebox = new QHBoxLayout(); + timebox->addWidget(&time); + timebox->addWidget(&score); + vbox->addLayout(timebox); + } + QHBoxLayout *condbox = new QHBoxLayout(); // Conditions + if (spreadout) { + // when not condensed, include Alignment with Conditions to + // spread things out and also so that their row is never empty + condbox->addWidget(&align); + } else { + // otherwise place a padding widget on this row; it will be + // hidden if any Conditions are shown, or shown (with blank + // icon and empty text) when there aren't any, reserving + // space (the height of the row) for later conditions + condbox->addWidget(&blank2); + } + condbox->addWidget(&hunger); + condbox->addWidget(&encumber); + condbox->addWidget(&stoned); + condbox->addWidget(&slimed); + condbox->addWidget(&strngld); + condbox->addWidget(&sick_fp); + condbox->addWidget(&sick_il); + condbox->addWidget(&stunned); + condbox->addWidget(&confused); + condbox->addWidget(&hallu); + condbox->addWidget(&blind); + condbox->addWidget(&deaf); + condbox->addWidget(&lev); + condbox->addWidget(&fly); + condbox->addWidget(&ride); + condbox->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + vbox->addLayout(condbox); setLayout(vbox); #endif - connect(qt_settings,SIGNAL(fontChanged()),this,SLOT(doUpdate())); + connect(qt_settings, SIGNAL(fontChanged()), this, SLOT(doUpdate())); doUpdate(); } @@ -633,6 +677,9 @@ void NetHackQtStatusWindow::updateStats() wis.setLabel("Wis:", (long) ACURR(A_WIS)); cha.setLabel("Cha:", (long) ACURR(A_CHA)); + boolean spreadout = (::iflags.wc2_statuslines != 2); + int k = 0; // number of conditions shown + const char* hung=hu_stat[u.uhs]; if (hung[0]==' ') { hunger.hide(); @@ -640,7 +687,7 @@ void NetHackQtStatusWindow::updateStats() hunger.setIcon(u.uhs ? p_hungry : p_satiated); hunger.setLabel(hung); hunger.ForceResize(); - hunger.show(); + ++k, hunger.show(); } const char *enc = enc_stat[near_capacity()]; if (enc[0]==' ' || !enc[0]) { @@ -649,20 +696,20 @@ void NetHackQtStatusWindow::updateStats() encumber.setIcon(p_encumber[near_capacity() - 1]); encumber.setLabel(enc); encumber.ForceResize(); - encumber.show(); + ++k, encumber.show(); } - if (Stoned) stoned.show(); else stoned.hide(); - if (Slimed) slimed.show(); else slimed.hide(); - if (Strangled) strngld.show(); else strngld.hide(); + if (Stoned) ++k, stoned.show(); else stoned.hide(); + if (Slimed) ++k, slimed.show(); else slimed.hide(); + if (Strangled) ++k, strngld.show(); else strngld.hide(); if (Sick) { /* FoodPois or TermIll or both */ if (u.usick_type & SICK_VOMITABLE) { /* food poisoning */ - sick_fp.show(); + ++k, sick_fp.show(); } else { sick_fp.hide(); } if (u.usick_type & SICK_NONVOMITABLE) { /* terminally ill */ - sick_il.show(); + ++k, sick_il.show(); } else { sick_il.hide(); } @@ -670,16 +717,16 @@ void NetHackQtStatusWindow::updateStats() sick_fp.hide(); sick_il.hide(); } - if (Stunned) stunned.show(); else stunned.hide(); - if (Confusion) confused.show(); else confused.hide(); - if (Hallucination) hallu.show(); else hallu.hide(); - if (Blind) blind.show(); else blind.hide(); - if (Deaf) deaf.show(); else deaf.hide(); + if (Stunned) ++k, stunned.show(); else stunned.hide(); + if (Confusion) ++k, confused.show(); else confused.hide(); + if (Hallucination) ++k, hallu.show(); else hallu.hide(); + if (Blind) ++k, blind.show(); else blind.hide(); + if (Deaf) ++k, deaf.show(); else deaf.hide(); // flying is blocked when levitating, so Lev and Fly are mutually exclusive - if (Levitation) lev.show(); else lev.hide(); - if (Flying) fly.show(); else fly.hide(); - if (u.usteed) ride.show(); else ride.hide(); + if (Levitation) ++k, lev.show(); else lev.hide(); + if (Flying) ++k, fly.show(); else fly.hide(); + if (u.usteed) ++k, ride.show(); else ride.hide(); if (Upolyd) { buf = nh_capitalize_words(mons[u.umonnum].mname); @@ -748,6 +795,13 @@ void NetHackQtStatusWindow::updateStats() // justified relative to the label text for some unknown reason... align.ForceResize(); } + if (spreadout) + ++k; // when not condensed, Alignment is shown on the Conditions row + + if (!k) { + blank2.show(); // for vertical spacing: force the row to be non-empty + } else + blank2.hide(); if (::flags.time) time.setLabel("Time:", (long) g.moves); diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index ccc1df7f1..6464be047 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -46,6 +46,7 @@ private: QPixmap p_chaotic; QPixmap p_neutral; QPixmap p_lawful; + QPixmap p_blank2; // conditionally used for vertical spacing QPixmap p_satiated; QPixmap p_hungry; @@ -109,6 +110,7 @@ private: a 40x40 icon above and text lebel below; blank values are omitted and non-blank values are left justified */ NetHackQtLabelledIcon align; // w/ alignment-specific ankh icon + NetHackQtLabelledIcon blank2; // used for spacing if Align is moved NetHackQtLabelledIcon hunger; // blank if 'normal' NetHackQtLabelledIcon encumber; // blank if 'unencumbered' ('normal') /* zero or more status conditions; in major, minor, 'other' order */ diff --git a/win/Qt/qt_xpms.h b/win/Qt/qt_xpms.h index df0540ad9..43b055e34 100644 --- a/win/Qt/qt_xpms.h +++ b/win/Qt/qt_xpms.h @@ -3,7 +3,8 @@ // In alhpabetical order by array name. Probably not the best ordering... /* clang-format off */ -#if 0 // blank icon for use as placeholder + +// blank icon for use as placeholder /* XPM */ static const char *blank_xpm[] = { /* width height ncolors chars_per_pixel */ @@ -57,7 +58,8 @@ static const char *blank_xpm[] = { "........................................", "........................................" }; -#endif + +// Characteristics, Alignment, and Conditions static const char *blind_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 5 1", @@ -1821,4 +1823,5 @@ static const char *wis_xpm[] = { "oooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooo" }; + /* clang-format on */