diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index cb41c22026949e871501e6e6bdaa5fffc3c28ddf..7bbf0c383bf9832cc114ffe33938c5b55b37e34d 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -275,7 +275,7 @@ FlGui::FlGui(int argc, char **argv)
 
   // use retina resolution if available
 #if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) && (FL_PATCH_VERSION >= 4)
-  Fl::use_high_res_GL(CTX::instance()-> highResolutionGraphics);
+  Fl::use_high_res_GL(CTX::instance()->highResolutionGraphics);
 #endif
 
   // register image formats not in core fltk library (jpeg/png)
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index bdaa482a9dac5e0b7403caab988f2b3cb1b2a0f4..d4ace764fd87f99f78a9bb6e63c69b4461b84410 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -42,7 +42,6 @@ static void navigator_handler(void *data)
   }
 }
 
-
 static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &click2)
 {
   if(click1.win[0] == click2.win[0] || click1.win[1] == click2.win[1]) return;
@@ -66,7 +65,8 @@ openglWindow::openglWindow(int x, int y, int w, int h)
   :  Fl_Gl_Window(x, y, w, h, "gl"), _lock(false), _drawn(false),
      _selection(ENT_NONE), _trySelection(0), Nautilus(0)
 {
-  _ctx = new drawContext();
+  _ctx = new drawContext(this);
+
   for(int i = 0; i < 3; i++) _point[i] = 0.;
   for(int i = 0; i < 4; i++) _trySelectionXYWH[i] = 0;
   _lassoXY[0] = _lassoXY[1] = 0;
@@ -74,7 +74,7 @@ openglWindow::openglWindow(int x, int y, int w, int h)
   addPointMode = lassoMode = selectionMode = false;
   endSelection = undoSelection = invertSelection = quitSelection = 0;
 
-  if(CTX::instance()->gamepad)   Fl::add_timeout(.5, navigator_handler, (void*)this);
+  if(CTX::instance()->gamepad) Fl::add_timeout(.5, navigator_handler, (void*)this);
 }
 
 openglWindow::~openglWindow()
@@ -689,11 +689,6 @@ int openglWindow::pixel_h()
 #endif
 }
 
-bool openglWindow::retina()
-{
-  return pixel_w() > w();
-}
-
 bool openglWindow::_select(int type, bool multiple, bool mesh,
                            int x, int y, int w, int h,
                            std::vector<GVertex*> &vertices,
diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h
index 9d2ad23688cdf757551a02c6f89144550e36d9a0..684e81b73f5015dce013d1346add587926dd8dd0 100644
--- a/Fltk/openglWindow.h
+++ b/Fltk/openglWindow.h
@@ -42,8 +42,7 @@ class openglWindow : public Fl_Gl_Window {
  public:
   int pixel_w();
   int pixel_h();
-  bool retina();
-  time_t  rawtime,  prev_rawtime;
+  time_t rawtime,  prev_rawtime;
   double response_frequency;
   bool addPointMode, lassoMode, selectionMode;
   int endSelection, undoSelection, invertSelection, quitSelection;
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index 2990b1f548c687f220c26df057a3d1147971561a..d0d53cad1a42389db989b0f86ac6d27120be90c6 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -24,6 +24,7 @@
 #include <FL/Fl_JPEG_Image.H>
 #include <FL/Fl_PNG_Image.H>
 #include <FL/gl.h>
+#include "openglWindow.h"
 #endif
 
 #if defined(HAVE_POPPLER)
@@ -34,8 +35,8 @@ drawContextGlobal *drawContext::_global = 0;
 
 extern SPoint2 getGraph2dDataPointForTag(unsigned int);
 
-drawContext::drawContext(drawTransform *transform)
-  : _transform(transform)
+drawContext::drawContext(openglWindow *window, drawTransform *transform)
+  : _transform(transform), _openglWindow(window)
 {
   // initialize from temp values in global context
   for(int i = 0; i < 3; i++){
@@ -65,6 +66,17 @@ drawContext::~drawContext()
   invalidateQuadricsAndDisplayLists();
 }
 
+bool drawContext::isHighResolution()
+{
+  // this must be dynamic: the high resolution can change when a window is moved
+  // across displays
+#if defined(HAVE_FLTK)
+  return _openglWindow->pixel_w() > _openglWindow->w();
+#else
+  return false;
+#endif
+}
+
 drawContextGlobal *drawContext::global()
 {
   if(!_global) _global = new drawContextGlobal(); // create dummy default
@@ -299,6 +311,7 @@ void drawContext::draw2d()
 
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
+
   glOrtho((double)viewport[0], (double)viewport[2],
           (double)viewport[1], (double)viewport[3],
           -100., 100.); // in pixels, so we can draw some 3D glyphs
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index ad403c67906923095a21d72ed36ae9711c04fa03..ef2d1e9edea7c67a365aabbda823381431730b42 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -34,6 +34,7 @@ class GEdge;
 class GFace;
 class GRegion;
 class MElement;
+class openglWindow;
 
 class drawTransform {
  public:
@@ -112,6 +113,7 @@ class drawContext {
   std::set<GModel*> _hiddenModels;
   std::set<PView*> _hiddenViews;
   GLuint _bgImageTexture, _bgImageW, _bgImageH;
+  openglWindow *_openglWindow;
  public:
   Camera camera;
   double r[3]; // current Euler angles (in degrees!)
@@ -127,8 +129,9 @@ class drawContext {
   enum RenderMode {GMSH_RENDER=1, GMSH_SELECT=2, GMSH_FEEDBACK=3};
   int render_mode; // current rendering mode
  public:
-  drawContext(drawTransform *transform=0);
+  drawContext(openglWindow *window, drawTransform *transform=0);
   ~drawContext();
+  bool isHighResolution();
   void copyViewAttributes(drawContext *other)
   {
     camera = other->camera;
diff --git a/Graphics/drawGlyph.cpp b/Graphics/drawGlyph.cpp
index 8c04472d9bf45f4896ee8768efb6e200a3ead114..1b0f983391ad62a992b96fa99ba8df75ae2c69cf 100644
--- a/Graphics/drawGlyph.cpp
+++ b/Graphics/drawGlyph.cpp
@@ -31,15 +31,21 @@ void drawContext::drawString(const std::string &s, const std::string &font_name,
     drawContext::global()->setFont(font_enum, font_size);
     double width = drawContext::global()->getStringWidth(s.c_str());
     double height = drawContext::global()->getStringHeight();
+    // width and height must here be computed in true pixel coordinates, because
+    // viewport2world uses the actual, pixel-sized (not FLTK-sized) viewport
+    if(isHighResolution()){
+      width *= 2;
+      height *= 2;
+    }
     switch(align){
-    case 1: w[0] -= width/2.;                     break; // bottom center
-    case 2: w[0] -= width;                        break; // bottom right
-    case 3:                    w[1] -= height;    break; // top left
-    case 4: w[0] -= width/2.;  w[1] -= height;    break; // top center
-    case 5: w[0] -= width;     w[1] -= height;    break; // top right
-    case 6:                    w[1] -= height/2.; break; // center left
-    case 7: w[0] -= width/2.;  w[1] -= height/2.; break; // center center
-    case 8: w[0] -= width;     w[1] -= height/2.; break; // center right
+    case 1: w[0] -= width/2.;                    break; // bottom center
+    case 2: w[0] -= width;                       break; // bottom right
+    case 3:                   w[1] -= height;    break; // top left
+    case 4: w[0] -= width/2.; w[1] -= height;    break; // top center
+    case 5: w[0] -= width;    w[1] -= height;    break; // top right
+    case 6:                   w[1] -= height/2.; break; // center left
+    case 7: w[0] -= width/2.; w[1] -= height/2.; break; // center center
+    case 8: w[0] -= width;    w[1] -= height/2.; break; // center right
     default: break;
     }
     viewport2World(w, x);