diff options
author | Sebastian Geerken <devnull@localhost> | 2012-11-17 11:31:57 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2012-11-17 11:31:57 +0100 |
commit | 0bbf8d7470e94e78d3be45e4da023034943e25b3 (patch) | |
tree | e0dc3173c94779c2e360a6702607d7aa689d93f9 | |
parent | 9153bef3961e671095ab03be3b3f6cb23a5059e1 (diff) | |
parent | d9bccd6d15eb017964fbdfc3aba428dfbc4764b2 (diff) |
Merge.
-rw-r--r-- | doc/dw-line-breaking.doc | 297 | ||||
-rw-r--r-- | dw/fltkviewport.cc | 9 | ||||
-rw-r--r-- | dw/textblock.cc | 12 | ||||
-rw-r--r-- | dw/textblock.hh | 2 | ||||
-rw-r--r-- | src/IO/IO.c | 7 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/cssparser.cc | 2 | ||||
-rw-r--r-- | src/domainrc | 8 | ||||
-rw-r--r-- | src/findbar.cc | 16 | ||||
-rw-r--r-- | src/findbar.hh | 5 | ||||
-rw-r--r-- | src/html.cc | 4 | ||||
-rw-r--r-- | src/tipwin.cc | 224 | ||||
-rw-r--r-- | src/tipwin.hh | 74 | ||||
-rw-r--r-- | src/ui.cc | 78 | ||||
-rw-r--r-- | src/ui.hh | 36 | ||||
-rw-r--r-- | src/uicmd.cc | 10 |
16 files changed, 528 insertions, 258 deletions
diff --git a/doc/dw-line-breaking.doc b/doc/dw-line-breaking.doc index 6492a579..2967e98f 100644 --- a/doc/dw-line-breaking.doc +++ b/doc/dw-line-breaking.doc @@ -4,7 +4,8 @@ padding: 0.5em 1em; background-color: #ffffe0"><b>Info:</b> Should be incorporated into dw::Textblock.</div> -<h2>Introduction</h2> +Introduction +============ For the implementation of hyphenation in dillo, not only a hyphenation algorithm was implemented, but also, the line breaking was @@ -23,11 +24,9 @@ get a penalty of, say, 1, since hyphenation is generally considered as a bit "ugly" and should rather be avoided. Consider a situation where the word "dillo" could be hyphenated, with the following badnesses: -<ul> -<li>before "dillo": 0.6; -<li>between "dil-" and "lo": 0.2; -<li>after "dillo": 0.5. -</ul> +- before "dillo": 0.6; +- between "dil-" and "lo": 0.2; +- after "dillo": 0.5. Since the penalty is added, the last value is the best one, so "dillo" is put at the end of the line, without hyphenation. @@ -35,40 +34,42 @@ is put at the end of the line, without hyphenation. Under other circumstances (e. g. narrower lines), the values might be different: -<ul> -<li>before "dillo": infinite; -<li>between "dil-" and "lo": 0.3; -<li>after "dillo": 1.5. -</ul> +- before "dillo": infinite; +- between "dil-" and "lo": 0.3; +- after "dillo": 1.5. In this case, even the addition of the penalty makes hyphenation the best choice. -<h2>Literature</h2> +Literature +========== -<h3>Breaking Paragraphs Into Lines</h3> +Breaking Paragraphs Into Lines +------------------------------ Although dillo does not (yet?) implement the algorithm T<sub>E</sub>X uses for line breaking, this document shares much of the notation used -by the article <i>Breaking Paragraphs Into Lines</i> by Donald -E. Knuth and Michael F. Plass; originally published in: Software -- -Practice and Experience <b>11</b> (1981), 1119-1184; reprinted in: -<i>Digital Typography</i> by Donalt E. Knuth, CSLI Publications 1999. -Anyway an interesting reading. +by the article *Breaking Paragraphs Into Lines* by Donald E. Knuth and +Michael F. Plass; originally published in: Software -- Practice and +Experience **11** (1981), 1119-1184; reprinted in: *Digital +Typography* by Donalt E. Knuth, CSLI Publications 1999. Anyway an +interesting reading. -<h3>Hyphenation</h3> +Hyphenation +----------- Dillo uses the algorithm by Frank Liang, which is described in his doctoral dissertation found at http://www.tug.org/docs/liang/. There -is also a description in chapter H ("Hyphenation") of <i>The -T<sub>E</sub>Xbook</i> by Donald E. Knuth, Addison-Wesley 1984. +is also a description in chapter H ("Hyphenation") of *The +T<sub>E</sub>Xbook* by Donald E. Knuth, Addison-Wesley 1984. Pattern files can be found at http://www.ctan.org/tex-archive/language/hyphenation. -<h2>Overview of Changes</h2> +Overview of Changes +=================== Starting with this change, dw/textblock.cc has been split up; anything related to line breaking has been moved into @@ -77,32 +78,31 @@ like floats. (Better, however, would be a clean logical split.) An important change relates to the way that lines are added: before, dillo would add a line as soon as a new word for this line was -added. Now, a line is added not before the <i>last</i> word of this -line is known. This has two important implications: - -<ul> -<li>Some values in dw::Textblock::Line, which represented values -accumulated within the line, could be removed, since now, these values -can be calculated simply in a loop. -<li>On the other hand, this means that some words may not belong to -any line. For this reason, in some cases (e. g. in -dw::Textblock::sizeRequestImpl) dw::Textblock::showMissingLines is -called, which creates temporary lines, which must, under other -circumstances, be removed again by dw::Textblock::removeTemporaryLines, -since they have been created based on limited information, and so -possibly in a wrong way. (See below for details.) -</ul> +added. Now, a line is added not before the *last* word of this line is +known. This has two important implications: + +- Some values in dw::Textblock::Line, which represented values + accumulated within the line, could be removed, since now, these + values can be calculated simply in a loop. +- On the other hand, this means that some words may not belong to any + line. For this reason, in some cases (e. g. in + dw::Textblock::sizeRequestImpl) dw::Textblock::showMissingLines is + called, which creates temporary lines, which must, under other + circumstances, be removed again by + dw::Textblock::removeTemporaryLines, since they have been created + based on limited information, and so possibly in a wrong way. (See + below for details.) When a word can be hyphenated, an instance of dw::Textblock::Word is used for each part. Notice that soft hyphens are evaluated immediately, but automatic hyphenation is done in a lazy way (details below), so the number of instances may change. There are some new attributes: only when dw::Textblock::Word::canBeHyphenated is set to -<i>true</i>, automatic hyphenation is allowed; it is set to false when -soft hyphens are used for a word, and (of course) by the automatic -hyphenation itself. Furthermore, dw::Textblock::Word::hyphenWidth (more -details in the comment there) has to be included when calculating line -widths. +*true*, automatic hyphenation is allowed; it is set to false when soft +hyphens are used for a word, and (of course) by the automatic +hyphenation itself. Furthermore, dw::Textblock::Word::hyphenWidth +(more details in the comment there) has to be included when +calculating line widths. Some values should be configurable: dw::Textblock::HYPHEN_BREAK, the penalty for hyphens. Also dw::Textblock::Word::stretchability, @@ -110,17 +110,17 @@ dw::Textblock::Word::shrinkability, which are both set in dw::Textblock::addSpace. -<h2>Criteria for Line-Breaking</h2> +Criteria for Line-Breaking +========================== Before these changes to line breaking, a word (represented by dw::Textblock::Word) had the following attributes related to line-breaking: -<ul> -<li>the width of the word itself, represented by dw::Textblock::Word::size; -<li>the width of the space following the word, represented by -dw::Textblock::Word::origSpace. -</ul> +- the width of the word itself, represented by + dw::Textblock::Word::size; +- the width of the space following the word, represented by + dw::Textblock::Word::origSpace. In a more mathematical notation, the \f$i\f$th word has a width \f$w_i\f$ and a space \f$s_i\f$. @@ -132,37 +132,31 @@ With hyphenation, the criteria are refined. Hyphenation should only be used when otherwise line breaking results in very large spaces. We define: -<ul> -<li>the badness \f$\beta\f$ of a line, which is greater the more the -spaces between the words differ from the ideal space; -<li>a penalty \f$p\f$ for any possible break point. -</ul> +- the badness \f$\beta\f$ of a line, which is greater the more the + spaces between the words differ from the ideal space; +- a penalty \f$p\f$ for any possible break point. The goal is to find those break points, where \f$\beta + p\f$ is minimal. Examples for the penalty \f$p\f$: -<ul> -<li>0 for normal line breaks (between words); -<li>\f$\infty\f$ to prevent a line break at all costs; -<li>\f$-\infty\f$ to force a line -<li>a positive, but finite, value for hyphenation points. -</ul> +- 0 for normal line breaks (between words); +- \f$\infty\f$ to prevent a line break at all costs; +- \f$-\infty\f$ to force a line +- a positive, but finite, value for hyphenation points. So we need the following values: -<ul> -<li> \f$w_i\f$ (the width of the word \f$i\f$ itself); -<li> \f$s_i\f$ (the width of the space following the word \f$i\f$); -<li> the stretchability \f$y_i\f$, a value denoting how much the space -after word\f$i\f$ can be stretched (typically \f${1\over 2} s_i\f$); -<li> the shrinkability \f$y_i\f$, a value denoting how much the space -after word\f$i\f$ can be shrunken (typically \f${1\over 3} s_i\f$); -<li> the penalty \f$p_i\f$, if the line is broken after word \f$i\f$; -<li> a width \f$h_i\f$, which is added, when the line is broken after -word \f$i\f$. -</ul> +- \f$w_i\f$ (the width of the word \f$i\f$ itself); +- \f$s_i\f$ (the width of the space following the word \f$i\f$); +- the stretchability \f$y_i\f$, a value denoting how much the space + after word\f$i\f$ can be stretched (typically \f${1\over 2} s_i\f$); +- the shrinkability \f$y_i\f$, a value denoting how much the space + after word\f$i\f$ can be shrunken (typically \f${1\over 3} s_i\f$); +- the penalty \f$p_i\f$, if the line is broken after word \f$i\f$; +- a width \f$h_i\f$, which is added, when the line is broken after + word \f$i\f$. \f$h_i\f$ is the width of the hyphen, if the word \f$i\f$ is a part of the hyphenated word (except the last part); otherwise 0. @@ -185,22 +179,18 @@ We define: \f$W_a^b\f$ is the total width, \f$Y_a^b\f$ the total stretchability, and \f$Z_a^b\f$ the total shrinkability. -Furthermore the <i>adjustment ratio</i> \f$r_a^b\f$: +Furthermore the *adjustment ratio* \f$r_a^b\f$: -<ul> -<li>in the ideal case that \f$W_a^b = l\f$: \f$r_a^b = 0\f$; -<li>if \f$W_a^b < l\f$: \f$r_a^b = (l - W_a^b) / Y_a^b\f$ (\f$r_a^b < 0\f$ in -this case); -<li>if \f$W_a^b > l\f$: \f$r_a^b = (l - W_a^b) / Z_a^b\f$ (\f$r_a^b < 0\f$ in -this case). -</ul> +- in the ideal case that \f$W_a^b = l\f$: \f$r_a^b = 0\f$; +- if \f$W_a^b < l\f$: \f$r_a^b = (l - W_a^b) / Y_a^b\f$ + (\f$r_a^b < 0\f$ in this case); +- if \f$W_a^b > l\f$: \f$r_a^b = (l - W_a^b) / Z_a^b\f$ + (\f$r_a^b < 0\f$ in this case). The badness \f$\beta_a^b\f$ is defined as follows: -<ul> -<li>if \f$r_a^b\f$ is undefined or \f$r_a^b < -1\f$: \f$\beta_a^b = \infty\f$; -<li>otherwise: \f$\beta_a^b = |r_a^b|^3\f$ -</ul> +- if \f$r_a^b\f$ is undefined or \f$r_a^b < -1\f$: \f$\beta_a^b = \infty\f$; +- otherwise: \f$\beta_a^b = |r_a^b|^3\f$ The goal is to find the value of \f$b\f$ where \f$\beta_a^b + p_b\f$ is minimal. (\f$a\f$ is given, since we do not modify the previous @@ -210,13 +200,12 @@ After a couple of words, it is not predictable whether this minimum has already been reached. There are two cases where this is possible for a given \f$b'\f$: -<ul> -<li>\f$\beta_{b'}^a = \infty\f$ (line gets too tight): \f$a \le b < -b'\f$, the minimum has to be searched between these two values; -<li>\f$p_{b'} = -\infty\f$ (forced line break): \f$a \le b \le b'\f$ -(there may be another minimum of \f$\beta_a^b\f$ before; note the -\f$\le\f$ instead of \f$<\f$). -</ul> +- \f$\beta_{b'}^a = \infty\f$ (line gets too tight): + \f$a \le b < b'\f$, the minimum has to be searched between these two + values; +- \f$p_{b'} = -\infty\f$ (forced line break): + \f$a \le b \le b'\f$ (there may be another minimum of + \f$\beta_a^b\f$ before; note the \f$\le\f$ instead of \f$<\f$). This leads to a problem that the last words of a text block are not displayed this way, since they do not fulfill these rules for being @@ -229,7 +218,8 @@ code more complicated. See dw::Textblock::BadnessAndPenalty for details.) -<h2>Hyphens</h2> +Hyphens +======= Words (instances of dw::Textblock::Word), which are actually part of a hyphenated word, are always drawn as a whole, not seperately. This @@ -258,25 +248,21 @@ etc. However, it gets a bit more complicated. Since all non-hyphenations are drawn as a whole, the following conditions can be concluded: -<ul> -<li>from drawing "ABCD" (not hyphenated at all): w(A) + w(B) + w(C) + -w(D) = l(ABCD); -<li>from drawing "BCD", when hyphenated as "A-BCD" ("A-" is not -considered here): w(B) + w(C) + w(D) = l(BCD); -<li>likewise, from drawing "CD" (cases "AB-CD" and "A-B-CD"): w(C) + -w(D) = l(CD); -<li>finally, for the cases "ABC-D", "AB-C-D", "A-BC-D", and "A-B-C-D": -w(D) = l(D). -</ul> +- from drawing "ABCD" (not hyphenated at all): w(A) + w(B) + w(C) + + w(D) = l(ABCD); +- from drawing "BCD", when hyphenated as "A-BCD" ("A-" is not + considered here): w(B) + w(C) + w(D) = l(BCD); +- likewise, from drawing "CD" (cases "AB-CD" and "A-B-CD"): w(C) + + w(D) = l(CD); +- finally, for the cases "ABC-D", "AB-C-D", "A-BC-D", and "A-B-C-D": + w(D) = l(D). So, the calculation is simple: -<ul> -<li>w(D) = l(D) -<li>w(C) = l(CD) - w(D) -<li>w(B) = l(BCD) - (w(C) + w(D)) -<li>w(A) = l(ABCD) - (w(B) + w(C) + w(D)) -</ul> +- w(D) = l(D) +- w(C) = l(CD) - w(D) +- w(B) = l(BCD) - (w(C) + w(D)) +- w(A) = l(ABCD) - (w(B) + w(C) + w(D)) For calculation the hyphen widths, the exact conditions would be over-determined, even when the possibility for individual hyphen @@ -285,7 +271,8 @@ be used. However, a simple approach of fixed hyphen widths will have near-perfect results, so this is kept simple. -<h2>Automatic Hyphenation</h2> +Automatic Hyphenation +===================== When soft hyphens are used, words are immediately divided into different parts, and so different instances of @@ -293,14 +280,12 @@ dw::Textblock::Word. Automatic hyphenation (using Liang's algorithm) is, however, not applied always, but only when possibly needed, after calculating a line without hyphenation: -<ul> -<li>When the line is tight, the last word of the line is hyphenated; -possibly this will result in a line with less parts of this word, and -so a less tight line. -<li>When the line is loose, and there is another word (for the -next line) available, this word is hyphenated; possibly, some parts of -this word are taken into this line, making it less loose. -</ul> +- When the line is tight, the last word of the line is hyphenated; + possibly this will result in a line with less parts of this word, + and so a less tight line. +- When the line is loose, and there is another word (for the next + line) available, this word is hyphenated; possibly, some parts of + this word are taken into this line, making it less loose. After this, the line is re-calculated. @@ -323,36 +308,38 @@ a trick (a second array) to deal with exactly this problem. See there for more details. -<h2>Tests</h2> +Tests +===== There are test HTML files in the <i>test</i> directory. Also, there is a program testing automatic hyphenation, <i>test/liang</i>, which can be easily extended. -<h2>Bugs and Things Needing Improvement</h2> +Bugs and Things Needing Improvement +=================================== -<h3>High Priority</h3> +High Priority +------------- -<b>Bugs in hyphenation:</b> There seem to be problems when breaking +**Bugs in hyphenation:** There seem to be problems when breaking words containing hyphens already. Example: "Abtei-Stadt", which is divided into "Abtei-" and "Stadt", resulting possibly in "Abtei-<span></span>-[new line]Stadt". See also below under "Medium Priority", on how to deal with hyphens and dashes. -<h3>Medium Priority</h3> +Medium Priority +--------------- -<b>Break hyphens and dashes:</b> The following rules seem to be relevant: +**Break hyphens and dashes:** The following rules seem to be relevant: -<ol> -<li>In English, an em-dash is used with no spaces around. Breaking -before and after the dash should be possible, perhaps with a penalty > -0. (In German, an en-dash (Halbgeviert) with spaces around is used -instead.)</li> -<li>After a hyphen, which is part of a compound word, a break should -be possible. As described above ("Abtei-Stadt"), this collides with -hyphenation.</li> -</ol> +- In English, an em-dash is used with no spaces around. Breaking + before and after the dash should be possible, perhaps with a + penalty > 0. (In German, an en-dash (Halbgeviert) with spaces around + is used instead.) +- After a hyphen, which is part of a compound word, a break should be + possible. As described above ("Abtei-Stadt"), this collides with + hyphenation. Where to implement? In the same dynamic, lazy way like hyphenation? As part of hyphenation? @@ -364,7 +351,7 @@ and "Stadt", but "Nordrhein-Westfalen" is divided into "Nord", ("rhein-West") is untouched. (Sorry for the German words; if you have got English examples, send them me.) -<b>Incorrect calculation of extremes:</b> The minimal width of a text +**Incorrect calculation of extremes:** The minimal width of a text block (as part of the width extremes, which are mainly used for tables) is defined by everything between two possible breaks. A possible break may also be a hyphenation point; however, hyphenation @@ -377,30 +364,28 @@ resulting possibly in a different value for the minimal width. Possible strategies to deal with this problem: -<ol> -<li>Ignore. The implications should be minimal. -<li>Any solution will make it neccessary to hyphenate at least some -words when calculating extremes. Since the minimal widths of all words -are used to calculate the minimal width of the text block, the -simplest approach will hyphenate all words. This would, of course, -eliminate the performance gains of the current lazy approach. -<li>The latter approach could be optimized in some ways. Examples: (i) -If a word is already narrower than the current accumulated value for -the minimal width, it makes no sense to hyphenate it. (ii) In other -cases, heuristics may be used to estimate the number of syllables, the -width of the widest of them etc. -</ol> - -<h3>Low Priority</h3> - -<b>Mark the end of a paragraph:</b> Should dw::core::Content::BREAK -still be used? Currently, this is redundant to +- Ignore. The implications should be minimal. +- Any solution will make it neccessary to hyphenate at least some + words when calculating extremes. Since the minimal widths of all + words are used to calculate the minimal width of the text block, the + simplest approach will hyphenate all words. This would, of course, + eliminate the performance gains of the current lazy approach. +- The latter approach could be optimized in some ways. Examples: (i) + If a word is already narrower than the current accumulated value for + the minimal width, it makes no sense to hyphenate it. (ii) In other + cases, heuristics may be used to estimate the number of syllables, + the width of the widest of them etc. + +Low Priority +------------ + +**Mark the end of a paragraph:** Should dw::core::Content::BREAK still +be used? Currently, this is redundant to dw::Textblock::BadnessAndPenalty. -<b>Other than justified text:</b> The calculation of badness is -designed for justified text. For other alignments, it may be -modified. The point is the definition of stretchability and for the -line. +**Other than justified text:** The calculation of badness is designed +for justified text. For other alignments, it may be modified. The +point is the definition of stretchability and for the line. Consider left-aligned text. Most importantly, not the spaces between the words, but the space on the right border is adjusted. If the @@ -425,8 +410,8 @@ lines will, when spaces are shrunken, get too long!) Analogous considerations must be made for right-aligned and centered text. (For centered texts, there are two adjustable spaces.) -<b>Hyphens in adjacent lines:</b> It should be simple to assign a -larger penalty for hyphens, when the line before is already -hyphenated. This way, hyphens in adjacent lines are penalized further. +**Hyphens in adjacent lines:** It should be simple to assign a larger +penalty for hyphens, when the line before is already hyphenated. This +way, hyphens in adjacent lines are penalized further. */ diff --git a/dw/fltkviewport.cc b/dw/fltkviewport.cc index 748262d8..5a58565e 100644 --- a/dw/fltkviewport.cc +++ b/dw/fltkviewport.cc @@ -216,6 +216,11 @@ void FltkViewport::draw () } else { draw_child (*hscrollbar); draw_child (*vscrollbar); + + if (d == FL_DAMAGE_ALL && hdiff && vdiff) { + fl_color(FL_GRAY); + fl_rectf(x()+w()-hdiff, y()+h()-vdiff, hdiff, vdiff); + } } } @@ -318,6 +323,10 @@ int FltkViewport::handle (int event) mouse_y = Fl::event_y(); positionChanged(); break; + + case FL_LEAVE: + mouse_x = mouse_y = -1; + break; } return FltkWidgetView::handle (event); diff --git a/dw/textblock.cc b/dw/textblock.cc index b3971162..cd93fa1c 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -1046,7 +1046,7 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2, // Simple case, where copying in one buffer is not needed. Word *word = words->getRef (wordIndex1); drawWord0 (wordIndex1, wordIndex2, word->content.text, word->size.width, - style, view, area, xWidget, yWidgetBase); + false, style, view, area, xWidget, yWidgetBase); } else { // Concatenate all words in a new buffer. int l = 0, totalWidth = 0; @@ -1070,7 +1070,7 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2, text[p++] = 0; } - drawWord0 (wordIndex1, wordIndex2, text, totalWidth, + drawWord0 (wordIndex1, wordIndex2, text, totalWidth, drawHyphen, style, view, area, xWidget, yWidgetBase); } } @@ -1079,7 +1079,7 @@ void Textblock::drawWord (Line *line, int wordIndex1, int wordIndex2, * TODO Comment */ void Textblock::drawWord0 (int wordIndex1, int wordIndex2, - const char *text, int totalWidth, + const char *text, int totalWidth, bool drawHyphen, core::style::Style *style, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase) { @@ -1138,7 +1138,9 @@ void Textblock::drawWord0 (int wordIndex1, int wordIndex2, xStart = xWorld; if (firstCharIdx) xStart += textWidth (text, 0, firstCharIdx, style); - if (firstCharIdx == 0 && lastCharIdx == wordLen) + // With a hyphen, the width is a bit longer than totalWidth, + // and so, the optimization to use totalWidth is not correct. + if (!drawHyphen && firstCharIdx == 0 && lastCharIdx == wordLen) width = totalWidth; else width = textWidth (text, firstCharIdx, @@ -1233,7 +1235,7 @@ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area) Word *word = words->getRef(wordIndex); int wordSize = word->size.width; - if (xWidget + word->size.width + word->effSpace >= area->x) { + if (xWidget + wordSize + word->hyphenWidth + word->effSpace >= area->x) { if (word->content.type == core::Content::TEXT || word->content.type == core::Content::WIDGET_IN_FLOW) { diff --git a/dw/textblock.hh b/dw/textblock.hh index 820f3d6d..76dd68fb 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -411,7 +411,7 @@ protected: void drawWord (Line *line, int wordIndex1, int wordIndex2, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase); void drawWord0 (int wordIndex1, int wordIndex2, - const char *text, int totalWidth, + const char *text, int totalWidth, bool drawHyphen, core::style::Style *style, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase); void drawSpace (int wordIndex, core::View *view, core::Rectangle *area, diff --git a/src/IO/IO.c b/src/IO/IO.c index 4b0285f2..1243c70a 100644 --- a/src/IO/IO.c +++ b/src/IO/IO.c @@ -369,8 +369,11 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, case OpAbort: io = Info->LocalKey; if (io->Buf->len > 0) { - MSG_WARN("IO_write, closing with pending data not sent\n"); - MSG_WARN(" \"%s\"\n", dStr_printable(io->Buf, 2048)); + char *newline = memchr(io->Buf->str, '\n', io->Buf->len); + int msglen = newline ? newline - io->Buf->str : 2048; + + MSG_WARN("IO_write, closing with pending data not sent: " + "\"%s\"\n", dStr_printable(io->Buf, msglen)); } /* close FD, remove from ValidIOs and remove its watch */ IO_close_fd(io, Op == OpEnd ? IO_StopWr : IO_StopRdWr); diff --git a/src/Makefile.am b/src/Makefile.am index ceba3e01..c4c7949a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,6 +25,8 @@ dillo_SOURCES = \ dillo.cc \ paths.cc \ paths.hh \ + tipwin.cc \ + tipwin.hh \ ui.cc \ ui.hh \ uicmd.cc \ diff --git a/src/cssparser.cc b/src/cssparser.cc index 28b3badb..5096fb96 100644 --- a/src/cssparser.cc +++ b/src/cssparser.cc @@ -1261,7 +1261,7 @@ bool CssParser::parseSimpleSelector(CssSimpleSelector *selector) if (selectType != CssSimpleSelector::SELECT_NONE) { nextToken(); if (spaceSeparated) - return true; + return false; if (ttype == CSS_TK_SYMBOL) { selector->setSelect (selectType, tval); diff --git a/src/domainrc b/src/domainrc index 44380fd0..eaed9e8e 100644 --- a/src/domainrc +++ b/src/domainrc @@ -22,10 +22,18 @@ default accept # Let's block some of the most notorious ad sites and trackers. +* .2o7.net * .admt.com * .adnxs.com +* .atdmt.com +* .collective-media.net * .crwdcntrl.com * .doubleclick.net +* .effectivemeasure.net +* .googleadservices.com +* .imrworldwide.com * .quantserve.com +* .revsci.net * .scorecardresearch.com +* .webtrendslive.com * .yieldmanager.com diff --git a/src/findbar.cc b/src/findbar.cc index 28790563..f376895f 100644 --- a/src/findbar.cc +++ b/src/findbar.cc @@ -118,14 +118,14 @@ Findbar::Findbar(int width, int height) : box(FL_THIN_UP_BOX); - hide_btn = new Fl_Button(x, border, 16, height, 0); + hide_btn = new CustButton(x, border, 16, height, 0); hideImg = new Fl_Pixmap(new_s_xpm); hide_btn->image(hideImg); x += 16 + gap; hide_btn->callback(hide_cb, this); hide_btn->clear_visible_focus(); hide_btn->box(FL_THIN_UP_BOX); - hide_btn->tooltip("Hide"); + hide_btn->set_tooltip("Hide"); add(hide_btn); i = new MyInput(x, border, input_width, height); @@ -135,24 +135,24 @@ Findbar::Findbar(int width, int height) : i->when(FL_WHEN_NEVER); add(i); - next_btn = new Fl_Button(x, border, button_width, height, "Next"); + next_btn = new CustButton(x, border, button_width, height, "Next"); x += button_width + gap; next_btn->shortcut(FL_Enter); next_btn->callback(search_cb, this); next_btn->clear_visible_focus(); next_btn->box(FL_THIN_UP_BOX); - next_btn->tooltip("Find next occurrence of the search phrase\n" - "shortcut: Enter"); + next_btn->set_tooltip("Find next occurrence of the search phrase\n" + "shortcut: Enter"); add(next_btn); - prev_btn= new Fl_Button(x, border, button_width, height, "Previous"); + prev_btn= new CustButton(x, border, button_width, height, "Previous"); x += button_width + gap; prev_btn->shortcut(FL_SHIFT+FL_Enter); prev_btn->callback(searchBackwards_cb, this); prev_btn->clear_visible_focus(); prev_btn->box(FL_THIN_UP_BOX); - prev_btn->tooltip("Find previous occurrence of the search phrase\n" - "shortcut: Shift+Enter"); + prev_btn->set_tooltip("Find previous occurrence of the search phrase\n" + "shortcut: Shift+Enter"); add(prev_btn); check_btn = new Fl_Check_Button(x, border, 2*button_width, height, diff --git a/src/findbar.hh b/src/findbar.hh index 72d24c44..d91c42df 100644 --- a/src/findbar.hh +++ b/src/findbar.hh @@ -8,12 +8,13 @@ #include <FL/Fl_Group.H> #include <FL/Fl_Check_Button.H> +#include "tipwin.hh" + /* * Searchbar to find text in page. */ class Findbar : public Fl_Group { - Fl_Button *clrb; - Fl_Button *hide_btn, *next_btn, *prev_btn; + CustButton *hide_btn, *next_btn, *prev_btn; Fl_Check_Button *check_btn; Fl_Pixmap *hideImg; Fl_Input *i; diff --git a/src/html.cc b/src/html.cc index 1803e68c..ea675c1a 100644 --- a/src/html.cc +++ b/src/html.cc @@ -2969,10 +2969,10 @@ void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url) ++html->bw->NumPendingStyleSheets; a_Bw_add_client(html->bw, ClientKey, 0); a_Bw_add_url(html->bw, url); - MSG("NumPendingStyleSheets=%d", html->bw->NumPendingStyleSheets); + MSG("NumPendingStyleSheets=%d\n", html->bw->NumPendingStyleSheets); } } - MSG("\n"); + _MSG("\n"); } /* diff --git a/src/tipwin.cc b/src/tipwin.cc new file mode 100644 index 00000000..1b6d91a2 --- /dev/null +++ b/src/tipwin.cc @@ -0,0 +1,224 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <FL/fl_draw.H> +#include <FL/Fl.H> +#include <FL/Fl_Group.H> +#include <FL/Fl_Menu_Window.H> +#include <FL/Fl_Tooltip.H> +#include <FL/Fl_Button.H> + +#include "tipwin.hh" + +/* + * Forward declarations + */ +static void show_timeout(void*); +static void recent_timeout(void*); + +/* + * Custom tooltip window + */ +TipWin::TipWin() : Fl_Menu_Window(1, 1) // will autosize +{ + bgcolor = fl_color_cube(FL_NUM_RED - 1, FL_NUM_GREEN - 1, FL_NUM_BLUE - 2); + recent = 0; + strcpy(tip, ""); + cur_widget = NULL; + set_override(); // no border + end(); +} + +void TipWin::draw() +{ + draw_box(FL_BORDER_BOX, 0, 0, w(), h(), bgcolor); + fl_color(FL_BLACK); + fl_font(labelfont(), labelsize()); + fl_draw(tip, 3, 3, w() - 6, h() - 6, + //Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_WRAP)); + Fl_Align(FL_ALIGN_LEFT)); +} + +void TipWin::value(const char *s) { + // Recalc size of window + snprintf(tip, sizeof(tip) - 1, "%s", s); + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + W = 0; + fl_measure(tip, W, H, 0); + W += 8; H += 8; + size(W, H); + redraw(); +} + +void TipWin::do_show(void *wid) { + cur_widget = wid; // Keep track of requesting widget + Fl::add_timeout(recent ? 0.2f : 0.8f, show_timeout); +} + +void TipWin::do_hide() { + Fl::remove_timeout(show_timeout); + if (shown()) { + hide(); + recent = 1; + Fl::add_timeout(0.8f, recent_timeout); + } +} + +void TipWin::recent_tooltip(int val) { + recent = val; +} + +//-------------------------------------------------------------------------- + +TipWin *my_tipwin(void) +{ + static TipWin *tw = NULL; + + if (!tw) { + Fl_Group *save = Fl_Group::current(); // save current widget.. + tw = new TipWin(); // ..because this trashes it + tw->hide(); // start hidden + Fl_Group::current(save); // ..then back to previous. + } + return tw; +} + +static void show_timeout(void*) { + // if offscreen, move tip ABOVE mouse instead + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + int ty = Fl::event_y_root() + 20; + if (ty + my_tipwin()->h() > scr_h) + ty = Fl::event_y_root() - 20 - my_tipwin()->h(); + if (ty < 0) ty = 0; + + my_tipwin()->position(Fl::event_x_root(), ty); + my_tipwin()->show(); + my_tipwin()->recent_tooltip(0); +} + +static void recent_timeout(void*) { + my_tipwin()->recent_tooltip(0); +} + + +//--------------------------------------------------------------------------- + +/* + * A Button sharing a custom tooltip window + */ +TipWinButton::TipWinButton(int x, int y, int w, int h, const char *l) : + Fl_Button(x, y, w, h, l) +{ + tipwin = my_tipwin(); + mytooltip = strdup("empty"); +} + +TipWinButton::~TipWinButton(void) +{ + tipwin->cancel(this); // cancel tooltip if shown + free(mytooltip); +} + +int TipWinButton::handle(int e) +{ + switch (e) { + case FL_ENTER: + tipwin->value(mytooltip); + tipwin->do_show(this); + break; + case FL_PUSH: // push mouse + case FL_RELEASE: // release mouse + case FL_HIDE: // widget goes away + case FL_LEAVE: // leave focus + tipwin->do_hide(); + break; + } + return (Fl_Button::handle(e)); +} + +void TipWinButton::set_tooltip(const char *s) +{ + free(mytooltip); + mytooltip = strdup(s); +} + + +//--------------------------------------------------------------------------- + +/* + * A Light Button sharing a custom tooltip window + */ +CustButton::CustButton(int x, int y, int w, int h, const char *l) : + TipWinButton(x,y,w,h,l) +{ + norm_color = color(); + light_color = 17; // {17,26,51} +} + +int CustButton::handle(int e) +{ + if (active()) { + if (e == FL_ENTER) { + color(light_color); + redraw(); + } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) { + color(norm_color); + redraw(); + } + } else if (e == FL_DEACTIVATE && color() != norm_color) { + color(norm_color); + redraw(); + } + return TipWinButton::handle(e); +} + +void CustButton::hl_color(Fl_Color col) +{ + light_color = col; +} + + +//--------------------------------------------------------------------------- + +/* + * An Input with custom tooltip window + */ +TipWinInput::TipWinInput (int x, int y, int w, int h, const char *l) : + Fl_Input(x,y,w,h,l) +{ + tipwin = my_tipwin(); + mytooltip = strdup("empty"); +} + +TipWinInput::~TipWinInput(void) +{ + tipwin->cancel(this); // cancel tooltip if shown + free(mytooltip); +} + +int TipWinInput::handle(int e) +{ + switch (e) { + case FL_ENTER: + tipwin->value(mytooltip); + tipwin->do_show(this); + break; + case FL_PUSH: // push mouse + case FL_RELEASE: // release mouse + case FL_HIDE: // widget goes away + case FL_LEAVE: // leave focus + case FL_KEYBOARD: // key press + tipwin->do_hide(); + break; + } + return (Fl_Input::handle(e)); +} + +void TipWinInput::set_tooltip(const char *s) +{ + free(mytooltip); + mytooltip = strdup(s); +} + diff --git a/src/tipwin.hh b/src/tipwin.hh new file mode 100644 index 00000000..d3aeeac5 --- /dev/null +++ b/src/tipwin.hh @@ -0,0 +1,74 @@ +#ifndef __TIPWIN_HH__ +#define __TIPWIN_HH__ + +#include <FL/Fl_Menu_Window.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Input.H> + + +/* + * Custom tooltip window + */ +class TipWin : public Fl_Menu_Window { + char tip[256]; + int bgcolor, recent; + void *cur_widget; +public: + TipWin(); + void draw(); + void value(const char *s); + void do_show(void *wid); + void do_hide(); + void recent_tooltip(int val); + + void cancel(void *wid) { + if (wid == cur_widget) { cur_widget = NULL; do_hide(); } + } +}; + +extern TipWin *my_tipwin(void); + + +/* + * A Button sharing a custom tooltip window + */ +class TipWinButton : public Fl_Button { + char *mytooltip; + TipWin *tipwin; + public: + TipWinButton(int x, int y, int w, int h, const char *l = 0); + ~TipWinButton(); + virtual int handle(int e); + + void set_tooltip(const char *s); +}; + +/* + * A button that highlights on mouse over + */ +class CustButton : public TipWinButton { + Fl_Color norm_color, light_color; +public: + CustButton(int x, int y, int w, int h, const char *l=0); + virtual int handle(int e); + void hl_color(Fl_Color col); +}; + + +/* + * An Input with custom tooltip window + */ +class TipWinInput : public Fl_Input { + char *mytooltip; + TipWin *tipwin; +public: + TipWinInput (int x, int y, int w, int h, const char* l=0); + ~TipWinInput(void); + virtual int handle(int e); + + void set_tooltip(const char *s); +}; + + +#endif // __TIPWIN_HH__ + @@ -19,6 +19,7 @@ #include "msg.h" #include "timeout.hh" #include "utf8.hh" +#include "tipwin.hh" #include <FL/Fl.H> #include <FL/Fl_Pixmap.H> @@ -88,11 +89,11 @@ static struct iconset *icons = &standard_icons; /* * (Used to avoid certain shortcuts in the location bar) */ -class CustInput : public Fl_Input { +class CustInput : public TipWinInput { public: CustInput (int x, int y, int w, int h, const char* l=0) : - Fl_Input(x,y,w,h,l) {}; - int handle(int e); + TipWinInput(x,y,w,h,l) {}; + virtual int handle(int e); }; /* @@ -150,7 +151,7 @@ int CustInput::handle(int e) } } - return Fl_Input::handle(e); + return TipWinInput::handle(e); } //---------------------------------------------------------------------------- @@ -158,10 +159,10 @@ int CustInput::handle(int e) /* * Used to handle "paste" within the toolbar's Clear button. */ -class CustPasteButton : public CustLightButton { +class CustPasteButton : public CustButton { public: CustPasteButton(int x, int y, int w, int h, const char *l=0) : - CustLightButton(x,y,w,h,l) {}; + CustButton(x,y,w,h,l) {}; int handle(int e); }; @@ -175,7 +176,7 @@ int CustPasteButton::handle(int e) return 1; } } - return CustLightButton::handle(e); + return CustButton::handle(e); } //---------------------------------------------------------------------------- @@ -379,13 +380,13 @@ static void bugmeter_cb(Fl_Widget *wid, void *data) /* * Make a generic navigation button */ -Fl_Button *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg, - int b_n, int start) +CustButton *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg, + int b_n, int start) { if (start) p_xpos = 0; - Fl_Button *b = new CustLightButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL); + CustButton *b = new CustButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL); if (img) b->image(img); if (deimg) @@ -413,14 +414,14 @@ void UI::make_toolbar(int tw, int th) Bookmarks = make_button("Book", icons->ImgBook, NULL, UI_BOOK); Tools = make_button("Tools", icons->ImgTools, NULL, UI_TOOLS); - Back->tooltip("Previous page"); - Forw->tooltip("Next page"); - Home->tooltip("Go to the Home page"); - Reload->tooltip("Reload"); - Save->tooltip("Save this page"); - Stop->tooltip("Stop loading"); - Bookmarks->tooltip("View bookmarks"); - Tools->tooltip("Settings"); + Back->set_tooltip("Previous page"); + Forw->set_tooltip("Next page"); + Home->set_tooltip("Go to the Home page"); + Reload->set_tooltip("Reload"); + Save->set_tooltip("Save this page"); + Stop->set_tooltip("Stop loading"); + Bookmarks->set_tooltip("View bookmarks"); + Tools->set_tooltip("Settings"); } /* @@ -428,37 +429,38 @@ void UI::make_toolbar(int tw, int th) */ void UI::make_location(int ww) { - Fl_Button *b; + CustButton *b; - Clear = b = new CustPasteButton(p_xpos,0,16,lh,0); + b = Clear = (CustButton*) new CustPasteButton(p_xpos,0,16,lh,0); b->image(icons->ImgClear); b->callback(clear_cb, this); b->clear_visible_focus(); b->box(FL_THIN_UP_BOX); - b->tooltip("Clear the URL box.\nMiddle-click to paste a URL."); + b->set_tooltip("Clear the URL box.\nMiddle-click to paste a URL."); p_xpos += b->w(); - Fl_Input *i = Location = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0); + CustInput *i = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0); + Location = i; i->color(CuteColor); i->when(FL_WHEN_ENTER_KEY); i->callback(location_cb, this); - i->tooltip("Location"); + i->set_tooltip("Location"); p_xpos += i->w(); - Search = b = new CustLightButton(p_xpos,0,16,lh,0); + Search = b = new CustButton(p_xpos,0,16,lh,0); b->image(icons->ImgSearch); b->callback(search_cb, this); b->clear_visible_focus(); b->box(FL_THIN_UP_BOX); - b->tooltip("Search the Web"); + b->set_tooltip("Search the Web"); p_xpos += b->w(); - Help = b = new CustLightButton(p_xpos,0,16,lh,0); + Help = b = new CustButton(p_xpos,0,16,lh,0); b->image(icons->ImgHelp); b->callback(help_cb, this); b->clear_visible_focus(); b->box(FL_THIN_UP_BOX); - b->tooltip("Help"); + b->set_tooltip("Help"); p_xpos += b->w(); } @@ -489,10 +491,10 @@ void UI::make_progress_bars(int wide, int thin_up) */ Fl_Widget *UI::make_filemenu_button() { - Fl_Button *btn; + CustButton *btn; int w = 0, h = 0, padding; - FileButton = btn = new Fl_Button(p_xpos,0,bw,bh,"W"); + FileButton = btn = new CustButton(p_xpos,0,bw,bh,"W"); btn->labeltype(FL_FREE_LABELTYPE); btn->measure_label(w, h); padding = w; @@ -504,7 +506,7 @@ Fl_Widget *UI::make_filemenu_button() _MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding); btn->box(FL_THIN_UP_BOX); btn->callback(filemenu_cb, this); - btn->tooltip("File menu"); + btn->set_tooltip("File menu"); btn->clear_visible_focus(); if (!prefs.show_filemenu) btn->hide(); @@ -610,11 +612,11 @@ void UI::make_status_bar(int ww, int wh) StatusOutput->color(FL_GRAY_RAMP + 18); // Bug Meter - BugMeter = new CustLightButton(ww-bm_w,wh-sh,bm_w,sh); + BugMeter = new CustButton(ww-bm_w,wh-sh,bm_w,sh); BugMeter->image(icons->ImgMeterOK); BugMeter->box(FL_THIN_DOWN_BOX); BugMeter->align(FL_ALIGN_INSIDE | FL_ALIGN_TEXT_NEXT_TO_IMAGE); - BugMeter->tooltip("Show HTML bugs\n(right-click for menu)"); + BugMeter->set_tooltip("Show HTML bugs\n(right-click for menu)"); BugMeter->callback(bugmeter_cb, this); BugMeter->clear_visible_focus(); @@ -632,7 +634,6 @@ UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) : LocBar = NavBar = StatusBar = NULL; Tabs = NULL; - TabTooltip = NULL; TopGroup = this; TopGroup->box(FL_NO_BOX); clear_flag(SHORTCUT_LABEL); @@ -691,7 +692,6 @@ UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) : UI::~UI() { _MSG("UI::~UI()\n"); - dFree(TabTooltip); } /* @@ -703,16 +703,6 @@ int UI::handle(int event) int ret = 0; if (event == FL_KEYBOARD) { - /* WORKAROUND: remove the Panel's fltk-tooltip. - * Although the expose event is delivered, it has an offset. This - * extra call avoids the lingering tooltip. */ - if (!Fl::event_inside(Main) && - (Fl::event_inside((Fl_Widget*)tabs()) || - Fl::event_inside(NavBar) || - (LocBar && Fl::event_inside(LocBar)) || - (StatusBar && Fl::event_inside(StatusBar)))) - window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1); - return 0; // Receive as shortcut } else if (event == FL_SHORTCUT) { KeysCommand_t cmd = Keys::getKeyCmd(); @@ -11,6 +11,7 @@ #include <FL/Fl_Image.H> #include <FL/Fl_Tabs.H> +#include "tipwin.hh" #include "findbar.hh" typedef enum { @@ -115,43 +116,16 @@ public: } }; -/* - * A button that highlights on mouse over - */ -class CustLightButton : public Fl_Button { - Fl_Color norm_color, light_color; -public: - CustLightButton(int x, int y, int w, int h, const char *l=0) : - Fl_Button(x,y,w,h,l) { norm_color = color(); light_color = 51; }; - virtual int handle(int e) - { - if (active()) { - if (e == FL_ENTER) { - color(light_color); // {17,26,51} - redraw(); - } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) { - color(norm_color); - redraw(); - } - } else if (e == FL_DEACTIVATE && color() != norm_color) { - color(norm_color); - redraw(); - } - return Fl_Button::handle(e); - } - void hl_color(Fl_Color col) { light_color = col; }; -}; // // UI class definition ------------------------------------------------------- // class UI : public CustGroupVertical { CustTabs *Tabs; - char *TabTooltip; CustGroupVertical *TopGroup; - Fl_Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools, - *Clear, *Search, *Help, *BugMeter, *FileButton; + CustButton *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, + *Tools, *Clear, *Search, *Help, *BugMeter, *FileButton; CustGroupHorizontal *LocBar, *NavBar, *StatusBar; Fl_Input *Location; CustProgressBox *PProg, *IProg; @@ -166,8 +140,8 @@ class UI : public CustGroupVertical { bool PanelTemporary; UIPanelmode Panelmode; - Fl_Button *make_button(const char *label, Fl_Image *img, - Fl_Image*deimg, int b_n, int start = 0); + CustButton *make_button(const char *label, Fl_Image *img, Fl_Image*deimg, + int b_n, int start = 0); void make_toolbar(int tw, int th); void make_location(int ww); void make_progress_bars(int wide, int thin_up); diff --git a/src/uicmd.cc b/src/uicmd.cc index bf4bbe2f..27ad7d49 100644 --- a/src/uicmd.cc +++ b/src/uicmd.cc @@ -84,7 +84,7 @@ class CustTabButton : public Fl_Button { // active one (the highest numbered gets focus). public: CustTabButton (int x,int y,int w,int h, const char* label = 0) : - Fl_Button (x,y,w,h,label) { ui_ = NULL; }; + Fl_Button (x,y,w,h,label) { ui_ = NULL; focus_num_ = 0; }; void ui(UI *pui) { ui_ = pui; } UI *ui(void) { return ui_; } void focus_num(uint_t fn) { focus_num_ = fn; } @@ -107,7 +107,7 @@ class CustTabs : public Fl_Group { Fl_Scroll *Scroll; Fl_Pack *Pack; Fl_Group *Control; - CustLightButton *CloseBtn; + CustButton *CloseBtn; int tabcolor_inactive, tabcolor_active; void update_pack_offset(void); @@ -151,12 +151,12 @@ public: /* control buttons go inside a group */ Control = new Fl_Group(ww-ctl_w,0,ctl_w,ctab_h); - CloseBtn = new CustLightButton(ww-ctl_w+2,0,btn_w,ctab_h, "X"); + CloseBtn = new CustButton(ww-ctl_w+2,0,btn_w,ctab_h, "X"); CloseBtn->box(FL_THIN_UP_BOX); CloseBtn->labelcolor(0x00641000); CloseBtn->hl_color(FL_WHITE); CloseBtn->clear_visible_focus(); - CloseBtn->tooltip(prefs.right_click_closes_tab ? + CloseBtn->set_tooltip(prefs.right_click_closes_tab ? "Close current tab.\nor Right-click tab label to close." : "Close current tab.\nor Middle-click tab label to close."); CloseBtn->callback(close_tab_btn_cb, this); @@ -290,8 +290,6 @@ UI *CustTabs::add_new_tab(UI *old_ui, int focus) if (focus) { switch_tab(btn); } else if (num_tabs() == 2) { - increase_focus_counter(); - btn->focus_num(focus_counter); // no focus and tabbar added: redraw current page Wizard->redraw(); } |