From e1bf7b920254deea542c9c09a344498982ba9424 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Tue, 19 Jun 2018 16:29:20 +0000 Subject: [PATCH] Android: Clearing the desktop when a window is hidden. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12949 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- .../Android/Fl_Android_Application.cxx | 3 +- .../Android/Fl_Android_Graphics_Clipping.cxx | 6 ++-- .../Android/Fl_Android_Graphics_Driver.H | 4 ++- .../Android/Fl_Android_Graphics_Driver.cxx | 20 +++++++++---- .../Android/Fl_Android_Screen_Driver.H | 9 ++++-- .../Android/Fl_Android_Screen_Driver.cxx | 29 +++++++++++++++++-- .../Android/Fl_Android_Window_Driver.cxx | 3 +- test/CubeView.cxx | 1 + 8 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/drivers/Android/Fl_Android_Application.cxx b/src/drivers/Android/Fl_Android_Application.cxx index fca8d9a46..3a076bed3 100644 --- a/src/drivers/Android/Fl_Android_Application.cxx +++ b/src/drivers/Android/Fl_Android_Application.cxx @@ -389,7 +389,8 @@ void *Fl_Android_Application::thread_entry(void* param) * FIXME: everything is currently hardcoded to an 600x800 resolution * TODO: react to screen changes */ -void Fl_Android_Application::allocate_screen() { +void Fl_Android_Application::allocate_screen() +{ pApplicationWindowBuffer.bits = calloc(600*800, 2); // one uint16_t per pixel pApplicationWindowBuffer.width = 600; pApplicationWindowBuffer.height = 800; diff --git a/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx b/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx index f25f61976..b2fcff09e 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx @@ -367,7 +367,7 @@ void Fl_Complex_Region::compress() if (!pSubregion) return; // remove all empty regions, because the really don't add anything (literally) - print("Compress"); + // print("Compress"); Fl_Complex_Region *rgn = pSubregion; while (rgn && rgn->is_empty()) { pSubregion = rgn->next(); @@ -460,7 +460,7 @@ Fl_Complex_Region *Fl_Complex_Region::add_subregion() // ----------------------------------------------------------------------------- /** - * Returns an interator object for loops that traverse the entire region tree. + * Returns an iterator object for loops that traverse the entire region tree. * C++11 interface to range-based loops. * @return Iterator pointing to the first element. */ @@ -640,7 +640,7 @@ Fl_Complex_Region::Overlapping::OverlappingIterator::OverlappingIterator( /** * Compare two iterator. - * This is used by C++11 range0based for loops to find the end of the range. + * This is used by C++11 range-based for loops to find the end of the range. * @param other * @return */ diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H index 16754a35c..67327d4c6 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.H +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H @@ -83,9 +83,10 @@ protected: /** see fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D) */ virtual void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) override; #if 0 + // TODO: where are begine_, end_, create_, and delete_offscreen? Answer: Fl_Image_Surface - you know what to do! virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy); - /** Support function for image drawing */ + // TODO: these seem to be only needed if FL_Image and Fl_Pixmap store alpha values seperatley. virtual Fl_Bitmask create_bitmask(int w, int h, const uchar *array) {return 0; } #endif // Support function for image drawing @@ -232,6 +233,7 @@ public: /** Set the current Fl_Font_Descriptor */ // super: virtual void font_descriptor(Fl_Font_Descriptor *d) { font_descriptor_ = d;} #if 0 + // FIXME: do we need to implement any of the functions below? /** Sets the value of the driver-specific graphics context. */ virtual void gc(void*) {} /** Returns the driver-specific graphics context, of NULL if there's none. */ diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx index 06cc3b441..b927d1aa2 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx @@ -57,25 +57,35 @@ Fl_Android_Graphics_Driver::~Fl_Android_Graphics_Driver() void Fl_Android_Graphics_Driver::make_current(Fl_Window *win) { + // In the special case of win==0, we activate the desktop (the screen + // background) for drawing and clip out all visible windows + // The Stride is the offset between lines in the graphics buffer pStride = Fl_Android_Application::graphics_buffer().stride; // Bits is the memory address of the top left corner of the window - pBits = ((uint16_t*)(Fl_Android_Application::graphics_buffer().bits)) - + win->x_root() + pStride * win->y_root(); + pBits = ((uint16_t*)(Fl_Android_Application::graphics_buffer().bits)); + if (win) pBits += win->x_root() + pStride * win->y_root(); // TODO: set the clipping area // set the clipping area to the physical screen size in window coordinates - pWindowRegion.set(-win->x(), -win->y(), 600, 800); - pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h())); + if (win) { + pWindowRegion.set(-win->x(), -win->y(), 600, 800); + pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h())); + } else { + pWindowRegion.set(0, 0, 600, 800); + } pDesktopWindowRegion.set(pWindowRegion); // remove all window rectangles that are positioned on top of this window // TODO: this region is expensive to calculate. Cache it for each window and recalculate when windows move, show, hide, or change order + // TODO: this is where we also need to subtract any possible window decoration, like the window title and drag bar, resizing edges, etc. Fl_Window *wTop = Fl::first_window(); + int wx = win ? win->x() : 0; + int wy = win ? win->y() : 0; while (wTop) { if (wTop==win) break; - Fl_Rect_Region r(wTop->x()-win->x(), wTop->y()-win->y(), wTop->w(), wTop->h()); + Fl_Rect_Region r(wTop->x()-wx, wTop->y()-wy, wTop->w(), wTop->h()); pDesktopWindowRegion.subtract(r); wTop = Fl::next_window(wTop); } diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.H b/src/drivers/Android/Fl_Android_Screen_Driver.H index 4105bd731..ad9b82d4b 100644 --- a/src/drivers/Android/Fl_Android_Screen_Driver.H +++ b/src/drivers/Android/Fl_Android_Screen_Driver.H @@ -26,6 +26,7 @@ #define FL_ANDROID_SCREEN_DRIVER_H #include +#include #include //#include @@ -38,6 +39,8 @@ class Fl_Window; class FL_EXPORT Fl_Android_Screen_Driver : public Fl_Screen_Driver { + // easy access to the super class + typedef Fl_Screen_Driver super; #if 0 // No, this is not how we will implement this. @@ -77,7 +80,7 @@ private: int handle_mouse_event(AInputQueue*, AInputEvent*); public: - Fl_Android_Screen_Driver() : Fl_Screen_Driver(), pScreenContentChanged(false) { } + Fl_Android_Screen_Driver(); virtual void add_timeout(double time, Fl_Timeout_Handler cb, void *argp) override; virtual void repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) override; @@ -160,8 +163,8 @@ public: #endif #endif - bool pScreenContentChanged; - + bool pContentChanged; + bool pClearDesktop; }; #endif // FL_ANDROID_SCREEN_DRIVER_H diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.cxx b/src/drivers/Android/Fl_Android_Screen_Driver.cxx index 43ad41148..e295f5a1e 100644 --- a/src/drivers/Android/Fl_Android_Screen_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Screen_Driver.cxx @@ -52,6 +52,17 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() extern int fl_send_system_handlers(void *e); +/** + * Create the screen driver. + */ +Fl_Android_Screen_Driver::Fl_Android_Screen_Driver() : + super(), + pContentChanged(false), + pClearDesktop(false) +{ +} + + int Fl_Android_Screen_Driver::handle_app_command() { // get the command @@ -242,9 +253,23 @@ double Fl_Android_Screen_Driver::wait(double time_to_wait) fl_unlock_function(); handle_queued_events(time_to_wait); fl_lock_function(); + // FIXME: kludge to erase a window after it was hidden + if (pClearDesktop && fl_graphics_driver) { + ((Fl_Android_Graphics_Driver*)fl_graphics_driver)->make_current(nullptr); + fl_rectf(0, 0, 600, 800, FL_BLACK); + pClearDesktop = false; + pContentChanged = true; + } Fl::flush(); } else { // if there is wait time, show the pending changes and then handle the events + // FIXME: kludge to erase a window after it was hidden + if (pClearDesktop && fl_graphics_driver) { + ((Fl_Android_Graphics_Driver*)fl_graphics_driver)->make_current(nullptr); + fl_rectf(0, 0, 600, 800, FL_BLACK); + pClearDesktop = false; + pContentChanged = true; + } Fl::flush(); if (Fl::idle && !in_idle) // 'idle' may have been set within flush() time_to_wait = 0.0; @@ -264,9 +289,9 @@ void Fl_Android_Screen_Driver::flush() { Fl_Screen_Driver::flush(); // FIXME: do this only if anything actually changed on screen (need to optimize)! - if (pScreenContentChanged) { + if (pContentChanged) { if (Fl_Android_Application::copy_screen()) - pScreenContentChanged = false; + pContentChanged = false; } } diff --git a/src/drivers/Android/Fl_Android_Window_Driver.cxx b/src/drivers/Android/Fl_Android_Window_Driver.cxx index 05fd80020..b9a11c3fe 100644 --- a/src/drivers/Android/Fl_Android_Window_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Window_Driver.cxx @@ -103,13 +103,14 @@ void Fl_Android_Window_Driver::expose_all() win->damage(FL_DAMAGE_EXPOSE); win->redraw(); } + ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pClearDesktop = true; } void Fl_Android_Window_Driver::make_current() { // FXIME: that is quite a cludge: - ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pScreenContentChanged = true; + ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pContentChanged = true; Fl_Android_Graphics_Driver *gd = dynamic_cast(fl_graphics_driver); if (gd) { diff --git a/test/CubeView.cxx b/test/CubeView.cxx index 5e153c675..39afa80c1 100644 --- a/test/CubeView.cxx +++ b/test/CubeView.cxx @@ -28,6 +28,7 @@ CubeView::CubeView(int x,int y,int w,int h,const char *l) : Fl_Box(x,y,w,h,l) #endif /* HAVE_GL */ { + Fl::use_high_res_GL(1); vAng = 0.0; hAng=0.0; size=10.0;