From 2de19911f1102b367d2f413f6e002b8694578b79 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 20 May 2012 22:10:34 +0000 Subject: [PATCH] Add an NxWM console/keyboard thread and eliminate all issues with NxConsole window serial input git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4755 42af7a65-404d-4744-a932-0658087f49c3 --- ChangeLog.txt | 12 ++ TODO.txt | 8 +- UnitTests/nxwm/main.cxx | 45 +++++- libnxwidgets/include/ccallback.hxx | 2 +- nxwm/Makefile | 4 + nxwm/doc/NxWM-ThreadingModel.ppt | Bin 126464 -> 129024 bytes nxwm/include/ckeyboard.hxx | 133 ++++++++++++++++ nxwm/include/ctaskbar.hxx | 10 +- nxwm/include/nxwmconfig.hxx | 39 ++++- nxwm/src/ckeyboard.cxx | 245 +++++++++++++++++++++++++++++ nxwm/src/ctaskbar.cxx | 49 ++++-- 11 files changed, 529 insertions(+), 18 deletions(-) create mode 100644 nxwm/include/ckeyboard.hxx create mode 100644 nxwm/src/ckeyboard.cxx diff --git a/ChangeLog.txt b/ChangeLog.txt index c61d48375..9a5855252 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -124,3 +124,15 @@ * NxWM:CNxConsole: Configures the NxConsole window to redirectin keyboard input to the NxConsole; redirects standard input to the NxConsole device driver. +* NxWM:CKeyboard: Add a new class that implements a keyboard listener + thread. This thread reads from /dev/console and injects the keyboard + input into NX. NX will determine which window is at the top of the + heirarchy and re-direct the keyboard input to only that top window. + This solves an important problem with, for example, running multiple + copies of the NxConsole: On the copy of the NxConsole at the top of + the heirarchy should get the keyboard input. +* UnitTests/nxwm/main.cxx: Now starts the keyboard thread if + CONFIG_NXWM_KEYBOARD is defined. +* NxWM::CTaskbar: After drawing the task bar, need to raise the + application window otherwise the taskbar will be on the top and + keyboard input will not be received by the top application. diff --git a/TODO.txt b/TODO.txt index 6264d2f3d..e47b3cf1a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -72,7 +72,9 @@ o NxConsole Issues NxConsoles get their input from /dev/console which is the serial port. The necessary change is to create an NX input device for /dev/console that will get its input from NX. - Status: Open + Status: Closed with was fixed with the last check of 5/20/2012 (about + SVN version 4754). The fixed version is available in SVN but + won't be in a released version until NxWidgets-1.2 is released. Priority: Medium high, basically prohibits the use of multiple NSH windows. Title: CLOSING AN NxCONSOLE @@ -81,7 +83,9 @@ o NxConsole Issues you close one of the NxConsoles, then the others no longer received input (or no long generate output -- that cannot be distinguished). - Status: Open + Status: Closed with was fixed with the last check of 5/20/2012 (about + SVN version 4754). The fixed version is available in SVN but + won't be in a released version until NxWidgets-1.2 is released. Priority: Medium high, basically prohibits the use of multiple NSH windows. Title: DOUBLE DISPLAY UPDATES diff --git a/UnitTests/nxwm/main.cxx b/UnitTests/nxwm/main.cxx index 86ea324d5..3cc85dc43 100644 --- a/UnitTests/nxwm/main.cxx +++ b/UnitTests/nxwm/main.cxx @@ -53,6 +53,10 @@ # include "ccalibration.hxx" #endif +#ifdef CONFIG_NXWM_KEYBOARD +# include "ckeyboard.hxx" +#endif + ///////////////////////////////////////////////////////////////////////////// // Pre-processor Definitions ///////////////////////////////////////////////////////////////////////////// @@ -408,7 +412,7 @@ static bool createTouchScreen(void) printf("createTouchScreen: ERROR: Failed to create CTouchscreen\n"); return false; } - showTestCaseMemory("createTouchScreen: createTouchScreen: After creating CTouchscreen"); + showTestCaseMemory("createTouchScreen: After creating CTouchscreen"); printf("createTouchScreen: Start touchscreen listener\n"); if (!g_nxwmtest.touchscreen->start()) @@ -423,6 +427,35 @@ static bool createTouchScreen(void) } #endif +///////////////////////////////////////////////////////////////////////////// +// Name: createKeyboard +///////////////////////////////////////////////////////////////////////////// + +#ifdef CONFIG_NXWM_KEYBOARD +static bool createKeyboard(void) +{ + printf("createKeyboard: Creating CKeyboard\n"); + NxWM::CKeyboard *keyboard = new NxWM::CKeyboard(g_nxwmtest.taskbar); + if (!keyboard) + { + printf("createKeyboard: ERROR: Failed to create CKeyboard\n"); + return false; + } + showTestCaseMemory("createKeyboard After creating CKeyboard"); + + printf("createKeyboard: Start keyboard listener\n"); + if (!keyboard->start()) + { + printf("createKeyboard: ERROR: Failed start the keyboard listener\n"); + delete keyboard; + return false; + } + + showTestCaseMemory("createKeyboard: After starting the keyboard listener"); + return true; +} +#endif + ///////////////////////////////////////////////////////////////////////////// // Name: createCalibration ///////////////////////////////////////////////////////////////////////////// @@ -574,6 +607,16 @@ int MAIN_NAME(int argc, char *argv[]) testCleanUpAndExit(EXIT_FAILURE); } + // Create the keyboard device + +#ifdef CONFIG_NXWM_KEYBOARD + if (!createKeyboard()) + { + printf(MAIN_STRING "ERROR: Failed to create the keyboard\n"); + testCleanUpAndExit(EXIT_FAILURE); + } +#endif + // Create the touchscreen device #ifdef CONFIG_NXWM_TOUCHSCREEN diff --git a/libnxwidgets/include/ccallback.hxx b/libnxwidgets/include/ccallback.hxx index 8d3c13cd2..714ed1a7f 100644 --- a/libnxwidgets/include/ccallback.hxx +++ b/libnxwidgets/include/ccallback.hxx @@ -39,7 +39,7 @@ /**************************************************************************** * Included Files ****************************************************************************/ - + #include #include diff --git a/nxwm/Makefile b/nxwm/Makefile index b0b33c73d..01b8d4513 100644 --- a/nxwm/Makefile +++ b/nxwm/Makefile @@ -51,6 +51,10 @@ ifeq ($(CONFIG_NXWM_TOUCHSCREEN),y) CXXSRCS += ccalibration.cxx ctouchscreen.cxx endif +ifeq ($(CONFIG_NXWM_KEYBOARD),y) +CXXSRCS += ckeyboard.cxx +endif + # Images CXXSRCS += glyph_calibration.cxx glyph_cmd.cxx glyph_minimize.cxx glyph_nsh.cxx CXXSRCS += glyph_play.cxx glyph_start.cxx glyph_stop.cxx diff --git a/nxwm/doc/NxWM-ThreadingModel.ppt b/nxwm/doc/NxWM-ThreadingModel.ppt index acae788c2d15f44d8e880f13edb894af282722c6..1b7b43622d843eadd99b83d4566820c154e0ad61 100644 GIT binary patch delta 5121 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 delta 3653 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 diff --git a/nxwm/include/ckeyboard.hxx b/nxwm/include/ckeyboard.hxx new file mode 100644 index 000000000..8f16bd506 --- /dev/null +++ b/nxwm/include/ckeyboard.hxx @@ -0,0 +1,133 @@ +/**************************************************************************** + * NxWidgets/nxwm/include/keyboard.hxx + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors + * me be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_CKEYBOARD_HXX +#define __INCLUDE_CKEYBOARD_HXX + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "cnxserver.hxx" +#include "ccalibration.hxx" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Implementation Classes + ****************************************************************************/ + +namespace NxWM +{ + /** + * The CKeyboard class provides the the calibration window and obtains + * callibration data. + */ + + class CKeyboard + { + private: + /** + * The state of the listener thread. + */ + + enum EListenerState + { + LISTENER_NOTRUNNING = 0, /**< The listener thread has not yet been started */ + LISTENER_STARTED, /**< The listener thread has been started, but is not yet running */ + LISTENER_RUNNING, /**< The listener thread is running normally */ + LISTENER_STOPREQUESTED, /**< The listener thread has been requested to stop */ + LISTENER_TERMINATED, /**< The listener thread terminated normally */ + LISTENER_FAILED /**< The listener thread terminated abnormally */ + }; + + /** + * CKeyboard state data + */ + + NXWidgets::CNxServer *m_server; /**< The current NX server */ + int m_kbdFd; /**< File descriptor of the opened keyboard device */ + pthread_t m_thread; /**< The listener thread ID */ + volatile enum EListenerState m_state; /**< The state of the listener thread */ + sem_t m_waitSem; /**< Used to synchronize with the listener thread */ + + /** + * The keyboard listener thread. This is the entry point of a thread that + * listeners for and dispatches keyboard events to the NX server. + * + * @param arg. The CKeyboard 'this' pointer cast to a void*. + * @return This function normally does not return but may return NULL on + * error conditions. + */ + + static FAR void *listener(FAR void *arg); + + public: + + /** + * CKeyboard Constructor + * + * @param server. An instance of the NX server. This will be needed for + * injecting mouse data. + */ + + CKeyboard(NXWidgets::CNxServer *server); + + /** + * CKeyboard Destructor + */ + + ~CKeyboard(void); + + /** + * Start the keyboard listener thread. + * + * @return True if the keyboard listener thread was correctly started. + */ + + bool start(void); + }; +} + +#endif // __INCLUDE_CKEYBOARD_HXX diff --git a/nxwm/include/ctaskbar.hxx b/nxwm/include/ctaskbar.hxx index 2578a3ce9..5aab9e6bf 100644 --- a/nxwm/include/ctaskbar.hxx +++ b/nxwm/include/ctaskbar.hxx @@ -184,7 +184,15 @@ namespace NxWM * @return true on success */ - bool redrawTopWindow(void); + bool redrawTopApplication(void); + + /** + * Raise the top window to the top of the NXheirarchy. + * + * @return true on success + */ + + void raiseTopApplication(void); /** * (Re-)draw the background window. diff --git a/nxwm/include/nxwmconfig.hxx b/nxwm/include/nxwmconfig.hxx index 25a8beb66..8a7700af4 100644 --- a/nxwm/include/nxwmconfig.hxx +++ b/nxwm/include/nxwmconfig.hxx @@ -65,6 +65,7 @@ * CONFIG_NXWM_DEFAULT_FONTID - the NxWM default font ID. Default: * NXFONT_DEFAULT * CONFIG_NXWM_TOUCHSCREEN - Define to build in touchscreen support. + * CONFIG_NXWM_KEYBOARD - Define to build in touchscreen support. */ #ifndef CONFIG_HAVE_CXX @@ -386,7 +387,7 @@ * * CONFIG_NXWM_TOUCHSCREEN_DEVNO - Touchscreen device minor number, i.e., the * N in /dev/inputN. Default: 0 - * CONFIG_NXWM_TOUCHSCREEN_DEVNO - The full path to the touchscreen device. + * CONFIG_NXWM_TOUCHSCREEN_DEVPATH - The full path to the touchscreen device. * Default: "/dev/input0" * CONFIG_NXWM_TOUCHSCREEN_SIGNO - The realtime signal used to wake up the * touchscreen listener thread. Default: 5 @@ -416,6 +417,42 @@ # define CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK 1024 #endif +/* Keyboard device **********************************************************/ +/** + * Keyboard device settings + * + * CONFIG_NXWM_KEYBOARD_DEVNO - The full path to the touchscreen device. + * Default: "/dev/console" + * CONFIG_NXWM_KEYBOARD_SIGNO - The realtime signal used to wake up the + * touchscreen listener thread. Default: 6 + * CONFIG_NXWM_KEYBOARD_BUFSIZE - The size of the keyboard read data buffer. + * Default: 16 + * CONFIG_NXWM_KEYBOARD_LISTENERPRIO - Priority of the touchscreen listener + * thread. Default: SCHED_PRIORITY_DEFAULT + * CONFIG_NXWM_KEYBOARD_LISTENERSTACK - Keyboard listener thread stack + * size. Default 1024 + */ + +#ifndef CONFIG_NXWM_KEYBOARD_DEVPATH +# define CONFIG_NXWM_KEYBOARD_DEVPATH "/dev/console" +#endif + +#ifndef CONFIG_NXWM_KEYBOARD_SIGNO +# define CONFIG_NXWM_KEYBOARD_SIGNO 6 +#endif + +#ifndef CONFIG_NXWM_KEYBOARD_BUFSIZE +# define CONFIG_NXWM_KEYBOARD_BUFSIZE 6 +#endif + +#ifndef CONFIG_NXWM_KEYBOARD_LISTENERPRIO +# define CONFIG_NXWM_KEYBOARD_LISTENERPRIO SCHED_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_NXWM_KEYBOARD_LISTENERSTACK +# define CONFIG_NXWM_KEYBOARD_LISTENERSTACK 1024 +#endif + /* Calibration display ******************************************************/ /** * Calibration display settings: diff --git a/nxwm/src/ckeyboard.cxx b/nxwm/src/ckeyboard.cxx new file mode 100644 index 000000000..6e9d7b818 --- /dev/null +++ b/nxwm/src/ckeyboard.cxx @@ -0,0 +1,245 @@ +/******************************************************************************************** + * NxWidgets/nxwm/src/ckeyboard.cxx + * + * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors + * me be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ********************************************************************************************/ + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ +#include // REMOVE ME +#define CONFIG_DEBUG 1 // REMOVE ME +#define CONFIG_DEBUG_VERBOSE 1 // REMOVE ME +#define CONFIG_DEBUG_GRAPHICS 1 // REMOVE ME +#include // REMOVE ME + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "nxwmconfig.hxx" +#include "ckeyboard.hxx" + +/******************************************************************************************** + * Pre-Processor Definitions + ********************************************************************************************/ + +/******************************************************************************************** + * CKeyboard Method Implementations + ********************************************************************************************/ + +using namespace NxWM; + +/** + * CKeyboard Constructor + * + * @param server. An instance of the NX server. This will be needed for + * injecting mouse data. + */ + +CKeyboard::CKeyboard(NXWidgets::CNxServer *server) +{ + m_server = server; // Save the NX server + m_kbdFd = -1; // Device driver is not opened + m_state = LISTENER_NOTRUNNING; // The listener thread is not running yet + + // Initialize the semaphore used to synchronize with the listener thread + + sem_init(&m_waitSem, 0, 0); +} + +/** + * CKeyboard Destructor + */ + +CKeyboard::~CKeyboard(void) +{ + // Stop the listener thread + + m_state = LISTENER_STOPREQUESTED; + + // Wake up the listener thread so that it will use our buffer + // to receive data + // REVISIT: Need wait here for the listener thread to terminate + + (void)pthread_kill(m_thread, CONFIG_NXWM_KEYBOARD_SIGNO); + + // Close the keyboard device (or should these be done when the thread exits?) + + if (m_kbdFd >= 0) + { + std::close(m_kbdFd); + } +} + +/** + * Start the keyboard listener thread. + * + * @return True if the keyboard listener thread was correctly started. + */ + +bool CKeyboard::start(void) +{ + pthread_attr_t attr; + + gvdbg("Starting listener\n"); + + // Start a separate thread to listen for keyboard events + + (void)pthread_attr_init(&attr); + + struct sched_param param; + param.sched_priority = CONFIG_NXWM_KEYBOARD_LISTENERPRIO; + (void)pthread_attr_setschedparam(&attr, ¶m); + + (void)pthread_attr_setstacksize(&attr, CONFIG_NXWM_KEYBOARD_LISTENERSTACK); + + m_state = LISTENER_STARTED; // The listener thread has been started, but is not yet running + + int ret = pthread_create(&m_thread, &attr, listener, (FAR void *)this); + if (ret != 0) + { + gdbg("CKeyboard::start: pthread_create failed: %d\n", ret); + return false; + } + + // Detach from the thread + + (void)pthread_detach(m_thread); + + // Don't return until we are sure that the listener thread is running + // (or until it reports an error). + + while (m_state == LISTENER_STARTED) + { + // Wait for the listener thread to wake us up when we really + // are connected. + + (void)sem_wait(&m_waitSem); + } + + // Then return true only if the listener thread reported successful + // initialization. + + gvdbg("Listener m_state=%d\n", (int)m_state); + return m_state == LISTENER_RUNNING; +} + + /** + * The keyboard listener thread. This is the entry point of a thread that + * listeners for and dispatches keyboard events to the NX server. + * + * @param arg. The CKeyboard 'this' pointer cast to a void*. + * @return This function normally does not return but may return NULL on + * error conditions. + */ + +FAR void *CKeyboard::listener(FAR void *arg) +{ + CKeyboard *This = (CKeyboard *)arg; + + gvdbg("Listener started\n"); + + // Open the keyboard device + + This->m_kbdFd = std::open(CONFIG_NXWM_KEYBOARD_DEVPATH, O_RDONLY); + if (This->m_kbdFd < 0) + { + gdbg("ERROR Failed to open %s for reading: %d\n", + CONFIG_NXWM_KEYBOARD_DEVPATH, errno); + This->m_state = LISTENER_FAILED; + sem_post(&This->m_waitSem); + return (FAR void *)0; + } + + // Indicate that we have successfully initialized + + This->m_state = LISTENER_RUNNING; + sem_post(&This->m_waitSem); + + // Now loop, reading and dispatching keyboard data + + while (This->m_state == LISTENER_RUNNING) + { + // Read one keyboard sample + + gvdbg("Listening for keyboard input\n"); + + uint8_t rxbuffer[CONFIG_NXWM_KEYBOARD_BUFSIZE]; + ssize_t nbytes = read(This->m_kbdFd, rxbuffer, CONFIG_NXWM_KEYBOARD_BUFSIZE); +dbg("nbytes=%d\n"); // REMOVE ME + // Check for errors + + if (nbytes < 0) + { + // The only expect error is to be interrupt by a signal +#ifdef CONFIG_DEBUG + int errval = errno; + + gdbg("ERROR: read %s failed: %d\n", CONFIG_NXWM_KEYBOARD_DEVPATH, errval); + DEBUGASSERT(errval == EINTR); +#endif + } + + // Give the keyboard input to NX + + else if (nbytes > 0) + { + // Looks like good keyboard input... process it. + // First, get the server handle + + NXHANDLE handle = This->m_server->getServer(); + + // Then inject the keyboard input into NX + + int ret = nx_kbdin(handle, (uint8_t)nbytes, rxbuffer); + if (ret < 0) + { + gdbg("ERROR: nx_kbdin failed\n"); + } + } + } + + // We should get here only if we were asked to terminate via + // m_state = LISTENER_STOPREQUESTED + + gvdbg("Listener exiting\n"); + This->m_state = LISTENER_TERMINATED; + return (FAR void *)0; +} diff --git a/nxwm/src/ctaskbar.cxx b/nxwm/src/ctaskbar.cxx index 2130293c2..111d800e9 100644 --- a/nxwm/src/ctaskbar.cxx +++ b/nxwm/src/ctaskbar.cxx @@ -610,7 +610,7 @@ bool CTaskbar::minimizeApplication(IApplication *app) // Re-draw the new top, non-minimized application - return redrawTopWindow(); + return redrawTopApplication(); } return false; @@ -672,7 +672,7 @@ bool CTaskbar::stopApplication(IApplication *app) // Re-draw the new top, non-minimized application - bool ret = redrawTopWindow(); + bool ret = redrawTopApplication(); if (ret) { // And redraw the task bar (without the icon for this task) @@ -1184,6 +1184,11 @@ bool CTaskbar::redrawTaskbarWindow(void) } #endif } + + // If there is a top application then we must now raise it above the task + // bar so that itwill get the keyboard input. + + raiseTopApplication(); } // Return success (it is not a failure if the window manager is not started @@ -1198,7 +1203,7 @@ bool CTaskbar::redrawTaskbarWindow(void) * @return true on success */ -bool CTaskbar::redrawTopWindow(void) +bool CTaskbar::redrawTopApplication(void) { // Check if there is already a top application @@ -1236,6 +1241,30 @@ bool CTaskbar::redrawTopWindow(void) } } +/** + * Raise the top window to the top of the NXheirarchy. + * + * @return true on success + */ + +void CTaskbar::raiseTopApplication(void) +{ + if (m_topApp) + { + // Every application provides a method to obtain its application window + + IApplicationWindow *appWindow = m_topApp->getWindow(); + + // Each application window provides a method to get the underlying NX window + + NXWidgets::INxWindow *window = appWindow->getWindow(); + + // Raise the application window to the top of the hierarchy + + window->raise(); + } +} + /** * (Re-)draw the background window. * @@ -1301,18 +1330,14 @@ bool CTaskbar::redrawApplicationWindow(IApplication *app) m_backImage->disableDrawing(); + // Raise to top application to the top of the NX window heirarchy + + raiseTopApplication(); + // Every application provides a method to obtain its application window IApplicationWindow *appWindow = app->getWindow(); - // Each application window provides a method to get the underlying NX window - - NXWidgets::INxWindow *window = appWindow->getWindow(); - - // Raise the application window to the top of the hierarchy - - window->raise(); - // Re-draw the application window toolbar appWindow->redraw(); @@ -1333,7 +1358,7 @@ bool CTaskbar::redrawApplicationWindow(IApplication *app) void CTaskbar::hideApplicationWindow(IApplication *app) { // The hidden window is certainly not the top application any longer - // If it was before then redrawTopWindow() will pick a new one (rather + // If it was before then redrawTopApplication() will pick a new one (rather // arbitrarily). if (app->isTopApplication())