diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
index 0bb1df25d..4ff947abc 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1131,12 +1131,12 @@ GLCanvas3D::Gizmos::~Gizmos()
     _reset();
 }
 
-bool GLCanvas3D::Gizmos::init()
+bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
 {
 #if ENABLE_GIZMOS_3D
-    GLGizmoBase* gizmo = new GLGizmoScale3D;
+    GLGizmoBase* gizmo = new GLGizmoScale3D(parent);
 #else
-    GLGizmoBase* gizmo = new GLGizmoScale;
+    GLGizmoBase* gizmo = new GLGizmoScale(parent);
 #endif // ENABLE_GIZMOS_3D
     if (gizmo == nullptr)
         return false;
@@ -1147,9 +1147,9 @@ bool GLCanvas3D::Gizmos::init()
     m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
 
 #if ENABLE_GIZMOS_3D
-    gizmo = new GLGizmoRotate3D;
+    gizmo = new GLGizmoRotate3D(parent);
 #else
-    gizmo = new GLGizmoRotate(GLGizmoRotate::Z);
+    gizmo = new GLGizmoRotate(parent, GLGizmoRotate::Z);
 #endif // ENABLE_GIZMOS_3D
     if (gizmo == nullptr)
     {
@@ -1938,7 +1938,7 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
     if (!m_volumes.empty())
         m_volumes.finalize_geometry(m_use_VBOs);
 
-    if (m_gizmos.is_enabled() && !m_gizmos.init())
+    if (m_gizmos.is_enabled() && !m_gizmos.init(*this))
         return false;
 
     if (!_init_toolbar())
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp
index 0cd2870eb..cae8ddf0d 100644
--- a/xs/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp
@@ -352,7 +352,7 @@ public:
         Gizmos();
         ~Gizmos();
 
-        bool init();
+        bool init(GLCanvas3D& parent);
 
         bool is_enabled() const;
         void set_enabled(bool enable);
diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp
index ee98857e9..b742b642d 100644
--- a/xs/src/slic3r/GUI/GLGizmo.cpp
+++ b/xs/src/slic3r/GUI/GLGizmo.cpp
@@ -1,6 +1,7 @@
 #include "GLGizmo.hpp"
 
 #include "../../libslic3r/Utils.hpp"
+#include "../../slic3r/GUI/GLCanvas3D.hpp"
 
 #include <Eigen/Dense>
 
@@ -157,8 +158,9 @@ void GLGizmoBase::Grabber::render_face(float half_size) const
 }
 #endif // ENABLE_GIZMOS_3D
 
-GLGizmoBase::GLGizmoBase()
-    : m_group_id(-1)
+GLGizmoBase::GLGizmoBase(GLCanvas3D& parent)
+    : m_parent(parent)
+    , m_group_id(-1)
     , m_state(Off)
     , m_hover_id(-1)
     , m_is_container(false)
@@ -234,6 +236,18 @@ void GLGizmoBase::render_grabbers_for_picking() const
     }
 }
 
+void GLGizmoBase::set_tooltip(const std::string& tooltip) const
+{
+    m_parent.set_tooltip(tooltip);
+}
+
+std::string GLGizmoBase::format(float value, unsigned int decimals) const
+{
+    char buf[1024];
+    ::sprintf(buf, "%.*f", decimals, value);
+    return buf;
+}
+
 const float GLGizmoRotate::Offset = 5.0f;
 const unsigned int GLGizmoRotate::CircleResolution = 64;
 const unsigned int GLGizmoRotate::AngleResolution = 64;
@@ -245,8 +259,8 @@ const float GLGizmoRotate::ScaleShortTooth = 1.0f;
 const unsigned int GLGizmoRotate::SnapRegionsCount = 8;
 const float GLGizmoRotate::GrabberOffset = 5.0f;
 
-GLGizmoRotate::GLGizmoRotate(GLGizmoRotate::Axis axis)
-    : GLGizmoBase()
+GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
+    : GLGizmoBase(parent)
     , m_axis(axis)
     , m_angle(0.0f)
     , m_center(0.0, 0.0, 0.0)
@@ -327,6 +341,9 @@ void GLGizmoRotate::on_update(const Linef3& mouse_ray)
 
 void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
 {
+    if (m_grabbers[0].dragging)
+        set_tooltip(format(m_angle * 180.0f / (float)PI, 4));
+
 #if ENABLE_GIZMOS_3D
     ::glEnable(GL_DEPTH_TEST);
 #else
@@ -577,11 +594,11 @@ Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) cons
     return Linef3(Vec3d(local_ray(0, 0), local_ray(1, 0), local_ray(2, 0)), Vec3d(local_ray(0, 1), local_ray(1, 1), local_ray(2, 1))).intersect_plane(0.0);
 }
 
-GLGizmoRotate3D::GLGizmoRotate3D()
-    : GLGizmoBase()
-    , m_x(GLGizmoRotate::X)
-    , m_y(GLGizmoRotate::Y)
-    , m_z(GLGizmoRotate::Z)
+GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent)
+    : GLGizmoBase(parent)
+    , m_x(parent, GLGizmoRotate::X)
+    , m_y(parent, GLGizmoRotate::Y)
+    , m_z(parent, GLGizmoRotate::Z)
 {
     m_is_container = true;
 
@@ -682,8 +699,8 @@ void GLGizmoRotate3D::on_render(const BoundingBoxf3& box) const
 
 const float GLGizmoScale::Offset = 5.0f;
 
-GLGizmoScale::GLGizmoScale()
-    : GLGizmoBase()
+GLGizmoScale::GLGizmoScale(GLCanvas3D& parent)
+    : GLGizmoBase(parent)
     , m_scale(1.0f)
     , m_starting_scale(1.0f)
 {
@@ -733,6 +750,9 @@ void GLGizmoScale::on_update(const Linef3& mouse_ray)
 
 void GLGizmoScale::on_render(const BoundingBoxf3& box) const
 {
+    if (m_grabbers[0].dragging || m_grabbers[1].dragging || m_grabbers[2].dragging || m_grabbers[3].dragging)
+        set_tooltip(format(100.0f * m_scale, 4) + "%");
+
     ::glDisable(GL_DEPTH_TEST);
 
     double min_x = box.min(0) - (double)Offset;
@@ -779,8 +799,8 @@ void GLGizmoScale::on_render_for_picking(const BoundingBoxf3& box) const
 
 const float GLGizmoScale3D::Offset = 5.0f;
 
-GLGizmoScale3D::GLGizmoScale3D()
-    : GLGizmoBase()
+GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent)
+    : GLGizmoBase(parent)
     , m_scale_x(1.0f)
     , m_scale_y(1.0f)
     , m_scale_z(1.0f)
@@ -847,6 +867,20 @@ void GLGizmoScale3D::on_update(const Linef3& mouse_ray)
 
 void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
 {
+    if (m_grabbers[0].dragging || m_grabbers[1].dragging)
+        set_tooltip("X: " + format(100.0f * m_scale_x, 4) + "%");
+    else if (m_grabbers[2].dragging || m_grabbers[3].dragging)
+        set_tooltip("Y: " + format(100.0f * m_scale_y, 4) + "%");
+    else if (m_grabbers[4].dragging || m_grabbers[5].dragging)
+        set_tooltip("Z: " + format(100.0f * m_scale_z, 4) + "%");
+    else if (m_grabbers[6].dragging || m_grabbers[7].dragging || m_grabbers[8].dragging || m_grabbers[9].dragging)
+    {
+        std::string tooltip = "X: " + format(100.0f * m_scale_x, 4) + "%\n";
+        tooltip += "Y: " + format(100.0f * m_scale_y, 4) + "%\n";
+        tooltip += "Z: " + format(100.0f * m_scale_z, 4) + "%";
+        set_tooltip(tooltip);
+    }
+
     ::glEnable(GL_DEPTH_TEST);
 
     Vec3d offset_vec = (double)Offset * Vec3d::Ones();
@@ -1013,7 +1047,7 @@ void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray)
     double ratio = calc_ratio(2, mouse_ray, m_starting_center);
 
     if (ratio > 0.0)
-        m_scale_x = m_starting_scale_y * (float)ratio;
+        m_scale_x = m_starting_scale_y * (float)ratio; // << this is temporary
 //        m_scale_y = m_starting_scale_y * (float)ratio;
 }
 
@@ -1022,7 +1056,7 @@ void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray)
     double ratio = calc_ratio(1, mouse_ray, m_starting_center);
 
     if (ratio > 0.0)
-        m_scale_x = m_starting_scale_z * (float)ratio;
+        m_scale_x = m_starting_scale_z * (float)ratio; // << this is temporary
 //        m_scale_z = m_starting_scale_z * (float)ratio;
 }
 
diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp
index 0bef4bf63..50bb333e5 100644
--- a/xs/src/slic3r/GUI/GLGizmo.hpp
+++ b/xs/src/slic3r/GUI/GLGizmo.hpp
@@ -16,6 +16,8 @@ class Linef3;
 
 namespace GUI {
 
+class GLCanvas3D;
+
 class GLGizmoBase
 {
 protected:
@@ -61,6 +63,8 @@ public:
     };
 
 protected:
+    GLCanvas3D& m_parent;
+
     int m_group_id;
     EState m_state;
     // textures are assumed to be square and all with the same size in pixels, no internal check is done
@@ -73,7 +77,7 @@ protected:
     bool m_is_container;
 
 public:
-    GLGizmoBase();
+    explicit GLGizmoBase(GLCanvas3D& parent);
     virtual ~GLGizmoBase() {}
 
     bool init() { return on_init(); }
@@ -114,6 +118,9 @@ protected:
     float picking_color_component(unsigned int id) const;
     void render_grabbers() const;
     void render_grabbers_for_picking() const;
+
+    void set_tooltip(const std::string& tooltip) const;
+    std::string format(float value, unsigned int decimals) const;
 };
 
 class GLGizmoRotate : public GLGizmoBase
@@ -146,7 +153,7 @@ private:
     mutable bool m_keep_initial_values;
 
 public:
-    explicit GLGizmoRotate(Axis axis);
+    GLGizmoRotate(GLCanvas3D& parent, Axis axis);
 
     float get_angle() const { return m_angle; }
     void set_angle(float angle);
@@ -179,7 +186,7 @@ class GLGizmoRotate3D : public GLGizmoBase
     GLGizmoRotate m_z;
 
 public:
-    GLGizmoRotate3D();
+    explicit GLGizmoRotate3D(GLCanvas3D& parent);
 
     float get_angle_x() const { return m_x.get_angle(); }
     void set_angle_x(float angle) { m_x.set_angle(angle); }
@@ -237,7 +244,7 @@ class GLGizmoScale : public GLGizmoBase
     Vec2d m_starting_drag_position;
 
 public:
-    GLGizmoScale();
+    explicit GLGizmoScale(GLCanvas3D& parent);
 
     float get_scale() const { return m_scale; }
     void set_scale(float scale) { m_starting_scale = scale; }
@@ -268,7 +275,7 @@ class GLGizmoScale3D : public GLGizmoBase
     Vec3d m_starting_center;
 
 public:
-    GLGizmoScale3D();
+    explicit GLGizmoScale3D(GLCanvas3D& parent);
 
     float get_scale_x() const { return m_scale_x; }
     void set_scale_x(float scale) { m_starting_scale_x = scale; }