Browse Source

Added love.window.setPosition(x, y [, displayindex]), love.window.getPosition, and optional x and y fields for t.window in love.conf and for the flags table in love.window.set/getMode (resolves issue #930.)

Alex Szpakowski 11 years ago
parent
commit
b75e1bdeaa

+ 5 - 0
src/modules/window/Window.cpp

@@ -52,6 +52,9 @@ WindowSettings::WindowSettings()
 	, highdpi(false)
 	, highdpi(false)
 	, sRGB(false)
 	, sRGB(false)
 	, refreshrate(0.0)
 	, refreshrate(0.0)
+	, useposition(false)
+	, x(0)
+	, y(0)
 {
 {
 }
 }
 
 
@@ -101,6 +104,8 @@ StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntri
 	{"highdpi", SETTING_HIGHDPI},
 	{"highdpi", SETTING_HIGHDPI},
 	{"srgb", SETTING_SRGB},
 	{"srgb", SETTING_SRGB},
 	{"refreshrate", SETTING_REFRESHRATE},
 	{"refreshrate", SETTING_REFRESHRATE},
+	{"x", SETTING_X},
+	{"y", SETTING_Y},
 };
 };
 
 
 StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));
 StringMap<Window::Setting, Window::SETTING_MAX_ENUM> Window::settings(Window::settingEntries, sizeof(Window::settingEntries));

+ 8 - 0
src/modules/window/Window.h

@@ -60,6 +60,8 @@ public:
 		SETTING_HIGHDPI,
 		SETTING_HIGHDPI,
 		SETTING_SRGB,
 		SETTING_SRGB,
 		SETTING_REFRESHRATE,
 		SETTING_REFRESHRATE,
+		SETTING_X,
+		SETTING_Y,
 		SETTING_MAX_ENUM
 		SETTING_MAX_ENUM
 	};
 	};
 
 
@@ -122,6 +124,9 @@ public:
 
 
 	virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0;
 	virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0;
 
 
+	virtual void setPosition(int x, int y, int displayindex) = 0;
+	virtual void getPosition(int &x, int &y, int &displayindex) = 0;
+
 	virtual bool isCreated() const = 0;
 	virtual bool isCreated() const = 0;
 
 
 	virtual void setWindowTitle(const std::string &title) = 0;
 	virtual void setWindowTitle(const std::string &title) = 0;
@@ -205,6 +210,9 @@ struct WindowSettings
 	bool highdpi; // false
 	bool highdpi; // false
 	bool sRGB; // false
 	bool sRGB; // false
 	double refreshrate; // 0.0
 	double refreshrate; // 0.0
+	bool useposition; // false
+	int x; // 0
+	int y; // 0
 
 
 }; // WindowSettings
 }; // WindowSettings
 
 

+ 65 - 9
src/modules/window/sdl/Window.cpp

@@ -124,6 +124,25 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 		sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
 		sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI;
 #endif
 #endif
 
 
+	int x = f.x;
+	int y = f.y;
+
+	if (f.useposition)
+	{
+		// The position needs to be in the global coordinate space.
+		SDL_Rect displaybounds = {};
+		SDL_GetDisplayBounds(f.display, &displaybounds);
+		x += displaybounds.x;
+		y += displaybounds.y;
+	}
+	else
+	{
+		if (f.centered)
+			x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
+		else
+			x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
+	}
+
 	graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
 	graphics::Graphics *gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
 	if (gfx != nullptr)
 	if (gfx != nullptr)
 		gfx->unSetMode();
 		gfx->unSetMode();
@@ -156,9 +175,6 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 		}
 		}
 	}
 	}
 
 
-	int centeredpos = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
-	int uncenteredpos = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
-
 	if (!window)
 	if (!window)
 	{
 	{
 		created = false;
 		created = false;
@@ -167,9 +183,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 		setWindowGLAttributes(f.msaa, f.sRGB);
 		setWindowGLAttributes(f.msaa, f.sRGB);
 
 
 		const char *title = windowTitle.c_str();
 		const char *title = windowTitle.c_str();
-		int pos = f.centered ? centeredpos : uncenteredpos;
 
 
-		window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
+		window = SDL_CreateWindow(title, x, y, width, height, sdlflags);
 
 
 		if (!window && f.msaa > 0)
 		if (!window && f.msaa > 0)
 		{
 		{
@@ -177,7 +192,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
 			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
 			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
 			SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
 
 
-			window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
+			window = SDL_CreateWindow(title, x, y, width, height, sdlflags);
 			f.msaa = 0;
 			f.msaa = 0;
 		}
 		}
 
 
@@ -195,8 +210,8 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 	// Enforce minimum window dimensions.
 	// Enforce minimum window dimensions.
 	SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
 	SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
 
 
-	if (f.centered && !f.fullscreen)
-		SDL_SetWindowPosition(window, centeredpos, centeredpos);
+	if ((f.useposition || f.centered) && !f.fullscreen)
+		SDL_SetWindowPosition(window, x, y);
 
 
 	SDL_RaiseWindow(window);
 	SDL_RaiseWindow(window);
 
 
@@ -374,7 +389,8 @@ void Window::updateSettings(const WindowSettings &newsettings)
 	curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
 	curMode.settings.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
 	curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
 	curMode.settings.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
 	curMode.settings.centered = newsettings.centered;
 	curMode.settings.centered = newsettings.centered;
-	curMode.settings.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
+
+	getPosition(curMode.settings.x, curMode.settings.y, curMode.settings.display);
 
 
 #if SDL_VERSION_ATLEAST(2,0,1)
 #if SDL_VERSION_ATLEAST(2,0,1)
 	curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
 	curMode.settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
@@ -543,6 +559,46 @@ void Window::getDesktopDimensions(int displayindex, int &width, int &height) con
 	}
 	}
 }
 }
 
 
+void Window::setPosition(int x, int y, int displayindex)
+{
+	if (!window)
+		return;
+
+	displayindex = std::min(std::max(displayindex, 0), getDisplayCount() - 1);
+
+	SDL_Rect displaybounds = {};
+	SDL_GetDisplayBounds(displayindex, &displaybounds);
+
+	// The position needs to be in the global coordinate space.
+	x += displaybounds.x;
+	y += displaybounds.y;
+
+	SDL_SetWindowPosition(window, x, y);
+
+	curMode.settings.useposition = true;
+}
+
+void Window::getPosition(int &x, int &y, int &displayindex)
+{
+	if (!window)
+	{
+		x = y =  0;
+		displayindex = 0;
+		return;
+	}
+
+	displayindex = std::max(SDL_GetWindowDisplayIndex(window), 0);
+
+	SDL_GetWindowPosition(window, &x, &y);
+
+	SDL_Rect displaybounds = {};
+	SDL_GetDisplayBounds(displayindex, &displaybounds);
+
+	// The position needs to be in the monitor's coordinate space.
+	x -= displaybounds.x;
+	y -= displaybounds.y;
+}
+
 bool Window::isCreated() const
 bool Window::isCreated() const
 {
 {
 	return created;
 	return created;

+ 3 - 0
src/modules/window/sdl/Window.h

@@ -60,6 +60,9 @@ public:
 
 
 	void getDesktopDimensions(int displayindex, int &width, int &height) const;
 	void getDesktopDimensions(int displayindex, int &width, int &height) const;
 
 
+	void setPosition(int x, int y, int displayindex);
+	void getPosition(int &x, int &y, int &displayindex);
+
 	bool isCreated() const;
 	bool isCreated() const;
 
 
 	void setWindowTitle(const std::string &title);
 	void setWindowTitle(const std::string &title);

+ 39 - 0
src/modules/window/wrap_Window.cpp

@@ -109,6 +109,16 @@ int w_setMode(lua_State *L)
 	settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
 	settings.highdpi = luax_boolflag(L, 3, settingName(Window::SETTING_HIGHDPI), false);
 	settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
 	settings.sRGB = luax_boolflag(L, 3, settingName(Window::SETTING_SRGB), false);
 
 
+	lua_getfield(L, 3, settingName(Window::SETTING_X));
+	lua_getfield(L, 3, settingName(Window::SETTING_Y));
+	settings.useposition = !(lua_isnoneornil(L, -2) && lua_isnoneornil(L, -1));
+	if (settings.useposition)
+	{
+		settings.x = luaL_optint(L, -2, 0);
+		settings.y = luaL_optint(L, -1, 0);
+	}
+	lua_pop(L, 2);
+
 	// We don't explicitly set the refresh rate, it's "read-only".
 	// We don't explicitly set the refresh rate, it's "read-only".
 
 
 	// For backward-compatibility. TODO: remove!
 	// For backward-compatibility. TODO: remove!
@@ -178,6 +188,12 @@ int w_getMode(lua_State *L)
 	lua_pushnumber(L, settings.refreshrate);
 	lua_pushnumber(L, settings.refreshrate);
 	lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE));
 	lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE));
 
 
+	lua_pushinteger(L, settings.x);
+	lua_setfield(L, -2, settingName(Window::SETTING_X));
+
+	lua_pushinteger(L, settings.y);
+	lua_setfield(L, -2, settingName(Window::SETTING_Y));
+
 	return 3;
 	return 3;
 }
 }
 
 
@@ -279,6 +295,27 @@ int w_getDesktopDimensions(lua_State *L)
 	return 2;
 	return 2;
 }
 }
 
 
+int w_setPosition(lua_State *L)
+{
+	int x = luaL_checkint(L, 1);
+	int y = luaL_checkint(L, 2);
+	int displayindex = luaL_optint(L, 3, 1) - 1;
+	instance()->setPosition(x, y, displayindex);
+	return 0;
+}
+
+int w_getPosition(lua_State *L)
+{
+	int x = 0;
+	int y = 0;
+	int displayindex = 0;
+	instance()->getPosition(x, y, displayindex);
+	lua_pushinteger(L, x);
+	lua_pushinteger(L, y);
+	lua_pushinteger(L, displayindex + 1);
+	return 3;
+}
+
 int w_setIcon(lua_State *L)
 int w_setIcon(lua_State *L)
 {
 {
 	image::ImageData *i = luax_checktype<image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
 	image::ImageData *i = luax_checktype<image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
@@ -455,6 +492,8 @@ static const luaL_Reg functions[] =
 	{ "getHeight", w_getHeight },
 	{ "getHeight", w_getHeight },
 	{ "getDimensions", w_getDimensions },
 	{ "getDimensions", w_getDimensions },
 	{ "getDesktopDimensions", w_getDesktopDimensions },
 	{ "getDesktopDimensions", w_getDesktopDimensions },
+	{ "setPosition", w_setPosition },
+	{ "getPosition", w_getPosition },
 	{ "setIcon", w_setIcon },
 	{ "setIcon", w_setIcon },
 	{ "getIcon", w_getIcon },
 	{ "getIcon", w_getIcon },
 	{ "setTitle", w_setTitle },
 	{ "setTitle", w_setTitle },

+ 2 - 0
src/modules/window/wrap_Window.h

@@ -41,6 +41,8 @@ int w_getWidth(lua_State *L);
 int w_getHeight(lua_State *L);
 int w_getHeight(lua_State *L);
 int w_getDimensions(lua_State *L);
 int w_getDimensions(lua_State *L);
 int w_getDesktopDimensions(lua_State *L);
 int w_getDesktopDimensions(lua_State *L);
+int w_setPosition(lua_State *L);
+int w_getPosition(lua_State *L);
 int w_setIcon(lua_State *L);
 int w_setIcon(lua_State *L);
 int w_getIcon(lua_State *L);
 int w_getIcon(lua_State *L);
 int w_setTitle(lua_State *L);
 int w_setTitle(lua_State *L);

+ 4 - 0
src/scripts/boot.lua

@@ -300,6 +300,8 @@ function love.init()
 		window = {
 		window = {
 			width = 800,
 			width = 800,
 			height = 600,
 			height = 600,
+			x = nil,
+			y = nil,
 			minwidth = 1,
 			minwidth = 1,
 			minheight = 1,
 			minheight = 1,
 			fullscreen = false,
 			fullscreen = false,
@@ -407,6 +409,8 @@ function love.init()
 			display = c.window.display,
 			display = c.window.display,
 			highdpi = c.window.highdpi,
 			highdpi = c.window.highdpi,
 			srgb = c.window.srgb,
 			srgb = c.window.srgb,
+			x = c.window.x,
+			y = c.window.y,
 		}), "Could not set window mode")
 		}), "Could not set window mode")
 		love.window.setTitle(c.window.title or c.title)
 		love.window.setTitle(c.window.title or c.title)
 		if c.window.icon then
 		if c.window.icon then

+ 4 - 0
src/scripts/boot.lua.h

@@ -546,6 +546,8 @@ const unsigned char boot_lua[] =
 	0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
 	0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
 	0x09, 0x09, 0x09, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x38, 0x30, 0x30, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x38, 0x30, 0x30, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x61, 
 	0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x61, 
@@ -717,6 +719,8 @@ const unsigned char boot_lua[] =
 	0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x0a,
 	0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x73, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 
 	0x09, 0x09, 0x09, 0x73, 0x72, 0x67, 0x62, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 
 	0x2e, 0x73, 0x72, 0x67, 0x62, 0x2c, 0x0a,
 	0x2e, 0x73, 0x72, 0x67, 0x62, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x78, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x79, 0x2c, 0x0a,
 	0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 
 	0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 
 	0x65, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a,
 	0x65, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a,
 	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54, 
 	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x54,