summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-03-23 07:08:17 +0000
committerManolo Gouy <Manolo>2016-03-23 07:08:17 +0000
commit270b437500552cba0d082363f9124456f16a1fda (patch)
treeac7245b95a138a5f64c6e6b8318632fd4dc45075 /src/drivers
parentbf7e4de688fc1f0e3008049a41c07543a7da0752 (diff)
Rewrite Fl_Window::hide() under the driver model.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11402 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H1
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx16
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H1
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx76
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.H1
-rw-r--r--src/drivers/X11/Fl_X11_Window_Driver.cxx14
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H3
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx2
8 files changed, 113 insertions, 1 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
index 46428962b..bd5a0e79e 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.H
@@ -77,6 +77,7 @@ public:
virtual void label(const char *name, const char *mininame);
virtual void show();
virtual void resize(int X,int Y,int W,int H);
+ virtual void hide();
virtual void shape(const Fl_Image* img);
// that one is implemented in Fl_Cocoa.mm because it uses Objective-c
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
index 127a84d6d..5d97ac91d 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx
@@ -223,6 +223,22 @@ void Fl_Cocoa_Window_Driver::shape(const Fl_Image* img) {
#endif
}
+
+void Fl_Cocoa_Window_Driver::hide() {
+ Fl_X* ip = Fl_X::i(pWindow);
+ // MacOS X manages a single pointer per application. Make sure that hiding
+ // a toplevel window will not leave us with some random pointer shape, or
+ // worst case, an invisible pointer
+ if (ip && !pWindow->parent()) pWindow->cursor(FL_CURSOR_DEFAULT);
+ if ( hide_common() ) return;
+ Fl_X::q_release_context(ip);
+ if ( ip->xid == fl_window )
+ fl_window = 0;
+ if (ip->region) XDestroyRegion(ip->region);
+ ip->destroy();
+ delete ip;
+}
+
//
// End of "$Id$".
//
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
index 5a2053af8..4d7d8b490 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
+++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.H
@@ -82,6 +82,7 @@ public:
virtual void show();
virtual void label(const char *name,const char *iname);
virtual void resize(int X,int Y,int W,int H);
+ virtual void hide();
virtual void shape(const Fl_Image* img);
virtual void icons(const Fl_RGB_Image *icons[], int count);
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
index 976fbd606..70c254216 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Window_Driver.cxx
@@ -445,6 +445,82 @@ void Fl_WinAPI_Window_Driver::label(const char *name,const char *iname) {
}
}
+
+extern void fl_clipboard_notify_retarget(HWND wnd);
+extern void fl_update_clipboard(void);
+
+void Fl_WinAPI_Window_Driver::hide() {
+ Fl_X* ip = Fl_X::i(pWindow);
+ // STR#3079: if there remains a window and a non-modal window, and the window is deleted,
+ // the app remains running without any apparent window.
+ // Bug mechanism: hiding an owner window unmaps the owned (non-modal) window(s)
+ // but does not delete it(them) in FLTK.
+ // Fix for it:
+ // when hiding a window, build list of windows it owns, and do hide/show on them.
+ int count = 0;
+ Fl_Window *win, **doit = NULL;
+ for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) {
+ if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) {
+ count++;
+ }
+ }
+ if (count) {
+ doit = new Fl_Window*[count];
+ count = 0;
+ for (win = Fl::first_window(); win && ip; win = Fl::next_window(win)) {
+ if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == ip->xid) {
+ doit[count++] = win;
+ }
+ }
+ }
+
+ if (hide_common()) return;
+
+ // make sure any custom icons get freed
+ icons(NULL, 0);
+ // this little trick keeps the current clipboard alive, even if we are about
+ // to destroy the window that owns the selection.
+ if (GetClipboardOwner()==ip->xid)
+ fl_update_clipboard();
+ // Make sure we unlink this window from the clipboard chain
+ fl_clipboard_notify_retarget(ip->xid);
+ // Send a message to myself so that I'll get out of the event loop...
+ PostMessage(ip->xid, WM_APP, 0, 0);
+ if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
+ if (ip->xid == fl_window && fl_graphics_driver->gc()) {
+ fl_release_dc(fl_window, (HDC)fl_graphics_driver->gc());
+ fl_window = (HWND)-1;
+ fl_graphics_driver->gc(0);
+# ifdef FLTK_USE_CAIRO
+ if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0);
+# endif
+ }
+
+ if (ip->region) XDestroyRegion(ip->region);
+
+ // this little trickery seems to avoid the popup window stacking problem
+ HWND p = GetForegroundWindow();
+ if (p==GetParent(ip->xid)) {
+ ShowWindow(ip->xid, SW_HIDE);
+ ShowWindow(p, SW_SHOWNA);
+ }
+ XDestroyWindow(fl_display, ip->xid);
+ // end of fix for STR#3079
+ if (count) {
+ int ii;
+ for (ii = 0; ii < count; ii++) doit[ii]->hide();
+ for (ii = 0; ii < count; ii++) {
+ if (ii != 0) doit[0]->show(); // Fix for STR#3165
+ doit[ii]->show();
+ }
+ delete[] doit;
+ }
+ // Try to stop the annoying "raise another program" behavior
+ if (pWindow->non_modal() && Fl::first_window() && Fl::first_window()->shown())
+ Fl::first_window()->show();
+ delete ip;
+}
+
//
// End of "$Id$".
//
diff --git a/src/drivers/X11/Fl_X11_Window_Driver.H b/src/drivers/X11/Fl_X11_Window_Driver.H
index 89f8ca457..967b7d0fa 100644
--- a/src/drivers/X11/Fl_X11_Window_Driver.H
+++ b/src/drivers/X11/Fl_X11_Window_Driver.H
@@ -91,6 +91,7 @@ public:
virtual void resize(int X,int Y,int W,int H);
virtual void label(const char *name, const char *mininame);
virtual void destroy_double_buffer();
+ virtual void hide();
virtual void shape(const Fl_Image* img);
virtual void icons(const Fl_RGB_Image *icons[], int count);
diff --git a/src/drivers/X11/Fl_X11_Window_Driver.cxx b/src/drivers/X11/Fl_X11_Window_Driver.cxx
index 0458c2b4f..4f04dba7f 100644
--- a/src/drivers/X11/Fl_X11_Window_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Window_Driver.cxx
@@ -19,6 +19,7 @@
#include "../../config_lib.h"
#include "Fl_X11_Window_Driver.H"
+#include "Fl_Xlib_Graphics_Driver.H"
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Overlay_Window.H>
@@ -461,6 +462,19 @@ void Fl_X11_Window_Driver::show_menu()
pWindow->Fl_Window::show();
}
+
+void Fl_X11_Window_Driver::hide() {
+ Fl_X* ip = Fl_X::i(pWindow);
+ if (hide_common()) return;
+ if (ip->region) XDestroyRegion(ip->region);
+# if USE_XFT
+ Fl_Xlib_Graphics_Driver::destroy_xft_draw(ip->xid);
+# endif
+ // this test makes sure ip->xid has not been destroyed already
+ if (ip->xid) XDestroyWindow(fl_display, ip->xid);
+ delete ip;
+}
+
//
// End of "$Id$".
//
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index ef225092d..d9f0d7135 100644
--- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -44,6 +44,9 @@ public:
virtual void *gc() { return gc_; }
virtual void gc(void *value);
char can_do_alpha_blending();
+#if USE_XFT
+ static void destroy_xft_draw(Window id);
+#endif
// --- bitmap stuff
Fl_Bitmask create_bitmask(int w, int h, const uchar *array);
diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index ea2cacbda..c419b4fd6 100644
--- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -958,7 +958,7 @@ static XftDraw* draw_overlay;
static Window draw_overlay_window;
#endif
-void fl_destroy_xft_draw(Window id) {
+void Fl_Xlib_Graphics_Driver::destroy_xft_draw(Window id) {
if (id == draw_window)
XftDrawChange(draw_, draw_window = fl_message_window);
#if USE_OVERLAY