From 85f45be7271252d86d583411780a4b139ee1aa75 Mon Sep 17 00:00:00 2001
From: fluxgen <fluxgen>
Date: Sun, 18 Jun 2006 21:23:24 +0000
Subject: added support for _NET_WM_WINDOW_TYPE_DIALOG and _NET_FRAME_EXTENTS

---
 src/AtomHandler.hh |  2 +-
 src/Ewmh.cc        | 45 ++++++++++++++++++++++++++++++++++++++++++---
 src/Ewmh.hh        |  7 ++++++-
 src/Window.cc      |  4 ++++
 src/fluxbox.cc     |  8 ++++++++
 src/fluxbox.hh     |  2 ++
 6 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/src/AtomHandler.hh b/src/AtomHandler.hh
index b44d92f..cec75d3 100644
--- a/src/AtomHandler.hh
+++ b/src/AtomHandler.hh
@@ -53,7 +53,7 @@ public:
     virtual void updateState(FluxboxWindow &win) = 0;
     virtual void updateHints(FluxboxWindow &win) = 0;
     virtual void updateLayer(FluxboxWindow &win) = 0;
-
+    virtual void updateFrameExtents(FluxboxWindow &win) { }
     virtual bool checkClientMessage(const XClientMessageEvent &ce, 
                                     BScreen * screen, WinClient * const winclient) = 0;
 
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index af9343f..b80c4cf 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -140,6 +140,7 @@ void Ewmh::initForScreen(BScreen &screen) {
         m_net_wm_window_type_dock,
         m_net_wm_window_type_desktop,
         m_net_wm_window_type_splash,
+        m_net_wm_window_type_dialog,
         m_net_wm_window_type_normal,
 
         // window actions
@@ -168,6 +169,7 @@ void Ewmh::initForScreen(BScreen &screen) {
 
         m_net_wm_moveresize,
         
+        m_net_frame_extents,
 
         // desktop properties
         m_net_wm_desktop,
@@ -259,7 +261,6 @@ void Ewmh::setupFrame(FluxboxWindow &win) {
                 // we also assume it shouldn't be visible in any toolbar
                 win.setFocusHidden(true);
                 win.setIconHidden(true);
-                break;
             } else if (atoms[l] == m_net_wm_window_type_desktop) {
                 /*
                  * _NET_WM_WINDOW_TYPE_DESKTOP indicates a "false desktop" window
@@ -284,14 +285,28 @@ void Ewmh::setupFrame(FluxboxWindow &win) {
                  * is starting up.
                  */
                 win.setDecoration(FluxboxWindow::DECOR_NONE);
+                win.setFocusHidden(true);
+                win.setIconHidden(true);
                 win.setMovable(false);
             } else if (atoms[l] == m_net_wm_window_type_normal) {
                 // do nothing, this is ..normal..
+            } else if (atoms[l] == m_net_wm_window_type_dialog) {
+                // dialog windows should not be tabable
+                win.setTabable(false);
             }
 
         }
         XFree(data);
-    } 
+    } else {
+        // if _NET_WM_WINDOW_TYPE not set and this window 
+        // has transient_for the type must be set to _NET_WM_WINDOW_TYPE_DIALOG 
+        if ( win.winClient().isTransient() ) {
+            win.winClient().
+                changeProperty(m_net_wm_window_type, 
+                               XA_ATOM, 32, PropModeReplace,
+                               (unsigned char*)&m_net_wm_window_type_dialog, 1);
+        }
+    }
 
     setupState(win);
 
@@ -305,8 +320,11 @@ void Ewmh::setupFrame(FluxboxWindow &win) {
             win.setWorkspace(desktop);
 
         XFree(data);
-    } else 
+    } else {
         updateWorkspace(win);
+    }
+
+    updateFrameExtents(win);
 
 }
 
@@ -940,6 +958,7 @@ void Ewmh::createAtoms() {
     m_net_wm_window_type_dock = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_DOCK", False);
     m_net_wm_window_type_desktop = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_DESKTOP", False);
     m_net_wm_window_type_splash = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_SPLASH", False);
+    m_net_wm_window_type_dialog = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_DIALOG", False);
     m_net_wm_window_type_normal = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_NORMAL", False);
 
     // state atom and the supported state atoms
@@ -976,6 +995,8 @@ void Ewmh::createAtoms() {
     m_net_wm_pid = XInternAtom(disp, "_NET_WM_PID", False);
     m_net_wm_handled_icons = XInternAtom(disp, "_NET_WM_HANDLED_ICONS", False);
 
+    m_net_frame_extents = XInternAtom(disp, "_NET_FRAME_EXTENTS", False);
+
     m_net_wm_ping = XInternAtom(disp, "_NET_WM_PING", False);
     utf8_string = XInternAtom(disp, "UTF8_STRING", False);
 }
@@ -1220,6 +1241,23 @@ void Ewmh::setupState(FluxboxWindow &win) {
     }
 }
 
+void Ewmh::updateFrameExtents(FluxboxWindow &win) {
+    int extents[4];
+    extents[0] = win.frame().x();
+    extents[1] = win.frame().x() + win.frame().width();
+    extents[2] = win.frame().y();
+    extents[3] = win.frame().y() + win.frame().height();
+
+    FluxboxWindow::ClientList::iterator it = win.clientList().begin();
+    FluxboxWindow::ClientList::iterator it_end = win.clientList().end();
+    for (; it != it_end; ++it) {
+        (*it)->changeProperty(m_net_frame_extents,
+                              XA_CARDINAL, 32, PropModeReplace,
+                              (unsigned char *)extents, 4);
+    }
+}
+
+
 Ewmh::WindowState::WindowState(int t_x, int t_y,
                                unsigned int t_width,
                                unsigned int t_height,
@@ -1255,3 +1293,4 @@ void Ewmh::saveState(FluxboxWindow &win, WindowState *state) {
     m_savedstate[&win] = state;
 }
 
+
diff --git a/src/Ewmh.hh b/src/Ewmh.hh
index 6044f7c..1643d17 100644
--- a/src/Ewmh.hh
+++ b/src/Ewmh.hh
@@ -64,6 +64,7 @@ public:
 
     void setFullscreen(FluxboxWindow &win, bool value);
 
+    void updateFrameExtents(FluxboxWindow &win);
 private:
 
     typedef struct WindowState {
@@ -83,6 +84,7 @@ private:
 
     void setupState(FluxboxWindow &win);
 
+
     // root window properties
     Atom m_net_supported, 
         m_net_client_list, 
@@ -110,6 +112,7 @@ private:
         m_net_wm_window_type_dock,
         m_net_wm_window_type_desktop,
         m_net_wm_window_type_splash,
+        m_net_wm_window_type_dialog,
         m_net_wm_window_type_normal,
 
         // states
@@ -137,7 +140,9 @@ private:
         m_net_wm_action_close,
 
         m_net_wm_strut, m_net_wm_icon_geometry, m_net_wm_icon, m_net_wm_pid,
-        m_net_wm_handled_icons;
+        m_net_wm_handled_icons,
+
+        m_net_frame_extents;
 
     // application protocols
     Atom m_net_wm_ping;
diff --git a/src/Window.cc b/src/Window.cc
index 2311634..13167e7 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -3900,6 +3900,10 @@ void FluxboxWindow::sendConfigureNotify(bool send_to_netizens) {
             screen().updateNetizenConfigNotify(event);
         }
     } // end for
+
+    if (send_to_netizens) {
+        Fluxbox::instance()->updateFrameExtents(*this);
+    }
 }
 
 
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 70c5993..94c9730 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -1847,3 +1847,11 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) {
                   screen.rootWindow().window(), True,
                   GrabModeAsync, GrabModeAsync, CurrentTime);
 }
+
+void Fluxbox::updateFrameExtents(FluxboxWindow &win) {
+    AtomHandlerContainerIt it = m_atomhandler.begin();
+    AtomHandlerContainerIt it_end = m_atomhandler.end();
+    for (; it != it_end; ++it ) {
+        (*it).first->updateFrameExtents(win);
+    }
+}
diff --git a/src/fluxbox.hh b/src/fluxbox.hh
index c3936c7..206fcd4 100644
--- a/src/fluxbox.hh
+++ b/src/fluxbox.hh
@@ -182,6 +182,8 @@ public:
      * @param old_screen the old screen if any, can be the same as new screen
      */
     void updateFocusedWindow(BScreen *screen, BScreen *old_screen);
+    /// todo, remove this. just temporary
+    void updateFrameExtents(FluxboxWindow &win);
 
     void attachSignals(FluxboxWindow &win);
     void attachSignals(WinClient &winclient);
-- 
cgit v0.11.2