From 628c92c6a82e42c2f3c7970e64acffac544b5600 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Thu, 26 Oct 2006 06:58:34 +0000 Subject: [PATCH] workaround for crash 1580903 and several other issues caused by GTK's braindead behavior exposed by display interruptibility --- src/dialogs/fill-style.cpp | 6 ++++++ src/dialogs/object-properties.cpp | 16 +++++++++++++++- src/ui/widget/selected-style.cpp | 12 ++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp index 22c1ee0f7..9933887f3 100644 --- a/src/dialogs/fill-style.cpp +++ b/src/dialogs/fill-style.cpp @@ -35,6 +35,7 @@ #include #include #include +#include // These can be deleted once we sort out the libart dependence. @@ -396,9 +397,14 @@ sp_fill_style_widget_paint_changed ( SPPaintSelector *psel, case SP_PAINT_SELECTOR_MODE_COLOR_RGB: case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: { + // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events + sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); + sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity"); sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE, _("Set fill color")); + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); // on release, toggle undo_label so that the next drag will not be lumped with this one if (undo_label == undo_label_1) diff --git a/src/dialogs/object-properties.cpp b/src/dialogs/object-properties.cpp index 77d71b5fe..dc04d2772 100644 --- a/src/dialogs/object-properties.cpp +++ b/src/dialogs/object-properties.cpp @@ -44,6 +44,7 @@ #include "document-private.h" #include #include "xml/repr.h" +#include "display/sp-canvas.h" static GtkWidget *dlg = NULL; static win_data wd; @@ -360,6 +361,9 @@ sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *base) gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (TRUE)); + // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 + sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(SP_ACTIVE_DESKTOP), 0); + SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream os; @@ -373,6 +377,9 @@ sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *base) sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(SP_ACTIVE_DESKTOP)); + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (FALSE)); } @@ -386,12 +393,15 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *base) //lock dialog gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (TRUE)); - + //get desktop SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) { return; } + + // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 + sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); //get current selection Inkscape::Selection *selection = sp_desktop_selection (desktop); @@ -423,6 +433,10 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *base) } sp_document_maybe_done (sp_desktop_document (SP_ACTIVE_DESKTOP), "fillstroke:blur", SP_VERB_DIALOG_FILL_STROKE, _("Change blur")); + + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (FALSE)); } diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 90efd2da5..20398ecd9 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -36,6 +36,7 @@ #include "svg/css-ostringstream.h" #include "helper/units.h" #include "verbs.h" +#include static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 }; static gchar* const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"}; @@ -973,6 +974,7 @@ SelectedStyle::update() case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: _tooltips.set_tip(_opacity_place, _("Master opacity")); + if (_opacity_blocked) break; _opacity_blocked = true; _opacity_sb.set_sensitive(true); _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value)); @@ -1074,10 +1076,20 @@ void SelectedStyle::on_opacity_changed () { Inkscape::CSSOStringStream os; os << CLAMP (_opacity_adjustment.get_value(), 0.0, 1.0); sp_repr_css_set_property (css, "opacity", os.str().c_str()); + // FIXME: workaround for GTK breakage: display interruptibility sometimes results in GTK + // sending multiple value-changed events. As if when Inkscape interrupts redraw for main loop + // iterations, GTK discovers that this callback hasn't finished yet, and for some weird reason + // decides to add yet another value-changed event to the queue. Totally braindead if you ask + // me. As a result, scrolling the spinbutton once results in runaway change until it hits 1.0 + // or 0.0. (And no, this is not a race with ::update, I checked that.) + // Sigh. So we disable interruptibility while we're setting the new value. + sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(_desktop), 0); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); sp_document_maybe_done (sp_desktop_document (_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(_desktop)); spinbutton_defocus(GTK_OBJECT(_opacity_sb.gobj())); _opacity_blocked = false; } -- 2.30.2