=== modified file 'src/com/goldencode/p2j/ui/client/gui/GuiButton.java'
--- old/src/com/goldencode/p2j/ui/client/gui/GuiButton.java	2026-01-14 15:49:34 +0000
+++ new/src/com/goldencode/p2j/ui/client/gui/GuiButton.java	2026-01-27 14:38:53 +0000
@@ -20,6 +20,7 @@
 ** 009 IMS 20250704 The mouseOver modifier has been changed from private to protected. Rfs:#9973.
 ** 010 EVL 20260105 Improved bounds check for mouseExited event to avoid regressions.  We need to check if
 **                  the mouse point is inside possible tooltip overlay window that can overlap the button.
+**     PMP 20260127 TODO
 */
 
 /*
@@ -85,7 +86,6 @@
 import com.goldencode.p2j.ui.client.widget.Container;
 
 import java.awt.event.*;
-import java.util.concurrent.*;
 import java.util.logging.*;
 
 /**
@@ -109,6 +109,12 @@
    /** The mouse is dragging */
    private boolean mouseDragging;
    
+   /** TODO */
+   private Runnable repaintListener = null;
+   
+   /** TODO */
+   private boolean suppressNextEnterRepaint = false;
+
    /**
     * This constructor creates a button with a given text label.
     *
@@ -151,6 +157,44 @@
    }
    
    /**
+    * TODO 
+    * 
+    * @param   listener
+    *          TODO
+    */
+   public void setRepaintListener(Runnable listener)
+   {
+      repaintListener = listener;
+   }
+   
+   /**
+    * TODO
+    */
+   public void runRepaintListener()
+   {
+      if (repaintListener != null)
+      {
+         repaintListener.run();
+      }
+      
+      clearRepaintListener();
+      clearHoverSuppression();
+   }
+   
+   /**
+    * TODO
+    */
+   public void clearHoverSuppression()
+   {
+      suppressNextEnterRepaint = false;
+   }
+   
+   public void clearRepaintListener()
+   {
+      repaintListener = null;
+   }
+   
+   /**
     * Process the notification of a mouse enter event occurred for this widget. Store the new 
     * state and call repaint to update the button's visual.
     *
@@ -163,10 +207,12 @@
       if (isEnabled())
       {
          this.mouseOver = true;
-         if (ThemeManager.getCurrentTheme().isMouseHoverSensitive())
+         // TODO: 
+         if (ThemeManager.getCurrentTheme().isMouseHoverSensitive() && !suppressNextEnterRepaint)
          {
             repaint();
          }
+         clearHoverSuppression();
       }
    }
    
@@ -187,8 +233,34 @@
       
       final int xMouse = e.getXOnScreen();
       final int yMouse = e.getYOnScreen();
-      
-      processMouseExited(xMouse, yMouse);
+            
+      // for certain cases we need to check if we are still inside the button
+      NativePoint p = this.displayPhysicalLocation();
+      CoordinatesConversion cc = screen().coordinates();
+      NativeRectangle rect = cc.rectangleToNative(this.bounds());
+
+      final ToolTip tt = ToolTip.getInstance();
+      // only for buttons with tooltips
+      boolean skipBtnRepaint = xMouse >= p.x && xMouse <= p.x + rect.right() - rect.left() &&
+                               yMouse >= p.y && yMouse <= p.y + rect.bottom() - rect.top() &&
+                               tt != null && tt.isClockActive() && tt.isInsideTooltipArea(xMouse, yMouse);
+                               
+      if (ThemeManager.getCurrentTheme().isMouseHoverSensitive() && skipBtnRepaint)
+      {
+         clearRepaintListener();
+         setRepaintListener(() -> repaint());
+         suppressNextEnterRepaint = true;
+         return;
+      }
+                               
+       // normal exit
+       if (ThemeManager.getCurrentTheme().isMouseHoverSensitive())
+       {
+          repaint();
+       }
+       
+       clearRepaintListener();
+       clearHoverSuppression();
    }
    
    /**
@@ -248,6 +320,7 @@
                repaint();
             }
          }
+         
       }
    }   
    
@@ -332,56 +405,4 @@
          MouseEvent.MOUSE_DRAGGED,
       };
    }
-
-   /**
-    * The actual mouse exit event handler.  Can recall itself with forwarding the code to event loop.
-    *
-    * @param   xMouse
-    *          The mouse X absolute position.
-    * @param   yMouse
-    *          The mouse Y absolute position.
-    */
-   private void processMouseExited(int xMouse, int yMouse)
-   {
-      // in this case we re-enter mouse over button
-      if (this.mouseOver)
-      {
-         return;
-      }
-      
-      // for certain cases we need to check if we are still inside the button
-      NativePoint p = this.displayPhysicalLocation();
-      CoordinatesConversion cc = screen().coordinates();
-      NativeRectangle rect = cc.rectangleToNative(this.bounds());
-
-      final ToolTip tt = ToolTip.getInstance();
-      // only for buttons with tooltips
-      boolean skipBtnRepaint = xMouse >= p.x && xMouse <= p.x + rect.right() - rect.left() &&
-                               yMouse >= p.y && yMouse <= p.y + rect.bottom() - rect.top() &&
-                               tt != null && tt.isClockActive() && tt.isInsideTooltipArea(xMouse, yMouse);
-
-      // If the event occurs within the button bounds, the hover state should be maintained. 
-      // this can happen for big enough button and currently active tooltip
-      if (ThemeManager.getCurrentTheme().isMouseHoverSensitive())
-      {
-         if (skipBtnRepaint)
-         {
-            // we have to repeat mouse exit handler until the mouse will become outside the button area
-            ThinClient tc = ThinClient.getInstance();
-            tc.invokeLaterOS(() ->
-            {
-               tc.eventDrawingBracket(this, () ->
-               {
-                  NativePoint np = tc.getMousePosition();
-                  processMouseExited(np.x, np.y);
-               });
-            }, 250L, TimeUnit.MILLISECONDS);
-         }
-         else
-         {
-            // immediate repaint
-            this.repaint();
-         }
-      }
-   }   
 }

=== modified file 'src/com/goldencode/p2j/ui/client/gui/ToolTip.java'
--- old/src/com/goldencode/p2j/ui/client/gui/ToolTip.java	2026-01-14 01:09:46 +0000
+++ new/src/com/goldencode/p2j/ui/client/gui/ToolTip.java	2026-01-27 14:05:25 +0000
@@ -41,6 +41,7 @@
 ** 015 AB2 20250613 Added support for interpreting the accelerator symbol ('&'). See #10125.
 ** 016 PMP 20250723 Do not activate the tooltip if a pop up menu is displayed. See #10233.
 ** 017 EVL 20250112 Adding method to check if the given absolute point is inside tooltip overlay.
+**     PMP 20260127 TODO
 */
 
 /*
@@ -163,6 +164,9 @@
    /** Last activation mouse event absolute Y, otherwise undefined. */
    private int yAbs;
    
+   /** TODO */
+   private Widget<?> host;
+   
    /**
     * This constructor is private since the class is a singleton.
     */
@@ -321,6 +325,7 @@
       // the absolute mouse position is also required
       this.xAbs = evt.getXOnScreen();
       this.yAbs = evt.getYOnScreen();
+      this.host = widget;
       
       clock = new TooltipWorker((AbstractWidget<?>) widget, text);
    }
@@ -343,6 +348,29 @@
          overlayWindow = null;
       }
       
+      if (host != null && host instanceof GuiButton)
+      {
+         NativePoint p = host.displayPhysicalLocation();
+         CoordinatesConversion cc = screen().coordinates();
+         NativeRectangle rect = cc.rectangleToNative(host.bounds());
+         
+         boolean inHostBounds = xAbs >= p.x                              && 
+                                xAbs <= p.x + rect.right() - rect.left() &&
+                                yAbs >= p.y                              && 
+                                yAbs <= p.y + rect.bottom() - rect.top();
+         
+         // check if the mouse position is outside of the button boundaries
+         if (!inHostBounds)
+         {
+            ((GuiButton) host).runRepaintListener();
+         }
+         else
+         {
+            ((GuiButton) host).clearRepaintListener();
+            ((GuiButton) host).clearHoverSuppression();
+         }   
+      }
+      host = null;
       ThinClient.getInstance().registry().removeWidget(this.getId());
    }
    

