aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2011-07-08 11:56:42 -0400
committerJorge Arellano Cid <jcid@dillo.org>2011-07-08 11:56:42 -0400
commit165d9c378d9d4153b7396066bb0651737ea17add (patch)
tree26fbac7e2c687b488653714b4780a8b14184da9b
parent97932ddbd2fd08d6123e89bf8d25c31f29157d43 (diff)
Workaround: fixes hiding a tooltip with the keyboard or mousewheel
This is a complex problem where it is not clear whether the bug lies in dillo, fltk, or in their interaction. Tooltip handling is fuzzy in FLTK, and there are glitches in it; trying to "fix" it inside dillo produces partial solutions. OTOH, although implementing custom tooltip handling adds complexity, it provides a solution that so far works in all the testcases.
-rw-r--r--dw/fltkplatform.cc69
-rw-r--r--dw/fltkviewbase.cc6
2 files changed, 67 insertions, 8 deletions
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index f45a15db..5d954147 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -25,20 +25,28 @@
#include "fltkcore.hh"
#include <FL/fl_draw.H>
+#include <FL/Fl_Box.H>
#include <FL/Fl_Tooltip.H>
+#include <FL/Fl_Menu_Window.H>
#include <FL/Fl_Paged_Device.H>
-/* Use of Fl_Text_Display links in a lot of printer code that we don't have
- * any need for currently. This stub prevents that.
+/*
+ * Local data
*/
+
+/* Use of Fl_Text_Display links in a lot of printer code that we don't have
+ * any need for currently. This stub prevents that. */
class FL_EXPORT Fl_Printer : public Fl_Paged_Device {
public:
static const char *class_id;
Fl_Printer(void) {};
};
-
const char *Fl_Printer::class_id = "Fl_Printer";
+/* Tooltips */
+static Fl_Menu_Window *tt_window = NULL;
+static int in_tooltip = 0;
+dw::core::style::Tooltip *tt_active = NULL;
namespace dw {
namespace fltk {
@@ -242,8 +250,10 @@ FltkColor * FltkColor::create (int col)
FltkTooltip::FltkTooltip (const char *text) : Tooltip(text)
{
- if (!strchr(text, '@')) {
+ if (!text) {
escaped_str = NULL;
+ } else if (!strchr(text, '@')) {
+ escaped_str = strdup(text);
} else {
/* FLTK likes to interpret symbols, and so they must be escaped */
const char *src = text;
@@ -262,6 +272,8 @@ FltkTooltip::~FltkTooltip ()
{
if (escaped_str)
free(escaped_str);
+ if (in_tooltip && this == tt_active)
+ onLeave(); /* hide tooltip window */
}
FltkTooltip *FltkTooltip::create (const char *text)
@@ -271,15 +283,56 @@ FltkTooltip *FltkTooltip::create (const char *text)
void FltkTooltip::onEnter()
{
- Fl_Widget *widget = Fl::belowmouse();
+ _MSG("FltkTooltip::onEnter\n");
+ if (!escaped_str || !*escaped_str)
+ return;
+
+ if (!tt_window) {
+ tt_window = new Fl_Menu_Window(0,0,100,24);
+ tt_window->set_override();
+ tt_window->box(FL_NO_BOX);
+ Fl_Box *b = new Fl_Box(0,0,100,24);
+ b->box(FL_BORDER_BOX);
+ b->color(fl_color_cube(FL_NUM_RED-1, FL_NUM_GREEN-1, FL_NUM_BLUE-2));
+ b->labelfont(FL_HELVETICA);
+ b->labelsize(14);
+ b->align(FL_ALIGN_WRAP);
+ tt_window->resizable(b);
+ tt_window->end();
+ }
- Fl_Tooltip::enter_area(widget, widget->x(), widget->y(), widget->w(),
- widget->h(), escaped_str ? escaped_str : str);
+ /* prepare tooltip window */
+ int x, y;
+ Fl_Box *box = (Fl_Box*)tt_window->child(0);
+ box->label(escaped_str);
+ Fl::get_mouse(x,y); y += 6;
+ /* calculate window size */
+ fl_font(box->labelfont(), box->labelsize());
+ int ww, hh;
+ ww = 800; // max width;
+ fl_measure(escaped_str,ww,hh,FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
+ ww += 6; hh += 6;
+ tt_window->resize(x,y,ww,hh);
+ tt_window->show();
+ in_tooltip = 1;
+ tt_active = this;
}
void FltkTooltip::onLeave()
{
- Fl_Tooltip::exit(NULL);
+ _MSG(" FltkTooltip::onLeave in_tooltip=%d\n", in_tooltip);
+ if (!in_tooltip) return;
+ in_tooltip = 0;
+ tt_active = NULL;
+ tt_window->hide();
+
+ /* WORKAROUND: (Black magic here)
+ * Hiding a tooltip with the keyboard or mousewheel doesn't work.
+ * The code below "fixes" the problem */
+ Fl_Widget *widget = Fl::belowmouse();
+ if (widget && widget->window()) {
+ widget->window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1);
+ }
}
void FltkTooltip::onMotion()
diff --git a/dw/fltkviewbase.cc b/dw/fltkviewbase.cc
index 9e23cf19..066d3354 100644
--- a/dw/fltkviewbase.cc
+++ b/dw/fltkviewbase.cc
@@ -182,6 +182,9 @@ void FltkViewBase::draw (const core::Rectangle *rect,
fl_rectf (X, Y, W, H);
theLayout->expose (this, &r);
}
+ // DEBUG:
+ //fl_color(FL_RED);
+ //fl_rect(X, Y, W, H);
exposeArea = NULL;
}
@@ -274,6 +277,9 @@ int FltkViewBase::handle (int event)
getDwButtonState ());
return Fl_Group::handle (event);
+ case FL_HIDE:
+ /* WORKAROUND: strangely, the tooltip window is not automatically hidden
+ * with its parent. Here we fake a LEAVE to achieve it. */
case FL_LEAVE:
theLayout->leaveNotify (this, getDwButtonState ());
return Fl_Group::handle (event);