Introduced window positioning hints and window position properties
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 87ba942..69fe6bf 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -413,6 +413,8 @@
 #define GLFW_OPENGL_ROBUSTNESS    0x00022006
 #define GLFW_RESIZABLE            0x00022007
 #define GLFW_VISIBLE              0x00022008
+#define GLFW_POSITION_X           0x00022009
+#define GLFW_POSITION_Y           0x0002200A
 
 /* GLFW_CLIENT_API tokens */
 #define GLFW_OPENGL_API           0x00000001
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index fd60d0e..8fa1b86 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -686,7 +686,7 @@
         styleMask = NSBorderlessWindowMask;
 
     window->NS.object = [[NSWindow alloc]
-        initWithContentRect:NSMakeRect(0, 0, window->width, window->height)
+        initWithContentRect:NSMakeRect(wndconfig->positionX, wndconfig->positionY, window->width, window->height)
                   styleMask:styleMask
                     backing:NSBackingStoreBuffered
                       defer:NO];
diff --git a/src/internal.h b/src/internal.h
index bbbced8..573c985 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -107,6 +107,8 @@
     GLboolean   glDebug;
     int         glProfile;
     int         glRobustness;
+    int         positionX;
+    int         positionY;
 };
 
 
@@ -123,6 +125,8 @@
     int           refreshRate;
     GLboolean     resizable;
     GLboolean     visible;
+    int           positionX;
+    int           positionY;
     int           clientAPI;
     int           glMajor;
     int           glMinor;
diff --git a/src/win32_window.c b/src/win32_window.c
index 75c8a8c..2e6070a 100644
--- a/src/win32_window.c
+++ b/src/win32_window.c
@@ -772,7 +772,11 @@
     if (window->mode == GLFW_FULLSCREEN)
         wa.left = wa.top = 0;
     else
+    {
         SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0);
+        wa.left += wndconfig->positionX;
+        wa.top += wndconfig->positionY;
+    }
 
     wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title);
     if (!wideTitle)
diff --git a/src/window.c b/src/window.c
index b86dcfe..bf499a0 100644
--- a/src/window.c
+++ b/src/window.c
@@ -238,6 +238,8 @@
     wndconfig.refreshRate    = Max(_glfwLibrary.hints.refreshRate, 0);
     wndconfig.resizable      = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE;
     wndconfig.visible        = _glfwLibrary.hints.visible ? GL_TRUE : GL_FALSE;
+    wndconfig.positionX      = _glfwLibrary.hints.positionX;
+    wndconfig.positionY      = _glfwLibrary.hints.positionY;
     wndconfig.clientAPI      = _glfwLibrary.hints.clientAPI;
     wndconfig.glMajor        = _glfwLibrary.hints.glMajor;
     wndconfig.glMinor        = _glfwLibrary.hints.glMinor;
@@ -369,6 +371,10 @@
     _glfwLibrary.hints.resizable = GL_TRUE;
     _glfwLibrary.hints.visible   = GL_TRUE;
 
+    // The default window position is the upper left corner of the screen
+    _glfwLibrary.hints.positionX = 0;
+    _glfwLibrary.hints.positionY = 0;
+
     // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil
     _glfwLibrary.hints.redBits     = 8;
     _glfwLibrary.hints.greenBits   = 8;
@@ -437,6 +443,12 @@
         case GLFW_VISIBLE:
             _glfwLibrary.hints.visible = hint;
             break;
+        case GLFW_POSITION_X:
+            _glfwLibrary.hints.positionX = hint;
+            break;
+        case GLFW_POSITION_Y:
+            _glfwLibrary.hints.positionY = hint;
+            break;
         case GLFW_FSAA_SAMPLES:
             _glfwLibrary.hints.samples = hint;
             break;
@@ -747,6 +759,10 @@
             return window->resizable;
         case GLFW_VISIBLE:
             return window->visible;
+        case GLFW_POSITION_X:
+            return window->positionX;
+        case GLFW_POSITION_Y:
+            return window->positionY;
         case GLFW_CLIENT_API:
             return window->clientAPI;
         case GLFW_OPENGL_VERSION_MAJOR:
diff --git a/src/x11_platform.h b/src/x11_platform.h
index a6b576e..e289721 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -141,6 +141,12 @@
     GLboolean     cursorCentered;   // True if cursor was moved since last poll
     int           cursorPosX, cursorPosY;
 
+    // Window position hint (commited the first time the window is shown)
+    GLboolean     windowPosSet;     // False until the window position has
+                                    // been set
+    int           positionX;        // The window position to be set the
+    int           positionY;        // first time the window is shown
+
 } _GLFWwindowX11;
 
 
diff --git a/src/x11_window.c b/src/x11_window.c
index ae920e7..a4233f2 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -119,7 +119,7 @@
 
         window->X11.handle = XCreateWindow(_glfwLibrary.X11.display,
                                            _glfwLibrary.X11.root,
-                                           0, 0,           // Position
+                                           wndconfig->positionX, wndconfig->positionY,
                                            window->width, window->height,
                                            0,              // Border width
                                            visual->depth,  // Color depth
@@ -136,6 +136,12 @@
             _glfwSetError(GLFW_PLATFORM_ERROR, "X11: Failed to create window");
             return GL_FALSE;
         }
+
+        // Request a window position to be set once the window is shown
+        // (see _glfwPlatformShowWindow)
+        window->X11.windowPosSet = GL_FALSE;
+        window->X11.positionX = wndconfig->positionX;
+        window->X11.positionY = wndconfig->positionY;
     }
 
     if (window->mode == GLFW_FULLSCREEN && !_glfwLibrary.X11.hasEWMH)
@@ -1060,6 +1066,15 @@
 {
     XMapRaised(_glfwLibrary.X11.display, window->X11.handle);
     XFlush(_glfwLibrary.X11.display);
+
+    // Set the window position the first time the window is shown
+    // Note: XMoveWindow has no effect before the window has been mapped.
+    if (!window->X11.windowPosSet)
+    {
+        XMoveWindow(_glfwLibrary.X11.display, window->X11.handle,
+                    window->X11.positionX, window->X11.positionY);
+        window->X11.windowPosSet = GL_TRUE;
+    }
 }
 
 
diff --git a/tests/sharing.c b/tests/sharing.c
index 41ce8db..74e1147 100644
--- a/tests/sharing.c
+++ b/tests/sharing.c
@@ -51,10 +51,12 @@
     return GL_FALSE;
 }
 
-static GLFWwindow open_window(const char* title, GLFWwindow share)
+static GLFWwindow open_window(const char* title, GLFWwindow share, int posX, int posY)
 {
     GLFWwindow window;
 
+    glfwWindowHint(GLFW_POSITION_X, posX);
+    glfwWindowHint(GLFW_POSITION_Y, posY);
     window = glfwCreateWindow(WIDTH, HEIGHT, GLFW_WINDOWED, title, share);
     if (!window)
         return NULL;
@@ -125,7 +127,6 @@
 int main(int argc, char** argv)
 {
     GLuint texture;
-    int x, y;
 
     if (!glfwInit())
     {
@@ -133,7 +134,7 @@
         exit(EXIT_FAILURE);
     }
 
-    windows[0] = open_window("First", NULL);
+    windows[0] = open_window("First", NULL, 0, 0);
     if (!windows[0])
     {
         fprintf(stderr, "Failed to open first GLFW window: %s\n", glfwErrorString(glfwGetError()));
@@ -147,7 +148,8 @@
     // It will then be shared with the second context, created below
     texture = create_texture();
 
-    windows[1] = open_window("Second", windows[0]);
+    // Put the second window to the right of the first one
+    windows[1] = open_window("Second", windows[0], WIDTH + 50, 0);
     if (!windows[1])
     {
         fprintf(stderr, "Failed to open second GLFW window: %s\n", glfwErrorString(glfwGetError()));
@@ -161,10 +163,6 @@
     glColor3f(0.6f, 0.f, 0.6f);
     glfwCopyContext(windows[0], windows[1], GL_CURRENT_BIT);
 
-    // Put the second window to the right of the first one
-    glfwGetWindowPos(windows[0], &x, &y);
-    glfwSetWindowPos(windows[1], x + WIDTH + 50, y);
-
     while (!closed)
     {
         glfwMakeContextCurrent(windows[0]);
diff --git a/tests/threads.c b/tests/threads.c
index 49e3739..8b06b1d 100644
--- a/tests/threads.c
+++ b/tests/threads.c
@@ -89,6 +89,8 @@
 
     for (i = 0;  i < count;  i++)
     {
+        glfwWindowHint(GLFW_POSITION_X, 200 + 250 * i);
+        glfwWindowHint(GLFW_POSITION_Y, 200);
         threads[i].window = glfwCreateWindow(200, 200,
                                              GLFW_WINDOWED,
                                              threads[i].title,
@@ -100,8 +102,6 @@
             exit(EXIT_FAILURE);
         }
 
-        glfwSetWindowPos(threads[i].window, 200 + 250 * i, 200);
-
         if (thrd_create(&threads[i].id, thread_main, threads + i) !=
             thrd_success)
         {
diff --git a/tests/windows.c b/tests/windows.c
index ddf6791..187248c 100644
--- a/tests/windows.c
+++ b/tests/windows.c
@@ -55,6 +55,8 @@
 
     for (i = 0;  i < 4;  i++)
     {
+        glfwWindowHint(GLFW_POSITION_X, 100 + (i & 1) * 300);
+        glfwWindowHint(GLFW_POSITION_Y, 100 + (i >> 1) * 300);
         windows[i] = glfwCreateWindow(200, 200, GLFW_WINDOWED, titles[i], NULL);
         if (!windows[i])
         {
@@ -70,8 +72,6 @@
                      (GLclampf) (i >> 1),
                      i ? 0.f : 1.f,
                      0.f);
-
-        glfwSetWindowPos(windows[i], 100 + (i & 1) * 300, 100 + (i >> 1) * 300);
     }
 
     while (running)