Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shoes console not wrapping up text #18

Open
IanTrudel opened this issue Jan 8, 2015 · 14 comments
Open

Shoes console not wrapping up text #18

IanTrudel opened this issue Jan 8, 2015 · 14 comments
Labels

Comments

@IanTrudel
Copy link
Collaborator

IanTrudel commented Jan 8, 2015

Shoes console is not wrapping up text preventing a user to read all the information when it exceeds the width of the window. This issue on Linux is currently undetermined.

Shoes.app(:title => "Shoes Console Unwrapped", :width => 450, :height => 250) {
   info Shoes.instance_methods
   para "Check Shoes console (alt-/)"
}

Shoes on MacOS X
capture d ecran 2015-01-08 a 04 14 24 am

Shoes on Windows

image

@IanTrudel
Copy link
Collaborator Author

Investigation revealed that word wrapping on an array of symbols is not working. This issue affects normal windows as much as Shoes console.

Shoes.app(:width => 450, :height => 450) {
   a = (0..25).map { [*('A'..'Z')].sample(rand(7) + 1).join }
   para "#{a.inspect}\n\n", :wrap => "char"
   para "#{a.inspect}\n\n", :wrap => "word"

   a.collect! { |n| n.to_sym }
   para "#{a.inspect}\n\n", :wrap => "char"
   para "#{a.inspect}", :wrap => "word"
}

image

@ccoupe
Copy link

ccoupe commented Jan 17, 2015

It might be two separate issues. The console does not wrap until \n or some very large number of characters are written. Try that new copy button.

It wasn't aware that word wrapping was the Shoes spec. As you resize the second example it's only the last line that overflows he visual box.

Both errors affect all three platforms so its not a Gtk vs OSX issue.

@IanTrudel
Copy link
Collaborator Author

It is most likely the same issue because Shoes console uses para to display info, debug and error and para is using _word wrapping by default_. The copy button does copy the whole content but that was expected anyway since it is a rendering problem. The console does wrap as you can see in the console version of the code above:

image

Shoes.app(:width => 450, :height => 450) {
   a = (0..25).map { [*('A'..'Z')].sample(rand(7) + 1).join }
   info "#{a.inspect}"

   a.collect! { |n| n.to_sym }
   info "#{a.inspect}"
}

@ccoupe ccoupe added the Linux label Jan 18, 2015
@ccoupe
Copy link

ccoupe commented Jan 18, 2015

Should the console use char wrap? That would be more terminal like.

In the example below, note how para 1 & 2 change as you widen the window .

para 5 is the weirdest. Delete the '5. ' and it behaves like you first example.

Shoes.app(:width => 450, :height => 500) {
   info Shoes.instance_methods
   para "Check Shoes console (alt-/)\n"
   para "1. How does wrap work when we have really long strings that exceed the size of the window", :wrap => "trim"
   a = (0..25).map { [*('A'..'Z')].sample(rand(7) + 1).join }
   para "2. #{a.inspect}\n\n", :wrap => "char"
   para "3. #{a.inspect}\n\n", :wrap => "word"

   a.collect! { |n| n.to_sym }
   para "4. #{a.inspect}\n\n", :wrap => "char"
   para "5. #{a.inspect}", :wrap => "word"
   para "6 a para at the end which may not wrap or it might be joined with the para above"
}

There's something about number 5 that causes confusion.

@IanTrudel
Copy link
Collaborator Author

Word wrap is better for Shoes considering how often you remind me that Shoes is for end-users that may not have much programming experience. Word wrap is essentially easier to read.

Another test was to remove https://github.com/Shoes3/shoes/blob/master/lib/shoes/inspect.rb and create an empty inspect.rb. It was suspected because the code overloads inspect methods. No change whatsoever in the rendering.

@ccoupe
Copy link

ccoupe commented Jan 18, 2015

Word wrap on the console may be better but it's not working! I suspect the stacks and flows in log.rb need to be re-examined so they do the right thing - the definition of 'right' is not clear to me.

Since the behavior is not platform dependent it must be in the next higher layer of shoes, in the general layout abstractions and textblock & styles and it has probably existed since Shoes 2. Which leads to a couple more questions. What does Shoes4 do with our snippets? I know they struggle with styled text segments too. Is there a compatibility break with Shoes 4? If so, should Shoes 3.2 emulate the behavior of 4 or stick with the old bugs?

Most folks would see the bugs, sigh and just add some stacks and flows that work for them. That would be my first solution to the console layout since in the big scheme the perfect console layout isn't all that important.

@IanTrudel
Copy link
Collaborator Author

Your assessment is sound to me as it must be in the low level C code where TextBlock and Style are good candidates. The expected behaviour is a proper word wrap and the manual says it should word wrap. Is this not maintenance? Shoes 4 most likely have to fix this issue too.

@ccoupe
Copy link

ccoupe commented Jan 19, 2015

Here's an example that seems similar to yours but as best I can tell, this one behaves as expected.
https://gist.github.com/ccoupe/cb793fd29b94c7bc2d97

Why does your fail but plain text succeed?

@IanTrudel
Copy link
Collaborator Author

The following code snippet will show you that the colon is causing the wrapping to fail. Notice that p1 and p2 are rendered properly but p3 and p4 are not. The simple fact that the word TextBlock is prefixed by a colon on p3 is enough to cause rendering problems because it is the first word to be wrapped, where as when the word where is prefixed by colon the rendering is done properly.

Shoes.app do
   p1 = "Your assessment is sound to me as it must be in the low level C code where TextBlock and Style are good candidates."
   p2 = p1.split.collect { |n| (n =~ /where/ ? ":" + n : n) }.join(" ")
   p3 = p1.split.collect { |n| (n =~ /TextBlock/ ? ":" + n : n) }.join(" ")
   p4 = p1.split.collect { |n| ":" + n }.join(" ")

   para "#{p1}\n\n", :wrap => "word"
   para "#{p2}\n\n", :wrap => "word"
   para "#{p3}\n\n", :wrap => "word"
   para "#{p4}\n\n", :wrap => "word"

   info p1
   info p2
   info p3
   info p4
end

image

image

@IanTrudel
Copy link
Collaborator Author

This is another interesting test where most characters will not affect the rendering but some characters such as colon and semi-colon will break the word wrap. Some other characters such as |, ?, !, -, %, / and } will be displayed on the first line whereas others will be wrapped on the next line. Using a stack in this example will not affect the rendering nor prevent the bug.

Shoes.app do
   p1 = "Your assessment is sound to me as it must be in the low level C code where TextBlock and Style are good candidates."

   [":", "_", "|", "?", ";", "!", "*", "-", "%", "/", "=",
      ">", "<", "(", ")", "{", "}", "[", "]"].each_with_index { |m, i|
      p2 = p1.split.collect { |n| (n =~ /TextBlock/ ? m + n : n) }.join(" ")
      stack {
         background "#f1f5e1" if i % 2 == 0
         para p2, :wrap => "word"
      }
      info p2
   }
end

@ccoupe
Copy link

ccoupe commented Jan 19, 2015

Ruby.c: 2743 in shoes_textblock_on_layout() calls pango_layout_set_wrap. We need to consult the pango doc to figure out whether this normal pango or not and what we might do to fix it.

@ccoupe
Copy link

ccoupe commented Jan 19, 2015

After a cursory glance at this part of ruby.c, I don't see an obvious attempt from Shoes to interpret characters in the string and tell pango to do something different. That doesn't mean it's not there.

The pango doc is spartan but there are hints it can interpret tags (in the html sense) if asked but your example would probably not trigger that, if it was set. Perhaps this is pango-cairo magic?

I don't think pango or cairo are used in Shoes 4 so they probably would not have implemented this behavior unless they knew about it and some one considers it a feature.

@ccoupe
Copy link

ccoupe commented Jan 19, 2015

Hmm. Running that latest example where you test some special chars shows that the word wrapping does happen correctly. Some chars end a word some don't but none are lost. Not really the same problem.

Here's a simple test to show what's happening

Shoes.app do
   p1 = "Your assessment is sound to me as it must be in the low level C code where TextBlock and Style are good candidates."
   p2 = ":Your :assessment :is :sound :to :me :as :it :must :be :in :the :low :level :C :code :where :TextBlock :and :Style :are :good :candidates."  
   p3 = ":Your :assessment :is :sound :to :me :as :it :must :be :in :the :low :level :C code where TextBlock :and :Style :are :good :candidates."  
   para "#{p1}\n\n"
   para "#{p2}\n\n"  # doesn't wrap
   para "#{p3}\n\n"  # wraps funny
end

Watch what happens as you narrow the screen.

Working hypothesis is: A leading colon on a word is a flag to pango to disable wrapping here until something resets the flag. As mentioned pango does have markup capability. Alternate hypothesis is these are not strings but ruby symbols and :sym.to_s returns something that confuses pango.

@IanTrudel
Copy link
Collaborator Author

Working hypothesis is: A leading colon on a word is a flag to pango to disable wrapping here until something resets the flag. As mentioned pango does have markup capability. Alternate hypothesis is these are not strings but ruby symbols and :sym.to_s returns something that confuses pango.

Pango markup capability might be the culprit here but don't forget that semi-colon is also disabling wrapping. The problem with the second hypothesis is that the last few tests were designed to avoid this issue by defining a string instead of an array of symbols, so there is no conversion symbol to_s. Your very last snippet doesn't need to_s.

The following snippet is interesting because it shows that where : is considered one unit when you resize the width of the window. Take a look at the third para, if you resize smaller and reach the colon, it will wrap where : instead of only the colon.

So it might be how Pango interpret the text but not as a markup, instead as a plain text, trying to keep logical units together.

Shoes.app do
   p1 = "Your assessment is sound to me as it must be in the low level C code where TextBlock and Style are good candidates."
   p2 = "Your assessment is sound to me as it must be in the low level C code where :TextBlock and Style are good candidates."
   p3 = "Your assessment is sound to me as it must be in the low level C code where : TextBlock and Style are good candidates."

   para "#{p1}\n\n"
   para "#{p2}\n\n"
   para "#{p3}\n\n"
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants