Description: Fix flickering - in GR_Caret::s_blink_timeout, avoid repeated calls by stopping the timer, it will be restarted when needed, . - in GR_Caret::s_enable, avoid extra unnecessary _blink calls when blink is enabled, as they serve no purpose, . - in XAP_UnixFrameImpl::_fe::expose, use the Cairo clip rectangle instead of the expose event area, thanks to Hubert Figuière in 865c1dda7e13deff04573ffc42028b71fee07f9c, . - in XAP_UnixFrameImpl::_fe::expose, do not return FALSE, as other handlers will need to handle the draw event, . - in GR_UnixCairoGraphics::flush, fix excessive draw events; gtk_widget_queue_draw only marks the widget as needing redrawing, which causes a draw event for each call to flush, therefore every caret blink, so use gdk_flush instead, Author: James Cameron Origin: other Bug: https://bugzilla.abisource.com/show_bug.cgi?id=13791 Bug-SugarLabs: https://bugs.sugarlabs.org/ticket/4915 Bug-Ubuntu: https://pad.lv/1574278 Last-Update: 2017-09-24 --- a/src/af/gr/gtk/gr_UnixCairoGraphics.cpp +++ b/src/af/gr/gtk/gr_UnixCairoGraphics.cpp @@ -577,9 +577,7 @@ void GR_UnixCairoGraphics::_endPaint() void GR_UnixCairoGraphics::flush(void) { - if (m_Widget) { - gtk_widget_queue_draw(m_Widget); - } + gdk_flush(); } bool GR_UnixCairoGraphics::queryProperties(GR_Graphics::Properties gp) const --- a/src/af/gr/xp/gr_Caret.cpp +++ b/src/af/gr/xp/gr_Caret.cpp @@ -155,22 +155,17 @@ void GR_Caret::s_enable(UT_Worker * _w) { GR_Caret * c = static_cast(_w->getInstanceData()); + c->m_enabler->stop(); c->m_worker->stop(); - c->_blink(true); - if (!c->m_bCursorIsOn) - c->_blink(true); // blink again - else - { - c->_blink(true); // ?? - MARCM - c->_blink(true); - } c->m_worker->start(); - c->m_enabler->stop(); + c->_blink(true); } void GR_Caret::s_blink_timeout(UT_Worker * _w) { GR_Caret * c = static_cast(_w->getInstanceData()); + + c->m_blinkTimeout->stop(); if (c->isEnabled()) c->disable(); } --- a/src/af/xap/gtk/xap_UnixFrameImpl.cpp +++ b/src/af/xap/gtk/xap_UnixFrameImpl.cpp @@ -1215,8 +1215,16 @@ gboolean XAP_UnixFrameImpl::_fe::expose( { XAP_UnixFrameImpl * pUnixFrameImpl = static_cast(g_object_get_data(G_OBJECT(w), "user_data")); FV_View * pView = static_cast(pUnixFrameImpl->getFrame()->getCurrentView()); + double x, y, width, height; #if GTK_CHECK_VERSION(3,0,0) - GdkEventExpose *pExposeEvent = reinterpret_cast(gtk_get_current_event()); + cairo_clip_extents (cr, &x, &y, &width, &height); + width -= x; + height -= y; +#else + x = pExposeEvent->area.x; + y = pExposeEvent->area.y; + width = pExposeEvent->area.width; + height = pExposeEvent->area.height; #endif /* Jean: commenting out next lines since the zoom update code does draw only * part of what needs to be updated. */ @@ -1230,16 +1238,17 @@ gboolean XAP_UnixFrameImpl::_fe::expose( UT_Rect rClip; if (pGr->getPaintCount () > 0) return TRUE; - xxx_UT_DEBUGMSG(("Expose area: x %d y %d width %d height %d \n",pExposeEvent->area.x,pExposeEvent->area.y,pExposeEvent->area.width,pExposeEvent->area.height)); - rClip.left = pGr->tlu(pExposeEvent->area.x); - rClip.top = pGr->tlu(pExposeEvent->area.y); - rClip.width = pGr->tlu(pExposeEvent->area.width)+1; - rClip.height = pGr->tlu(pExposeEvent->area.height)+1; + rClip.left = pGr->tlu(x); + rClip.top = pGr->tlu(y); #if GTK_CHECK_VERSION(3,0,0) + rClip.width = pGr->tlu(width); + rClip.height = pGr->tlu(height); static_cast(pGr)->setCairo(cr); pView->draw(&rClip); static_cast(pGr)->setCairo(NULL); #else + rClip.width = pGr->tlu(width)+1; + rClip.height = pGr->tlu(height)+1; pView->draw(&rClip); #endif }