changeset 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 9cbf4d3ef444
children 7a8bbd6d1c2d
files gtk/gtkconv.c gtk/gtkgaim.h gtk/gtkmain.c gtk/gtknotify.c gtk/gtkprefs.c gtk/win32/gtkwin32dep.c gtk/win32/gtkwin32dep.h
diffstat 7 files changed, 100 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/gtk/gtkconv.c	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/gtkconv.c	Sun Sep 17 23:13:55 2006 +0000
@@ -5550,7 +5550,6 @@
 									 (gaim_blist_find_chat(account, gaim_conversation_get_name(conv)) != NULL));
 		}
 
-  
 	} else {
 		/* Account is offline */
 		/* Or it's a chat that we've left. */
@@ -7503,6 +7502,11 @@
 
 	gtk_widget_show(testidea);
 
+#ifdef _WIN32
+	g_signal_connect(G_OBJECT(win->window), "show",
+	                 G_CALLBACK(gtkwgaim_ensure_onscreen), win->window);
+#endif
+
 	return win;
 }
 
--- a/gtk/gtkgaim.h	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/gtkgaim.h	Sun Sep 17 23:13:55 2006 +0000
@@ -32,6 +32,10 @@
 
 #include <gtk/gtk.h>
 
+#ifdef _WIN32
+# include "gtkwin32dep.h"
+#endif
+
 /**
  * Our UI's identifier.
  */
--- a/gtk/gtkmain.c	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/gtkmain.c	Sun Sep 17 23:13:55 2006 +0000
@@ -77,10 +77,6 @@
 # include <gdk/gdkx.h>
 #endif
 
-#ifdef _WIN32
-# include "gtkwin32dep.h"
-#endif
-
 
 
 #ifdef HAVE_STARTUP_NOTIFICATION
@@ -476,17 +472,15 @@
 	int sig_indx;	/* for setting up signal catching */
 	sigset_t sigset;
 	RETSIGTYPE (*prev_sig_disp)(int);
-#endif
-	int opt;
-	gboolean gui_check;
-	gboolean debug_enabled;
-#ifdef HAVE_SIGNAL_H
 	char errmsg[BUFSIZ];
 #ifndef DEBUG
 	char *segfault_message_tmp;
 	GError *error = NULL;
 #endif
 #endif
+	int opt;
+	gboolean gui_check;
+	gboolean debug_enabled;
 
 	struct option long_options[] = {
 		{"config",   required_argument, NULL, 'c'},
--- a/gtk/gtknotify.c	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/gtknotify.c	Sun Sep 17 23:13:55 2006 +0000
@@ -38,10 +38,6 @@
 #include "gtknotify.h"
 #include "gtkutils.h"
 
-#ifdef _WIN32
-# include "gtkwin32dep.h"
-#endif
-
 typedef struct
 {
 	GaimConnection *gc;
--- a/gtk/gtkprefs.c	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/gtkprefs.c	Sun Sep 17 23:13:55 2006 +0000
@@ -50,10 +50,6 @@
 #include "gtkutils.h"
 #include "gaimstock.h"
 
-#ifdef _WIN32
-# include "gtkwin32dep.h"
-#endif
-
 #define PROXYHOST 0
 #define PROXYPORT 1
 #define PROXYUSER 2
@@ -2080,7 +2076,7 @@
 
 	/* Convert old queuing prefs to hide_new 3-way pref. */
 	if (gaim_prefs_exists("/plugins/gtk/docklet/queue_messages") &&
-	    gaim_prefs_get_bool("/plugins/gtk/docklet/queue_messages"))     
+	    gaim_prefs_get_bool("/plugins/gtk/docklet/queue_messages"))
 	{
 		gaim_prefs_set_string("/gaim/gtk/conversations/im/hide_new", "always");
 	}
--- 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);
+	}
+}
+
--- a/gtk/win32/gtkwin32dep.h	Sun Sep 17 22:43:01 2006 +0000
+++ b/gtk/win32/gtkwin32dep.h	Sun Sep 17 23:13:55 2006 +0000
@@ -28,6 +28,7 @@
 /* Utility */
 int       gtkwgaim_gz_decompress(const char* in, const char* out);
 int       gtkwgaim_gz_untar(const char* filename, const char* destdir);
+void gtkwgaim_ensure_onscreen(GtkWidget *win);
 
 /* Misc */
 void      gtkwgaim_notify_uri(const char *uri);