diff gtk/win32/gtkwin32dep.c @ 14574:333989477bcd

[gaim-migrate @ 17298] On win32, ensure that conversation windows are initially put in a sane place (instead of just [0,0]). This can easily be extended to any other problematic windows. I should have done this a long time ago to prevent countless bug reports. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 17 Sep 2006 23:13:55 +0000
parents 14933d9055a0
children 7fb8a8583c73
line wrap: on
line diff
--- a/gtk/win32/gtkwin32dep.c	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/win32/gtkwin32dep.c	Sun Sep 17 23:13:55 2006 +0000
@@ -23,6 +23,9 @@
  *
  */
 #define _WIN32_IE 0x500
+#ifndef WINVER
+#define WINVER 0x0500 /* W2K */
+#endif
 #include <windows.h>
 #include <io.h>
 #include <stdlib.h>
@@ -32,6 +35,7 @@
 #include <glib.h>
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkwin32.h>
 
 #include "gaim.h"
 #include "debug.h"
@@ -46,6 +50,8 @@
 
 #include "gtkwin32dep.h"
 
+#include "win32dep.h"
+
 #include "wspell.h"
 
 /*
@@ -147,7 +153,7 @@
 				uri, (int) wsinfo.hInstApp);
 
 		g_free(w_uri);
-        } else {
+	} else {
 		SHELLEXECUTEINFOA sinfo;
 		gchar *locale_uri;
 
@@ -248,7 +254,85 @@
 }
 
 /* DLL initializer */
-BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
 	gtkgaimdll_hInstance = hinstDLL;
 	return TRUE;
 }
+
+typedef HMONITOR WINAPI gaim_MonitorFromWindow(HWND, DWORD);
+typedef BOOL WINAPI gaim_GetMonitorInfo(HMONITOR, LPMONITORINFO);
+
+static gboolean
+get_WorkingAreaRectForWindow(HWND hwnd, RECT *workingAreaRc) {
+	static gaim_MonitorFromWindow *the_MonitorFromWindow;
+	static gaim_GetMonitorInfo *the_GetMonitorInfo;
+	static gboolean initialized = FALSE;
+
+	HMONITOR monitor;
+	MONITORINFO info;
+
+	if(!initialized) {
+		the_MonitorFromWindow = (gaim_MonitorFromWindow*)
+			wgaim_find_and_loadproc("user32", "MonitorFromWindow");
+		the_GetMonitorInfo = (gaim_GetMonitorInfo*)
+			wgaim_find_and_loadproc("user32", "GetMonitorInfoA");
+		initialized = TRUE;
+	}
+
+	if(!the_MonitorFromWindow)
+		return FALSE;
+
+	if(!the_GetMonitorInfo)
+		return FALSE;
+
+	monitor = the_MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
+
+	info.cbSize = sizeof(info);
+	if(!the_GetMonitorInfo(monitor, &info))
+		return FALSE;
+
+	CopyRect(workingAreaRc, &(info.rcWork));
+	return TRUE;
+}
+
+void gtkwgaim_ensure_onscreen(GtkWidget *win) {
+	RECT windowRect, workingAreaRect, intersectionRect;
+	HWND hwnd = GDK_WINDOW_HWND(win->window);
+
+	g_return_if_fail(hwnd != NULL);
+	GetWindowRect(hwnd, &windowRect);
+
+	gaim_debug_info("win32placement",
+			"Window RECT: L:%ld R:%ld T:%ld B:%ld\n",
+			windowRect.left, windowRect.right,
+			windowRect.top, windowRect.bottom);
+
+	if(!get_WorkingAreaRectForWindow(hwnd, &workingAreaRect)) {
+		gaim_debug_info("win32placement",
+				"Couldn't get multimonitor working area\n");
+		if(!SystemParametersInfo(SPI_GETWORKAREA, 0, &workingAreaRect, FALSE)) {
+			/* I don't think this will ever happen */
+			workingAreaRect.left = 0;
+			workingAreaRect.top = 0;
+			workingAreaRect.bottom = GetSystemMetrics(SM_CYSCREEN);
+			workingAreaRect.right = GetSystemMetrics(SM_CXSCREEN);
+		}
+	}
+
+	gaim_debug_info("win32placement",
+			"Working Area RECT: L:%ld R:%ld T:%ld B:%ld\n",
+			workingAreaRect.left, workingAreaRect.right,
+			workingAreaRect.top, workingAreaRect.bottom);
+
+	/** If the conversation window doesn't intersect perfectly with the working area,
+	 *  move it to the top left corner of the working area */
+	if(!(IntersectRect(&intersectionRect, &windowRect, &workingAreaRect)
+				&& EqualRect(&intersectionRect, &windowRect))) {
+		gaim_debug_info("win32placement",
+				"conversation window out of working area, relocating\n");
+		MoveWindow(hwnd, workingAreaRect.left, workingAreaRect.top,
+				(windowRect.right - windowRect.left),
+				(windowRect.bottom - windowRect.top), TRUE);
+	}
+}
+