orbitalquark / textadept

Textadept is a fast, minimalist, and remarkably extensible cross-platform text editor for programmers.
https://orbitalquark.github.io/textadept
MIT License
636 stars 38 forks source link

Unpredictable behavior of statusbar and view while using `ui.buffer_statusbar_text="..."` #462

Closed oOosys closed 11 months ago

oOosys commented 11 months ago

Linux Mint 21.2 Xfce GTK version of Textadept 12 :

I am trying to use the statusbar to display the currently on the clipboard available text and experienced that the statusbar is capable of displaying multiple lines of text (as many as needed up to full height of the window making the buffer text vanishing):


ui.buffer_statusbar_text = 
"-************************************************************************************************-" 
            .. "\n" .. "CLIPBOARD='" .. tostring(ui.clipboard_text)
            .. "\n" .. "'UPDATE_UI' event call No: " .. tostring( callsCounter ) 

The issues are:

(*) sometimes no text is shown at all (because to short?), sometimes the full text width is shown and sometimes only part of the text (in spite of enough space in the statusbar to show the entire text width). 

(*) with change of the number of lines there are weird effects on the window size and the number of shown lines of the actual buffer text

I am currently failing to find any reliable rule able to predict what will happen when ... really weird and somehow unpredictable behavior which seems to demonstrate that there must be a flaw in the logic behind handling of changes of by ui.buffer_statusbar_text= set text.

It seems that the statusbar is splitted into left and right parts with left aligned text in the left part and right aligned text in the right part. The left part can be set using ui.statusbar_text, the right part using ui.buffer_statusbar_text. Does the statusbar have also a third part in the middle?

oOosys commented 11 months ago

The statusbar consists of two parts only. Below a textadept_gtk.c code snippet showing this:

    GtkWidget *hbox = gtk_hbox_new(false, 0);
    gtk_box_pack_start(GTK_BOX(hbox), statusbar[0] = gtk_label_new(NULL), true, true, 5);
    gtk_misc_set_alignment(GTK_MISC(statusbar[0]), 0, 0); // left-align
    gtk_box_pack_start(GTK_BOX(hbox), statusbar[1] = gtk_label_new(NULL), false, false, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, false, false, 1);

The observed "weird" behavior isn't a weird behavior because of varying setting of the content of the statusbar. It is caused by resizing the application window beyond the size of the display/monitor/screen done in order to show all of the text.

The issue is, that if the some lines of the text to be shown in the statusbar are too long to fit into the statusbar, the window will be resized in order to show the entire text beyond the width of the display/monitor/screen width. This, if unnoticed, leads to the "weird" behavior which is hard to explain not knowing that the text is properly rendered, but partially or entirely not visible because of window width increased beyond the width of the display/monitor/screen.

The increased window size will be not revoked when the length of the lines to display in the statusbar becomes shorter. The side effect of this fact and the fact that the text is right aligned is that a short text displayed at the right edge of the window will be not visible after there was a looong line text displayed in the statusbar before.

oOosys commented 11 months ago

To keep the code base of Textadept small it would be probably best not to try to provide any fix for the observed behavior. For me reason enough to agree with closing the opened issue, so feel free to close the issue as solved.

Below are four kinds of possible solutions which come to my mind considering the reason for the "weird" behavior in case the guidelines of Textadept design change allowing extending the code in order to improve Textadepts' behavior:

Saving the original window width and height on resize due to setting of text of the statusbar in order to be able to reduce the increased window width/height on next change of statusbar text to a text with less or shorter lines.  

As it could interfere with other possible changes of window size happening before the next update of the statusbar, it would need mirroring the default window size to come back to, on any window size change.

Prevent that the window size extends beyond the display/monitor/screen width and height. 

This needs to decide if the text should be wrapped or cut off at the window edge. Probably wrapping it along with showing the wrapping marks plus two spaces indentation is the better option. The alternative would be to provide at line ends of overlong text lines appropriate markings indicating that the text extends beyond the visible part.
Considering the text height the options would be to provide an indicator that there are more lines than shown or to display some leading and trailing lines along with an indicator that are more lines in between.

Limit the vertical size of the status bar to three lines or to a smaller height in case of extreme small vertical window size and limit the length of shown lines to a fixed width. 

This option is in my eyes limiting the use of the statusbar and probably not worth to be considered even if this would be probably the easiest way of solving any issues if coupled with not resizing the window at all no matter which text is specified to show up.

Adapt the font size to the text content to be displayed showing as much of the text in a statusbar as possible with height limited to a maximum of three lines of default font size. 

This option requires most programming efforts to cover all the possible cases with overlong lines and many text lines limiting the minimal size of the font to for example 6. Nice to have would be here (and also in the options mentioned above) if the indicators of overlong lines and skipped lines get displayed in another color.

orbitalquark commented 11 months ago

Thanks for taking the time to describe the issue you're experiencing and investigating further. Textadept relies on the GUI toolkit to handle how statusbar text is laid out and displayed. It assumes whatever the user is passing to ui.statusbar_text and ui.buffer_statusbar_text can be reasonably displayed. Therefore, I will close this.

oOosys commented 11 months ago

@orbitalquark May you please explain how it comes that the right label widget of the statusbar is set in C-code as not resizable, but actually it resizes to the text size pasted into it the same way as the left label widget does?

    static GtkWidget *window, *menubar, *tabbar, *statusbar[2];
    ...
    GtkWidget *hbox = gtk_hbox_new(false, 0);
    gtk_box_pack_start(GTK_BOX(hbox), statusbar[0] = gtk_label_new(NULL), true  , true  , 5);
    gtk_misc_set_alignment(GTK_MISC(statusbar[0]), 0, 0); // left-align
    gtk_box_pack_start(GTK_BOX(hbox), statusbar[1] = gtk_label_new(NULL), false , false , 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, false, false, 1);
orbitalquark commented 11 months ago

I'm pretty sure it is resizable, but it shrinks as much as possible.

oOosys commented 11 months ago

I'm pretty sure it is resizable, but it shrinks as much as possible.

OK ... I need to dive deeper into the actual meaning of GTK-options for gtk_box_pack_start. It's not that easy to guess from the documentation what is the actual effect of them. If I understand you right, the left label will take as much space as possible, and the right box as less as possible. This explains how it comes that the right box looks like right aligned even if it is left aligned (the default label alignment), right? If it is actually that way ... what is the explicit alignment tk_misc_set_alignment(GTK_MISC(statusbar[0]), 0, 0); // left-align good for? The labels should work the same way also without it, don't they?

orbitalquark commented 11 months ago

Correct, the left statusbar label expands to fill up as much space as possible, making the buffer statusbar look right-aligned. I think labels are centered by default. You can always comment out that line and test it for yourself.