From f897309da7f5d145e504ccf427e8821cbda7c1e6 Mon Sep 17 00:00:00 2001 From: lemort Date: Mon, 21 Jan 2008 09:43:40 +0000 Subject: Ajout d'une propriete -windowtitle qui permet de specifier le nom (ou un pattern) de la fenetre a reparenter dans l'item window Cette propriete vient en complement de la propriete -window qui permet de reparenter des widgets Tk La propriete peut prendre comme valeur le nom de la fenetre (Google -Moxilla Firefox par exemple) ou un pattern fonctionnant avec Tcl_String (* - Mozilla Firefox par exemple) Cette gestion du reparentage de fenetre eterne fonctionne sous Linux, Windows et un peu sous Mac (pour l'instant le support Mac est limite aux applications X11) --- generic/Window.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 231 insertions(+), 2 deletions(-) (limited to 'generic/Window.c') diff --git a/generic/Window.c b/generic/Window.c index 9dac5c7..0b6459f 100644 --- a/generic/Window.c +++ b/generic/Window.c @@ -20,6 +20,14 @@ #include "WidgetInfo.h" #include "tkZinc.h" +#include +#include "WindowUtils.h" + +/* We need to include tkPlatDecls to use Tk_GetHWND */ +#if defined(_WIN32) && defined(PTK) && !defined(PTK_800) +#include +#endif + static const char rcsid[] = "$Id$"; static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; @@ -41,11 +49,20 @@ typedef struct _WindowItemStruct { Tk_Window win; int width; int height; + char *windowtitle; /* Private data */ ZnPoint pos_dev; int real_width; int real_height; + +#ifdef _WIN32 + HWND externalwindow; + LONG externalwindowstyle; +#else + Window externalwindow; +#endif /* ifdef _WIN32 */ + } WindowItemStruct, *WindowItem; @@ -89,6 +106,9 @@ static ZnAttrConfig wind_attrs[] = { { ZN_CONFIG_WINDOW, "-window", NULL, Tk_Offset(WindowItemStruct, win), 0, ZN_COORDS_FLAG|ZN_WINDOW_FLAG, False }, + { ZN_CONFIG_STRING, "-windowtitle", NULL, + Tk_Offset(WindowItemStruct, windowtitle), 0, + ZN_COORDS_FLAG|ZN_WINDOW_FLAG, False }, { ZN_CONFIG_END, NULL, NULL, 0, 0, 0, False } }; @@ -123,6 +143,7 @@ WindowDeleted(ClientData client_data, ********************************************************************************** */ + /* * A managed window changes requested dimensions. */ @@ -162,6 +183,178 @@ static Tk_GeomMgr wind_geom_type = { }; + +/* + ********************************************************************************** + * + * Manage external Window -- Reparent, Unparent, Resize + * + ********************************************************************************** + */ + +/* + * Create a Tk_Window + */ + static int WINDOW_PRIVATE_TK_WINDOW_COUNTER = 0; + + static void + WindowCreateTkWindow(ZnItem item) + { + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + char buffer[32]; + + if (wind->win == 0) { + /* create a unique name */ + sprintf(buffer, "_private_tkwindow_%d", WINDOW_PRIVATE_TK_WINDOW_COUNTER); + WINDOW_PRIVATE_TK_WINDOW_COUNTER++; + + /* create a new Tk_Window */ + wind->win = Tk_CreateWindow(wi->interp, wi->win, buffer, NULL); + } + } + + + /* + * Resize an external window + */ +static void +WindowResizeExternalWindow(ZnItem item, int width, int height) +{ + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + + /* Our window (wi->win) must exists before doing anything */ + Tk_MakeWindowExist(wi->win); + Tk_MakeWindowExist(wind->win); + +#ifdef _WIN32 + /* Resize our external window if needed */ + if (wind->externalwindow != 0) { + MoveWindow(wind->externalwindow, 0, 0, width, height, TRUE); + } + +#else + /* Resize our external window if needed */ + if (wind->externalwindow != 0) { + XResizeWindow(wi->dpy, wind->externalwindow, width, height); + XFlush(wi->dpy); + } + +#endif /* ifdef _WIN32 */ +} + + +/* + * Reparent/capture an external window + */ +static void +WindowCaptureExternalWindow(ZnItem item) +{ + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + +#ifdef _WIN32 + /* Try to find a window matching windowtitle */ + HWND externalWindow = SearchWindowByTitle(wind->windowtitle, wi->dpy, NULL, 0); + + /* Test if we can reparent our window */ + if ((externalWindow != 0) && (wi->win != 0)) { + /* Save external window */ + wind->externalwindow = externalWindow; + + /* Test if we must create a window */ + if (wind->win == NULL) { + /* Create a new window */ + WindowCreateTkWindow(item); + } + + /* Our window must exists before we try to reparent an external window */ + Tk_MakeWindowExist(wi->win); + Tk_MakeWindowExist(wind->win); + + /* remove window decoration */ + wind->externalwindowstyle = removeWindowDecoration(externalWindow); + ShowWindow(externalWindow, SW_SHOW); + + /* Reparent our external window */ + SetParent(externalWindow, Tk_GetHWND(Tk_WindowId(wind->win))); + ShowWindow(externalWindow, SW_SHOW); + + /* Windows only: we must resize our external window */ + WindowResizeExternalWindow(item, wind->real_width, wind->real_height); + } + +#else + /* Try to find a window matching windowtitle */ + Window externalWindow = SearchWindowByTitle(wind->windowtitle, wi->dpy, RootWindowOfScreen(wi->screen), 0); + + /* Test if we can reparent our window */ + if ((externalWindow != 0) && (wi->win != 0)) { + /* Save external window */ + wind->externalwindow = externalWindow; + + /* Test if we must create a window */ + if (wind->win == NULL) { + /* Create a new window */ + WindowCreateTkWindow(item); + } + + /* Our window must exists before we try to reparent an external window */ + Tk_MakeWindowExist(wi->win); + Tk_MakeWindowExist(wind->win); + + /* Withdraw our external window from desktop */ + withdrawWindowFromDesktop (wi->dpy, externalWindow, Tk_ScreenNumber(wi->win)); + + /* Reparent our external window */ + XAddToSaveSet (wi->dpy, externalWindow); + XReparentWindow(wi->dpy, externalWindow, Tk_WindowId(wind->win), 0, 0); + XMapWindow(wi->dpy, externalWindow); + XFlush(wi->dpy); + } + +#endif /* ifdef _WIN32 */ +} + + +/* + * Unparent/release an external window + */ +static void +WindowReleaseExternalWindow(ZnItem item) +{ + ZnWInfo *wi = item->wi; + WindowItem wind = (WindowItem) item; + +#ifdef _WIN32 + /* Test if we must release an external window */ + if (wind->externalwindow != 0) { + /* restore window style */ + restoreWindowStyle(wind->externalwindow, wind->externalwindowstyle); + wind->externalwindowstyle = 0; + + /* Reparent our external window (new parent is the main root window) */ + SetParent(wind->externalwindow, NULL); + } + +#else + /* Test if we must release an external window */ + if (wind->externalwindow != 0) { + /* Reparent our external window (new parent is the main root window) */ + XReparentWindow(wi->dpy, wind->externalwindow, XRootWindow(wi->dpy, Tk_ScreenNumber(wi->win)), 0, 0); + XMapWindow(wi->dpy, wind->externalwindow); + XFlush(wi->dpy); + XRemoveFromSaveSet(wi->dpy, wind->externalwindow); + } +#endif /* ifdef _WIN32 */ + + /* Reset externalwindow */ + wind->externalwindow = NULL; +} + + + /* ********************************************************************************** * @@ -190,6 +383,8 @@ Init(ZnItem item, wind->anchor = TK_ANCHOR_NW; wind->connection_anchor = TK_ANCHOR_SW; wind->win = NULL; + wind->windowtitle = NULL; + wind->externalwindow = NULL; return TCL_OK; } @@ -211,6 +406,8 @@ Clone(ZnItem item) * The same Tk widget can't be shared by to Window items. */ wind->win = NULL; + wind->windowtitle = NULL; + wind->externalwindow = NULL; } @@ -227,6 +424,17 @@ Destroy(ZnItem item) ZnWInfo *wi = item->wi; WindowItem wind = (WindowItem) item; + + /* + * Unmanage external window if needed + */ + if (wind->externalwindow != 0) { + WindowReleaseExternalWindow(item); + } + if (wind->windowtitle) { + ZnFree(wind->windowtitle); + } + /* * Unmanage the widget. */ @@ -259,9 +467,11 @@ Configure(ZnItem item, ZnWInfo *wi = item->wi; ZnItem old_connected; Tk_Window old_win; + const char *old_windowtitle = wind->windowtitle; old_connected = item->connected_item; old_win = wind->win; + if (ZnConfigureAttributes(wi, item, item, wind_attrs, argc, argv, flags) == TCL_ERROR) { item->connected_item = old_connected; return TCL_ERROR; @@ -290,6 +500,24 @@ Configure(ZnItem item, Tk_UnmaintainGeometry(old_win, wi->win); Tk_UnmapWindow(old_win); } + + if (wind->windowtitle != NULL) { + if (old_windowtitle == 0) { + /* It's a new capture */ + WindowCaptureExternalWindow(item); + + } else { + /* Test if we must capture a new window */ + if (strcmp(old_windowtitle, (const char *)(wind->windowtitle)) != 0) { + /* release previous external window */ + WindowReleaseExternalWindow(item); + + /* Capture a new window */ + WindowCaptureExternalWindow(item); + } + } + } + if (wind->win != NULL) { Tk_CreateEventHandler(wind->win, StructureNotifyMask, WindowDeleted, (ClientData) item); @@ -300,7 +528,7 @@ Configure(ZnItem item, if ((wind->win != NULL) && ISSET(*flags, ZN_VIS_FLAG) && ISCLEAR(item->flags, ZN_VISIBLE_BIT)) { - Tk_UnmapWindow(wind->win); + Tk_UnmapWindow(wind->win); } return TCL_OK; @@ -392,7 +620,7 @@ ComputeCoordinates(ZnItem item, ZnTransfo *t; ZnResetBBox(&item->item_bounding_box); - + if (wind->win == NULL) { return; } @@ -516,6 +744,7 @@ Draw(ZnItem item) wind->real_width, wind->real_height); } + WindowResizeExternalWindow(item, wind->real_width, wind->real_height); } -- cgit v1.1