DSSeat: renew focus window on window creation/destroy handlers 72/241872/1
authorSung-Jin Park <sj76.park@samsung.com>
Thu, 20 Aug 2020 06:07:37 +0000 (15:07 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Thu, 20 Aug 2020 10:12:29 +0000 (19:12 +0900)
Change-Id: I88d6a9460a56c847a4cf57983a179449ecaa2b2f
Signed-off-by: Sung-Jin Park <sj76.park@samsung.com>
src/DSSeat/DSSeat.cpp
src/DSSeat/DSSeat.h

index b98574d..86d3cc7 100644 (file)
@@ -138,6 +138,7 @@ bool DSSeat::attachZone(std::shared_ptr<DSZone> zone)
 
        __zone = zone;
        __zone->registerCallbackWindowCreated(this, std::bind(&DSSeat::__onWindowCreated, this, std::placeholders::_1));
+       __zone->registerCallbackWindowDestroy(this, std::bind(&DSSeat::__onWindowDestroy, this, std::placeholders::_1));
 
        return true;
 }
@@ -420,7 +421,8 @@ void DSSeat::__onPointerEvent(DSInputMouseEvent *ev)
                        //TODO : emit MouseOut signal
 
                        //set the window as pointer focus window
-                       __pointer->setFocus(window);
+                       if (window)
+                               __pointer->setFocus(window);
 
                        //send pointer enter to the new pointer focus window
                        std::shared_ptr evMouseIn = std::make_shared<DSInputMouseEvent>(ev->getDevice(), DSInputEvent::MouseInEvent, ev->getTimestamp(), ev->getButton(), 0, 0, 0);
@@ -445,8 +447,11 @@ void DSSeat::__onTouchEvent(DSInputTouchEvent *ev)
                //get window whose geometry has intersection with the touch coordinates
                auto window = getTopWindowOnPosition(ev->getX(), ev->getY());
 
+               DSLOG_INF("DSSeat", "window=%p, window.get()=%p", window, window.get());
+
                //set the window as touch focus window
-               __touch->setFocus(window);
+               if (window)
+                       __touch->setFocus(window);
 
                //TODO : emit touch focus changed signal
        }
@@ -457,32 +462,40 @@ void DSSeat::__onTouchEvent(DSInputTouchEvent *ev)
 
 void DSSeat::__onWindowCreated(std::shared_ptr<DSWindow> window)
 {
-       DSLOG_INF("DSSeat", "window created : %p", window);
-
-       if (window == nullptr)
-       {
-               DSLOG_ERR("DSSeat", "Invalid window is given.");
-               return;
-       }
+       DSLOG_INF("DSSeat", "window created : %p (%p)", window, window.get());
 
-       /* Set newly created window as focus window for keyboard/pointer/touch temporarily */
-       /* FIXME when DSWindowShell and DSWMPolicy has been implmented properly */
+       /* FIXME : get focus window for keyboard from DSWindowManager/DSWindowPolicy later */
        if (__keyboard)
        {
-               DSLOG_INF("DSSeat", "keyboard focus : %p -> %p", __focusWin, window);
-               __keyboard->setFocus(window);
-       }
+               std::shared_ptr<DSWindow> focusWin = getTopWindow(__focusWin);
+               DSLOG_INF("DSSeat", "keyboard focus : %p -> %p", __focusWin ? __focusWin.get() : nullptr, focusWin ? focusWin.get() : nullptr);
 
-       if (__pointer)
-       {
-               DSLOG_INF("DSSeat", "pointer focus : %p -> %p", __focusWin, window);
-               __pointer->setFocus(window);
+               if (focusWin)
+                       __keyboard->setFocus(focusWin);
        }
+}
+
+void DSSeat::__onWindowDestroy(std::shared_ptr<DSWindow> window)
+{
+       DSLOG_INF("DSSeat", "window destroy : %p (%p)", window, window.get());
+
+       std::shared_ptr<DSWindow> currentFocus = nullptr;
+
+       if (__keyboard &&       (currentFocus = __keyboard->getFocus()) && (currentFocus.get() == window.get()))
+               __keyboard->resetFocus();
+       if (__pointer && (currentFocus = __pointer->getFocus()) && (currentFocus.get() == window.get()))
+               __pointer->resetFocus();
+       if (__touch && (currentFocus = __touch->getFocus()) && (currentFocus.get() == window.get()))
+               __touch->resetFocus();
 
-       if (__touch)
+       /* FIXME : get focus window for keyboard from DSWindowManager/DSWindowPolicy later */
+       if (__keyboard)
        {
-               DSLOG_INF("DSSeat", "touch focus : %p -> %p", __focusWin, window);
-               __touch->setFocus(window);
+               std::shared_ptr<DSWindow> focusWin = getTopWindow(window);
+               DSLOG_INF("DSSeat", "keyboard focus : %p -> %p", __focusWin ? __focusWin.get() : nullptr, focusWin ? focusWin.get() : nullptr);
+
+               if (focusWin)
+                       __keyboard->setFocus(focusWin);
        }
 }
 
@@ -510,6 +523,21 @@ Eina_Bool DSSeat::inputEventHandlerTouch(void *data, int type, void *event)
        return EINA_TRUE;
 }
 
+std::shared_ptr<DSWindow> DSSeat::getTopWindow(std::shared_ptr<DSWindow> winExcl)
+{
+       for (std::shared_ptr<DSWindow> w : __zone->getWindowList())
+       {
+               if (w && w.get() == winExcl.get())
+                       continue;
+
+               /* We suppose that the window located at the top of the window stack is at the front of the list. */
+               return w;
+
+       }
+
+       return nullptr;
+}
+
 std::shared_ptr<DSWindow> DSSeat::getTopWindowOnPosition(int x, int y)
 {
        stPosition wPos;
index 9363f6c..a599b50 100644 (file)
@@ -72,6 +72,7 @@ public:
        void removeTouch();
 
        DSXkb *getXkb();
+       std::shared_ptr<DSWindow> getTopWindow(std::shared_ptr<DSWindow> winExcl);
        std::shared_ptr<DSWindow> getTopWindowOnPosition(int x, int y);
 
 private:
@@ -109,6 +110,7 @@ private:
        void __onPointerEvent(DSInputMouseEvent *ev);
        void __onTouchEvent(DSInputTouchEvent *ev);
        void __onWindowCreated(std::shared_ptr<DSWindow> window);
+       void __onWindowDestroy(std::shared_ptr<DSWindow> window);
 };
 
 }