diff --git a/toonz/sources/tnztools/brushtool.cpp b/toonz/sources/tnztools/brushtool.cpp
index 2671078..e08e98d 100644
--- a/toonz/sources/tnztools/brushtool.cpp
+++ b/toonz/sources/tnztools/brushtool.cpp
@@ -1262,6 +1262,12 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
 
       TPointD halfThick(maxThick * 0.5, maxThick * 0.5);
       TRectD invalidateRect(pos - halfThick, pos + halfThick);
+      TPointD dpi;
+      ri->getDpi(dpi.x, dpi.y);
+      TRectD previousTipRect(m_brushPos - halfThick, m_brushPos + halfThick);
+      if (dpi.x > Stage::inch || dpi.y > Stage::inch)
+        previousTipRect *= dpi.x / Stage::inch;
+      invalidateRect += previousTipRect;
 
       // if the drawOrder mode = "Palette Order",
       // get styleId list which is above the current style in the palette
@@ -1324,7 +1330,7 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
       /*-- 作業中のFidを登録 --*/
       m_workingFrameId = getFrameId();
 
-      invalidate(invalidateRect);
+      invalidate(invalidateRect.enlarge(2));
     }
   } else {  // vector happens here
     m_track.clear();
@@ -1346,6 +1352,9 @@ void BrushTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
       addTrackPoint(TThickPoint(pos, thickness),
                     getPixelSize() * getPixelSize());
   }
+
+  // updating m_brushPos is needed to refresh viewer properly
+  m_brushPos = m_mousePos = pos;
 }
 
 //-------------------------------------------------------------------------------------------------------------
@@ -1464,6 +1473,13 @@ void BrushTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
         m_strokeRect += bbox;
       }
     }
+
+    // draw brush tip when drawing smooth stroke
+    if (m_smooth.getValue() != 0) {
+      TPointD halfThick(m_maxThick * 0.5, m_maxThick * 0.5);
+      invalidateRect += TRectD(m_brushPos - halfThick, m_brushPos + halfThick);
+    }
+
     invalidate(invalidateRect.enlarge(2));
   } else {
     double thickness =
@@ -2052,6 +2068,10 @@ void BrushTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
   // locals.addMinMax(
   //  TToonzImageP(getImage(false, 1)) ? m_rasThickness : m_thickness, add);
   //} else
+
+  TPointD halfThick(m_maxThick * 0.5, m_maxThick * 0.5);
+  TRectD invalidateRect(m_brushPos - halfThick, m_brushPos + halfThick);
+
   if (e.isCtrlPressed() && e.isAltPressed() && !e.isShiftPressed()) {
     const TPointD &diff = pos - m_mousePos;
     double max          = diff.x / 2;
@@ -2060,6 +2080,13 @@ void BrushTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
     locals.addMinMaxSeparate(
         (m_targetType & TTool::ToonzImage) ? m_rasThickness : m_thickness, min,
         max);
+
+    double radius = (m_targetType & TTool::ToonzImage)
+                        ? m_rasThickness.getValue().second * 0.5
+                        : m_thickness.getValue().second * 0.5;
+    invalidateRect += TRectD(m_brushPos - TPointD(radius, radius),
+                             m_brushPos + TPointD(radius, radius));
+
   } else {
     m_mousePos = pos;
     m_brushPos = pos;
@@ -2072,9 +2099,10 @@ void BrushTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
       checkGuideSnapping(true);
       m_brushPos = m_firstSnapPoint;
     }
+    invalidateRect += TRectD(pos - halfThick, pos + halfThick);
   }
-  // TODO: this can be partial update for toonz raster brush
-  invalidate();
+
+  invalidate(invalidateRect.enlarge(2));
 
   if (m_minThick == 0 && m_maxThick == 0) {
     if (m_targetType & TTool::ToonzImage) {
@@ -2199,8 +2227,8 @@ void BrushTool::checkGuideSnapping(bool beforeMousePress) {
         snapPoint.x = hGuide;
       }
       beforeMousePress ? m_foundFirstSnap = true : m_foundLastSnap = true;
-      beforeMousePress ? m_firstSnapPoint = snapPoint : m_lastSnapPoint =
-                                                            snapPoint;
+      beforeMousePress ? m_firstSnapPoint                          = snapPoint
+                       : m_lastSnapPoint                           = snapPoint;
     }
   }
 }
@@ -2272,11 +2300,15 @@ void BrushTool::draw() {
     TRasterP ras = ti->getRaster();
     int lx       = ras->getLx();
     int ly       = ras->getLy();
-
     drawEmptyCircle(m_brushPos, tround(m_minThick), lx % 2 == 0, ly % 2 == 0,
                     m_pencil.getValue());
     drawEmptyCircle(m_brushPos, tround(m_maxThick), lx % 2 == 0, ly % 2 == 0,
                     m_pencil.getValue());
+  } else if (m_targetType & TTool::ToonzImage) {
+    drawEmptyCircle(m_brushPos, tround(m_minThick), true, true,
+                    m_pencil.getValue());
+    drawEmptyCircle(m_brushPos, tround(m_maxThick), true, true,
+                    m_pencil.getValue());
   } else {
     tglDrawCircle(m_brushPos, 0.5 * m_minThick);
     tglDrawCircle(m_brushPos, 0.5 * m_maxThick);
@@ -2288,7 +2320,7 @@ void BrushTool::draw() {
 void BrushTool::onEnter() {
   TImageP img = getImage(false);
 
-  if (TToonzImageP(img)) {
+  if (m_targetType & TTool::ToonzImage) {
     m_minThick = m_rasThickness.getValue().first;
     m_maxThick = m_rasThickness.getValue().second;
   } else {
@@ -2382,11 +2414,9 @@ bool BrushTool::onPropertyChanged(std::string propertyName) {
 
   /*--- 変更されたPropertyに合わせて処理を分ける ---*/
 
-  /*--- m_thicknessとm_rasThicknessは同じName(="Size:")なので、
-          扱っている画像がラスタかどうかで区別する---*/
+  /*--- determine which type of brush to be modified ---*/
   if (propertyName == m_thickness.getName()) {
-    TImageP img = getImage(false);
-    if (TToonzImageP(img))  // raster
+    if (m_targetType & TTool::ToonzImage)  // raster
     {
       RasterBrushMinSize = m_rasThickness.getValue().first;
       RasterBrushMaxSize = m_rasThickness.getValue().second;
diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp
index 3516868..10c5a77 100644
--- a/toonz/sources/toonz/sceneviewer.cpp
+++ b/toonz/sources/toonz/sceneviewer.cpp
@@ -522,7 +522,7 @@ void SceneViewer::setVisual(const ImagePainter::VisualSettings &settings) {
   m_visualSettings = settings;
   m_visualSettings.m_sceneProperties =
       TApp::instance()->getCurrentScene()->getScene()->getProperties();
-  if (repaint) update();
+  if (repaint) GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
@@ -602,7 +602,7 @@ void SceneViewer::freeze(bool on) {
     setCursor(Qt::ForbiddenCursor);
     m_freezedStatus = UPDATE_FREEZED;
   }
-  update();
+  GLInvalidateAll();
 }
 
 //-------------------------------------------------------------------------------
@@ -633,7 +633,7 @@ void SceneViewer::enablePreview(int previewMode) {
 
   m_previewMode = previewMode;
 
-  update();
+  GLInvalidateAll();
 
   // for updating the title bar
   emit previewToggled();
@@ -1715,7 +1715,12 @@ void SceneViewer::GLInvalidateAll() {
 //-----------------------------------------------------------------------------
 
 void SceneViewer::GLInvalidateRect(const TRectD &rect) {
-  m_clipRect = rect;
+  // there is a case that this function is called more than once before
+  // paintGL() is called
+  if (!m_clipRect.isEmpty())
+    m_clipRect += rect;
+  else
+    m_clipRect = rect;
   update();
   if (m_vRuler) m_vRuler->update();
   if (m_hRuler) m_hRuler->update();
@@ -2154,7 +2159,7 @@ void SceneViewer::onXsheetChanged() {
   TTool *tool    = TApp::instance()->getCurrentTool()->getTool();
   if (tool && tool->isEnabled()) tool->updateMatrix();
   onLevelChanged();
-  update();
+  GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
@@ -2163,14 +2168,14 @@ void SceneViewer::onObjectSwitched() {
   TTool *tool = TApp::instance()->getCurrentTool()->getTool();
   if (tool && tool->isEnabled()) tool->updateMatrix();
   onLevelChanged();
-  update();
+  GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
 
 void SceneViewer::onSceneChanged() {
   onLevelChanged();
-  update();
+  GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
@@ -2185,7 +2190,7 @@ void SceneViewer::onFrameSwitched() {
     tool->onEnter();
   }
 
-  update();
+  GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
@@ -2194,7 +2199,7 @@ void SceneViewer::onFrameSwitched() {
 void SceneViewer::onToolChanged() {
   TTool *tool = TApp::instance()->getCurrentTool()->getTool();
   if (tool) setToolCursor(this, tool->getCursorId());
-  update();
+  GLInvalidateAll();
 }
 
 //-----------------------------------------------------------------------------
diff --git a/toonz/sources/toonz/sceneviewerevents.cpp b/toonz/sources/toonz/sceneviewerevents.cpp
index f997fac..8317664 100644
--- a/toonz/sources/toonz/sceneviewerevents.cpp
+++ b/toonz/sources/toonz/sceneviewerevents.cpp
@@ -1046,7 +1046,7 @@ bool SceneViewer::event(QEvent *e) {
   if (e->type() == QEvent::MouseButtonPress)
     clock.start();
   else if (e->type() == QEvent::MouseMove) {
-    if (clock.elapsed() < 10) {
+    if (clock.isValid() && clock.elapsed() < 10) {
       e->accept();
       return true;
     }