summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx141
-rw-r--r--src/Fl_Window.cxx4
-rw-r--r--src/Fl_Window_Driver.cxx40
-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
11 files changed, 157 insertions, 142 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 5e725cfcc..11d0c62ce 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -1450,147 +1450,6 @@ int Fl::handle_(int e, Fl_Window* window)
return send_handlers(e);
}
-////////////////////////////////////////////////////////////////
-// hide() destroys the X window, it does not do unmap!
-
-#if defined(WIN32)
-extern void fl_clipboard_notify_retarget(HWND wnd);
-extern void fl_update_clipboard(void);
-#elif USE_XFT
-extern void fl_destroy_xft_draw(Window);
-#endif
-
-void Fl_Window::hide() {
-#ifdef WIN32 // platform fix
- // 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 && i; win = Fl::next_window(win)) {
- if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == i->xid) {
- count++;
- }
- }
- if (count) {
- doit = new Fl_Window*[count];
- count = 0;
- for (win = Fl::first_window(); win && i; win = Fl::next_window(win)) {
- if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == i->xid) {
- doit[count++] = win;
- }
- }
- }
-#endif
- clear_visible();
-
- if (!shown()) return;
-
- // remove from the list of windows:
- Fl_X* ip = i;
- Fl_X** pp = &Fl_X::first;
- for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return;
- *pp = ip->next;
-#ifdef __APPLE__ // platform fix
- // 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 (!parent()) cursor(FL_CURSOR_DEFAULT);
-#endif
- i = 0;
-
- // recursively remove any subwindows:
- for (Fl_X *wi = Fl_X::first; wi;) {
- Fl_Window* W = wi->w;
- if (W->window() == this) {
- W->hide();
- W->set_visible();
- wi = Fl_X::first;
- } else wi = wi->next;
- }
-
- if (this == Fl::modal_) { // we are closing the modal window, find next one:
- Fl_Window* W;
- for (W = Fl::first_window(); W; W = Fl::next_window(W))
- if (W->modal()) break;
- Fl::modal_ = W;
- }
-
- // Make sure no events are sent to this window:
- fl_throw_focus(this);
- handle(FL_HIDE);
-
-#if defined(WIN32)
- // 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
- }
-#elif defined(__APPLE_QUARTZ__) // PORTME: Fl_Window_Driver - platform window unmapping
- Fl_X::q_release_context(ip);
- if ( ip->xid == fl_window )
- fl_window = 0;
-#endif
-
- if (ip->region) XDestroyRegion(ip->region);
-
-#if defined(USE_X11)
-# if USE_XFT
- fl_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);
-#elif defined(WIN32)
- // 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;
- }
-#elif defined(__APPLE_QUARTZ__) // PORTME: Fl_Window_Driver - platform window unmapping
- ip->destroy();
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: code to destroy a window on screen"
-#else
-# error unsupported platform
-#endif
-
-#ifdef WIN32
- // Try to stop the annoying "raise another program" behavior
- if (non_modal() && Fl::first_window() && Fl::first_window()->shown())
- Fl::first_window()->show();
-#endif
- delete ip;
-}
-
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
// or any parent changes. We must correctly map/unmap the system's window.
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
index 35c6c1945..df6f97259 100644
--- a/src/Fl_Window.cxx
+++ b/src/Fl_Window.cxx
@@ -510,6 +510,10 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
pWindowDriver->resize(X, Y, W, H);
}
+void Fl_Window::hide() {
+ pWindowDriver->hide();
+}
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Window_Driver.cxx b/src/Fl_Window_Driver.cxx
index 40cc7c668..f9dc31c79 100644
--- a/src/Fl_Window_Driver.cxx
+++ b/src/Fl_Window_Driver.cxx
@@ -21,7 +21,9 @@
#include <config.h>
#include <FL/Fl_Window_Driver.H>
#include <FL/fl_draw.H>
+#include <FL/Fl.H>
+extern void fl_throw_focus(Fl_Widget *o);
Fl_Window_Driver::Fl_Window_Driver(Fl_Window *win) :
pWindow(win)
@@ -151,6 +153,44 @@ void Fl_Window_Driver::capture_titlebar_and_borders(Fl_Shared_Image*& top, Fl_Sh
top = left = bottom = right = NULL;
}
+
+// This function is available for use by platform-specific, Fl_Window_Driver-derived classes
+int Fl_Window_Driver::hide_common() {
+ pWindow->clear_visible();
+
+ if (!pWindow->shown()) return 1;
+
+ // remove from the list of windows:
+ Fl_X* ip = Fl_X::i(pWindow);
+ Fl_X** pp = &Fl_X::first;
+ for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return 1;
+ *pp = ip->next;
+
+ pWindow->i = 0;
+
+ // recursively remove any subwindows:
+ for (Fl_X *wi = Fl_X::first; wi;) {
+ Fl_Window* W = wi->w;
+ if (W->window() == pWindow) {
+ W->hide();
+ W->set_visible();
+ wi = Fl_X::first;
+ } else wi = wi->next;
+ }
+
+ if (pWindow == Fl::modal_) { // we are closing the modal window, find next one:
+ Fl_Window* W;
+ for (W = Fl::first_window(); W; W = Fl::next_window(W))
+ if (W->modal()) break;
+ Fl::modal_ = W;
+ }
+
+ // Make sure no events are sent to this window:
+ fl_throw_focus(pWindow);
+ pWindow->handle(FL_HIDE);
+ return 0;
+}
+
//
// End of "$Id$".
//
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