Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 icewm (1.9.0-1.0antix1) unstable; urgency=medium
 .
   * latest uptream rlease
   * antiX buster build
Author: anticapitalista <antix@operamail.com>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2020-10-30

--- icewm-1.9.1.orig/icewm.spec.in
+++ icewm-1.9.1/icewm.spec.in
@@ -116,22 +116,8 @@ GNOME 1.0 menu support for icewm (using
 
 %files themes
 %defattr(-,root,root)
-%dir %{pkgdata}/themes/CrystalBlue
-%{pkgdata}/themes/CrystalBlue/*
-%dir %{pkgdata}/themes/Helix
-%{pkgdata}/themes/Helix/*
-%dir %{pkgdata}/themes/NanoBlue
-%{pkgdata}/themes/NanoBlue/*
-%dir %{pkgdata}/themes/motif
-%{pkgdata}/themes/motif/*
-%dir %{pkgdata}/themes/win95
-%{pkgdata}/themes/win95/*
 %dir %{pkgdata}/themes/metal2
 %{pkgdata}/themes/metal2/*
-%dir %{pkgdata}/themes/Infadel2
-%{pkgdata}/themes/Infadel2/*
-%dir %{pkgdata}/themes/icedesert
-%{pkgdata}/themes/icedesert/*
 
 %changelog
 * Mon Jun 12 2017 Bert Gijsbers
--- icewm-1.9.1.orig/lib/CMakeLists.txt
+++ icewm-1.9.1/lib/CMakeLists.txt
@@ -4,8 +4,7 @@ PROJECT(ICEWM CXX)
 #
 # Which themes to install in alphabetical order
 #
-set(themesList CrystalBlue Helix Infadel2 NanoBlue
-    default icedesert metal2 motif win95)
+set(themesList metal2)
 
 foreach(_src keys menu programs toolbar winoptions IceWM.jpg)
     set(_pre "${CMAKE_CURRENT_SOURCE_DIR}/${_src}.in")
--- icewm-1.9.1.orig/src/aclock.cc
+++ icewm-1.9.1/src/aclock.cc
@@ -56,7 +56,6 @@ YClock::YClock(YSMListener *smActionList
 
     autoSize();
     updateToolTip();
-    setDND(true);
     setTitle("Clock");
     show();
 }
--- icewm-1.9.1.orig/src/icehelp.cc
+++ icewm-1.9.1/src/icehelp.cc
@@ -1809,7 +1809,7 @@ void HTextView::handleClick(const XButto
     }
 }
 
-class FileView: public YWindow, public HTListener {
+class FileView: public YDndWindow, public HTListener {
 public:
     FileView(YApplication *app, int argc, char **argv);
     ~FileView() {
--- icewm-1.9.1.orig/src/iceicon.cc
+++ icewm-1.9.1/src/iceicon.cc
@@ -174,7 +174,6 @@ YIconView::YIconView(YScrollView *view,
     fOffsetX = fOffsetY = 0;
     fItems = 0;
     setBitGravity(NorthWestGravity);
-    setDoubleBuffer(true);
 }
 
 YIconView::~YIconView() {
@@ -473,7 +472,7 @@ ObjectIconView::~ObjectIconView() {
     }
 }
 
-class ObjectList: public YWindow {
+class ObjectList: public YDndWindow {
 public:
     static int winCount;
 
--- icewm-1.9.1.orig/src/icelist.cc
+++ icewm-1.9.1/src/icelist.cc
@@ -98,11 +98,11 @@ private:
     YAction actionOpenIcon;
 };
 
-class ObjectList: public YWindow {
+class ObjectList: public YDndWindow {
 public:
     static int winCount;
 
-    ObjectList(const char *path, YWindow *aParent): YWindow(aParent) {
+    ObjectList(const char *path, YWindow *aParent): YDndWindow(aParent) {
         setDND(true);
         fPath = newstr(path);
         scroll = new YScrollView(this);
@@ -137,9 +137,9 @@ public:
     ~ObjectList() {
         winCount--;
 
-        while (list->getFirst()) {
+        while (list->getItem(0)) {
             ObjectListItem* item =
-                static_cast<ObjectListItem *>(list->getFirst());
+                static_cast<ObjectListItem *>(list->getItem(0));
             list->removeItem(item);
             delete item;
         }
--- icewm-1.9.1.orig/src/iceview.cc
+++ icewm-1.9.1/src/iceview.cc
@@ -582,10 +582,9 @@ private:
     YAction actionToggleExpandTabs, actionToggleWrapLines, actionToggleHexView;
 };
 
-class FileView: public YWindow {
+class FileView: public YDndWindow {
 public:
     FileView(char *path) :
-        YWindow(desktop, None),
         fPath(newstr(path)),
         scroll(new YScrollView(this)),
         view(new TextView(scroll, this))
--- icewm-1.9.1.orig/src/logevent.cc
+++ icewm-1.9.1/src/logevent.cc
@@ -108,15 +108,22 @@ void logColormap(const XColormapEvent& x
 }
 
 void logConfigureNotify(const XConfigureEvent& xev) {
-    tlog("window=0x%lX: configureNotify serial=%lu event=0x%lX, (%+d%+d %dx%d) border=%d, above=0x%lX, override=%s",
+    const int size = 256;
+    char buf[size];
+    int len = snprintf(buf, size, "window=0x%lX: configureNotify serial=%lu event=0x%lX, (%+d%+d %dx%d) border=%d",
         xev.window,
         (unsigned long) xev.serial,
         xev.event,
         xev.x, xev.y,
         xev.width, xev.height,
-        xev.border_width,
-        xev.above,
-        boolStr(xev.override_redirect));
+        xev.border_width);
+    if (xev.above)
+        len += snprintf(buf + len, size - len, " above=0x%lX", xev.above);
+    if (xev.override_redirect)
+        len += snprintf(buf + len, size - len, " override=%s", boolStr(xev.override_redirect));
+    if (xev.send_event)
+        len += snprintf(buf + len, size - len, " send=%s", boolStr(xev.send_event));
+    tlog("%s", (0 < len && len < size) ? buf : "lcnbug");
 }
 
 void logConfigureRequest(const XConfigureRequestEvent& xev) {
--- icewm-1.9.1.orig/src/obj.h
+++ icewm-1.9.1/src/obj.h
@@ -29,7 +29,7 @@ class ObjectContainer {
 public:
     virtual void addObject(DObject *object) = 0;
     virtual void addSeparator() = 0;
-    virtual void addContainer(const mstring &name, ref<YIcon> icon, ObjectMenu *container) = 0;
+    virtual void addContainer(mstring name, ref<YIcon> icon, ObjectMenu *container) = 0;
 protected:
     virtual ~ObjectContainer() {}
 };
--- icewm-1.9.1.orig/src/objbar.cc
+++ icewm-1.9.1/src/objbar.cc
@@ -27,7 +27,7 @@ ObjectBar::~ObjectBar() {
     ObjectButton::freeFont();
 }
 
-void ObjectBar::addButton(const mstring &name, ref<YIcon> icon, ObjectButton *button) {
+void ObjectBar::addButton(mstring name, ref<YIcon> icon, ObjectButton *button) {
     button->setToolTip(name);
     if (icon != null) {
         button->setIcon(icon, YIcon::smallSize());
@@ -57,6 +57,7 @@ void ObjectBar::paint(Graphics &g, const
 
 void ObjectBar::addObject(DObject *object) {
     ObjectButton *button = new ObjectButton(this, object);
+    button->setTitle(object->getName().c_str());
     addButton(object->getName(), object->getIcon(), button);
 }
 
@@ -65,9 +66,10 @@ void ObjectBar::addSeparator() {
     objects.append(0);
 }
 
-void ObjectBar::addContainer(const mstring &name, ref<YIcon> icon, ObjectMenu *container) {
+void ObjectBar::addContainer(mstring name, ref<YIcon> icon, ObjectMenu *container) {
     if (container) {
         ObjectButton *button = new ObjectButton(this, container);
+        button->setTitle(name.c_str());
         addButton(name, icon, button);
     }
 }
--- icewm-1.9.1.orig/src/objbar.h
+++ icewm-1.9.1/src/objbar.h
@@ -22,11 +22,11 @@ public:
 
     virtual void addObject(DObject *object);
     virtual void addSeparator();
-    virtual void addContainer(const mstring &name, ref<YIcon> icon, ObjectMenu *container);
+    virtual void addContainer(mstring name, ref<YIcon> icon, ObjectMenu *container);
 
     virtual void paint(Graphics &g, const YRect &r);
 
-    void addButton(const mstring &name, ref<YIcon> icon, ObjectButton *button);
+    void addButton(mstring name, ref<YIcon> icon, ObjectButton *button);
     void refresh();
 
 private:
--- icewm-1.9.1.orig/src/objmenu.h
+++ icewm-1.9.1/src/objmenu.h
@@ -27,7 +27,7 @@ public:
     virtual void addObject(DObject *object);
     virtual void addObject(DObject *object, const char *icons);
     virtual void addSeparator();
-    virtual void addContainer(const mstring &name, ref<YIcon> icon, ObjectMenu *container);
+    virtual void addContainer(mstring name, ref<YIcon> icon, ObjectMenu *container);
 protected:
     YActionListener *wmActionListener;
 };
--- icewm-1.9.1.orig/src/wmclient.cc
+++ icewm-1.9.1/src/wmclient.cc
@@ -42,7 +42,7 @@ bool operator!=(const XSizeHints& a, con
 
 YFrameClient::YFrameClient(YWindow *parent, YFrameWindow *frame, Window win,
                            int depth, Visual *visual, Colormap colormap):
-    YWindow(parent, win, depth, visual, colormap),
+    YDndWindow(parent, win, depth, visual, colormap),
     fWindowTitle(),
     fIconTitle(),
     fWindowRole()
@@ -60,7 +60,6 @@ YFrameClient::YFrameClient(YWindow *pare
     fSavedWinState[0] = None;
     fSavedWinState[1] = None;
     fSizeHints = XAllocSizeHints();
-    fSaveHints = XAllocSizeHints();
     fTransientFor = None;
     fClientLeader = None;
     fPid = 0;
@@ -109,7 +108,6 @@ YFrameClient::~YFrameClient() {
     }
 
     if (fSizeHints) { XFree(fSizeHints); fSizeHints = nullptr; }
-    if (fSaveHints) { XFree(fSaveHints); fSaveHints = nullptr; }
     if (fHints) { XFree(fHints); fHints = nullptr; }
 }
 
@@ -566,7 +564,7 @@ void YFrameClient::handleProperty(const
             getSizeHints();
             if (old != *fSizeHints) {
                 if (getFrame())
-                    getFrame()->updateMwmHints();
+                    getFrame()->updateMwmHints(&old);
             }
         }
         prop.wm_normal_hints = new_prop;
@@ -666,7 +664,7 @@ void YFrameClient::handleProperty(const
             if (new_prop) prop.mwm_hints = true;
             getMwmHints();
             if (getFrame())
-                getFrame()->updateMwmHints();
+                getFrame()->updateMwmHints(fSizeHints);
             prop.mwm_hints = new_prop;
         } else if (property.atom == _XA_WM_CLIENT_LEADER) { // !!! check these
             if (new_prop) prop.wm_client_leader = true;
@@ -939,7 +937,7 @@ void YFrameClient::handleClientMessage(c
             setWinStateHint(mask, want);
         }
     } else
-        YWindow::handleClientMessage(message);
+        super::handleClientMessage(message);
 }
 
 void YFrameClient::netStateRequest(long action, long mask) {
@@ -1152,18 +1150,6 @@ void YFrameClient::setMwmHints(const Mwm
     *fMwmHints = mwm;
 }
 
-void YFrameClient::saveSizeHints() {
-    if (fSaveHints && fSizeHints) {
-        *fSaveHints = *fSizeHints;
-    }
-}
-
-void YFrameClient::restoreSizeHints() {
-    if (fSizeHints && fSaveHints) {
-        *fSizeHints = *fSaveHints;
-    }
-}
-
 long YFrameClient::mwmFunctions() {
     long functions = ~0U;
 
--- icewm-1.9.1.orig/src/wmclient.h
+++ icewm-1.9.1/src/wmclient.h
@@ -128,9 +128,10 @@ protected:
     virtual ~ClientData() {}
 };
 
-class YFrameClient: public YWindow
+class YFrameClient: public YDndWindow
                   , public YTimerListener
 {
+    typedef YDndWindow super;
 public:
     YFrameClient(YWindow *parent, YFrameWindow *frame, Window win = 0,
                  int depth = 0, Visual *visual = nullptr, Colormap cmap = 0);
@@ -184,9 +185,6 @@ public:
 
     void getSizeHints();
     XSizeHints *sizeHints() const { return fSizeHints; }
-    XSizeHints *saveHints() const { return fSaveHints; }
-    void saveSizeHints();
-    void restoreSizeHints();
 
     unsigned protocols() const { return fProtocols; }
     void getProtocols(bool force);
@@ -279,7 +277,6 @@ private:
     FrameState fSavedFrameState;
     long fSavedWinState[2];
     XSizeHints *fSizeHints;
-    XSizeHints *fSaveHints;
     ClassHint fClassHint;
     XWMHints *fHints;
     Colormap fColormap;
--- icewm-1.9.1.orig/src/wmframe.cc
+++ icewm-1.9.1/src/wmframe.cc
@@ -114,7 +114,7 @@ YFrameWindow::YFrameWindow(
     fWinOptionMask = ~0;
     fOldState = 0;
     fTrayOrder = 0;
-    fClientContainer = nullptr;
+    fContainer = nullptr;
     setTitle("Frame");
     setBackground(inactiveBorderBg);
 }
@@ -172,7 +172,7 @@ YFrameWindow::~YFrameWindow() {
     }
 
     delete fClient; fClient = nullptr;
-    delete fClientContainer; fClientContainer = nullptr;
+    delete fContainer; fContainer = nullptr;
     delete fTitleBar; fTitleBar = nullptr;
 
     manager->unlockWorkArea();
@@ -207,7 +207,7 @@ YFrameTitleBar* YFrameWindow::titlebar()
 }
 
 void YFrameWindow::doManage(YFrameClient *clientw, bool &doActivate, bool &requestFocus) {
-    PRECONDITION(clientw != 0 && !fClientContainer && !fClient);
+    PRECONDITION(clientw != 0 && !fContainer && !fClient);
 
     if (clientw->handle() == None || clientw->destroyed()) {
         return;
@@ -217,7 +217,7 @@ void YFrameWindow::doManage(YFrameClient
     bool sameDepth = (depth == xapp->depth());
     Visual* visual = (sameDepth ? xapp->visual() : clientw->visual());
     Colormap clmap = (sameDepth ? xapp->colormap() : clientw->colormap());
-    fClientContainer = new YClientContainer(this, this, depth, visual, clmap);
+    fContainer = new YClientContainer(this, this, depth, visual, clmap);
 
     fClient = clientw;
     if (hintOptions && hintOptions->nonempty()) {
@@ -592,21 +592,19 @@ void YFrameWindow::configureClient(const
     if (hasbit(mask, CWX | CWY | CWWidth | CWHeight)) {
         int cx, cy, cw, ch;
         getNewPos(configureRequest, cx, cy, cw, ch);
-
         configureClient(cx, cy, cw, ch);
     }
 
     if (hasbit(mask, CWStackMode)) {
-        long window = hasbit(mask, CWSibling) ? configureRequest.above : None;
-        long detail = configureRequest.detail;
-        if (inrange<long>(detail, Above, Opposite)) {
-            netRestackWindow(window, detail);
+        Window window = hasbit(mask, CWSibling) ? configureRequest.above : None;
+        if (inrange(configureRequest.detail, Above, Opposite)) {
+            netRestackWindow(window, configureRequest.detail);
         }
     }
     sendConfigure();
 }
 
-void YFrameWindow::netRestackWindow(long window, long detail) {
+void YFrameWindow::netRestackWindow(Window window, int detail) {
     YFrameWindow* sibling = window ? manager->findFrame(window) : nullptr;
     if (sibling) {
         switch (detail) {
@@ -771,7 +769,7 @@ void YFrameWindow::configureClient(int c
     MSG(("setting geometry (%d:%d %dx%d)", cx, cy, cwidth, cheight));
     cy -= titleYN();
     if (isFullscreen()) {
-        XSizeHints *sh = client()->saveHints();
+        XSizeHints *sh = client()->sizeHints();
         if (sh) {
             normalX = cx;
             normalY = cy;
@@ -2076,10 +2074,10 @@ WindowOption YFrameWindow::getWindowOpti
 void YFrameWindow::getWindowOptions(WindowOptions *list, WindowOption &opt,
                                     bool remove)
 {
-    XClassHint const *h(client()->classHint());
-    mstring klass = h ? h->res_class : nullptr;
-    mstring name = h ? h->res_name : nullptr;
-    mstring role = client()->windowRole();
+    const ClassHint* h = client()->classHint();
+    mstring klass(h->res_class);
+    mstring name(h->res_name);
+    mstring role(client()->windowRole());
 
     if (klass != null) {
         if (name != null) {
@@ -2311,7 +2309,7 @@ void YFrameWindow::updateIcon() {
             pix[1] = (h->flags & IconMaskHint) ? h->icon_mask : None;
             fFrameIcon = newClientIcon(1, 2, pix);
         }
-        else if (fFrameIcon == null && client()->classHint()) {
+        else if (fFrameIcon == null) {
             const char* name = client()->classHint()->res_name;
             if (nonempty(name)) {
                 fFrameIcon = YIcon::getIcon(name);
@@ -3046,24 +3044,6 @@ void YFrameWindow::setState(long mask, l
     fOldState = fWinState;
     long fNewState = (fWinState & ~mask) | (state & mask);
     long deltaState = fOldState ^ fNewState;
-
-    // !!! this should work
-    //if (fNewState == fOldState)
-    //    return ;
-
-    if (deltaState & WinStateFullscreen) {
-        if ((fNewState & WinStateFullscreen)) {
-            // going fullscreen
-            client()->saveSizeHints();
-        }
-        else {
-            // going back
-            client()->restoreSizeHints();
-        }
-    }
-
-    // !!! move here
-
     fWinState = fNewState;
 
     MSG(("setState: oldState: %lX, newState: %lX, mask: %lX, state: %lX",
@@ -3186,10 +3166,14 @@ void YFrameWindow::setDoNotCover(bool do
 }
 #endif
 
-void YFrameWindow::updateMwmHints() {
+void YFrameWindow::updateMwmHints(XSizeHints* sh) {
     YDimension old(dimension());
     getFrameHints();
-    setNormalGeometryInner(posX, posY, posW, posH);
+    int nwidth = sh ? normalW * max(1, sh->width_inc) + sh->base_width
+                    : client()->width();
+    int height = sh ? normalH * max(1, sh->height_inc) + sh->base_height
+                    : client()->height();
+    setNormalGeometryInner(normalX, normalY, nwidth, height);
     if (old == dimension()) {
         performLayout();
     }
--- icewm-1.9.1.orig/src/wmframe.h
+++ icewm-1.9.1/src/wmframe.h
@@ -110,7 +110,7 @@ public:
 
     YFrameClient *client() const { return fClient; }
     YFrameTitleBar *titlebar();
-    YClientContainer *container() const { return fClientContainer; }
+    YClientContainer *container() const { return fContainer; }
 
     void startMoveSize(int x, int y, int direction);
 
@@ -198,7 +198,7 @@ public:
                    int &cx, int &cy, int &cw, int &ch);
     void configureClient(const XConfigureRequestEvent &configureRequest);
     void configureClient(int cx, int cy, int cwidth, int cheight);
-    void netRestackWindow(long window, long detail);
+    void netRestackWindow(Window window, int detail);
 
     void setShape();
 
@@ -331,7 +331,7 @@ public:
     void updateLayout();
     void performLayout();
 
-    void updateMwmHints();
+    void updateMwmHints(XSizeHints* sh);
     void updateProperties();
     void updateTaskBar();
     void updateAppStatus();
@@ -445,7 +445,7 @@ private:
     int posX, posY, posW, posH;
 
     YFrameClient *fClient;
-    YClientContainer *fClientContainer;
+    YClientContainer *fContainer;
     YFrameTitleBar *fTitleBar;
 
     YPopupWindow *fPopupActive;
--- icewm-1.9.1.orig/src/wmmgr.cc
+++ icewm-1.9.1/src/wmmgr.cc
@@ -306,9 +306,9 @@ bool YWindowManager::handleWMKey(const X
             wmapp->getSwitchWindow()->begin(false, key.state);
             return true;
         } else if (gKeySysSwitchClass.eq(k, vm)) {
+            XAllowEvents(xapp->display(), AsyncKeyboard, key.time);
             char *prop = frame && frame->client()->adopted()
                        ? frame->client()->classHint()->resource() : nullptr;
-            XAllowEvents(xapp->display(), AsyncKeyboard, key.time);
             wmapp->getSwitchWindow()->begin(true, key.state, prop);
             return true;
         }
--- icewm-1.9.1.orig/src/wmprog.cc
+++ icewm-1.9.1/src/wmprog.cc
@@ -73,7 +73,7 @@ void ObjectMenu::addSeparator() {
     YMenu::addSeparator();
 }
 
-void ObjectMenu::addContainer(const mstring &name, ref<YIcon> icon, ObjectMenu *container) {
+void ObjectMenu::addContainer(mstring name, ref<YIcon> icon, ObjectMenu *container) {
     if (container) {
         YMenuItem *item =
             addSubmenu(name, -3, container);
@@ -520,7 +520,6 @@ public:
         for (int k = 0; ; ++k)
             if (icewm_preferences[k].type == cfoption::CF_NONE)
                 return k;
-        return 0;
     }
 
     static int sortPrefs(const void* p1, const void* p2) {
--- icewm-1.9.1.orig/src/wmsession.cc
+++ icewm-1.9.1/src/wmsession.cc
@@ -93,15 +93,8 @@ bool SMWindows::findWindowInfo(YFrameWin
             if (window->key.windowClass != null &&
                 window->key.windowInstance != null)
             {
-                mstring klass = null;
-                mstring instance = null;
-                XClassHint *ch = f->client()->classHint();
-
-                if (ch) {
-                    klass = ch->res_class;
-                    instance = ch->res_name;
-                }
-
+                mstring klass(f->client()->classHint()->res_class);
+                mstring instance(f->client()->classHint()->res_name);
                 if (klass.equals(window->key.windowClass) &&
                     instance.equals(window->key.windowInstance))
                 {
@@ -289,15 +282,8 @@ void YWMApp::smSaveYourselfPhase2() {
                     wr_str(fp, cid.c_str());
                     wr_str(fp, role.c_str());
                 } else {
-                    f->client()->getClassHint();
-                    char *klass = nullptr;
-                    char *instance = nullptr;
-                    XClassHint *ch = f->client()->classHint();
-                    if (ch) {
-                        klass = ch->res_class;
-                        instance = ch->res_name;
-                    }
-
+                    char* klass = f->client()->classHint()->res_class;
+                    char* instance = f->client()->classHint()->res_name;
                     if (klass && instance) {
                         //msg("k=%s, i=%s", klass, instance);
                         fprintf(fp, "c ");
--- icewm-1.9.1.orig/src/wmtaskbar.cc
+++ icewm-1.9.1/src/wmtaskbar.cc
@@ -45,7 +45,7 @@ EdgeTrigger::EdgeTrigger(TaskBar *owner)
 {
     setStyle(wsOverrideRedirect | wsInputOnly);
     setPointer(YXApplication::leftPointer);
-    setDND(true);
+    setDND(enabled());
     setTitle("IceEdge");
 }
 
--- icewm-1.9.1.orig/src/wmtaskbar.h
+++ icewm-1.9.1/src/wmtaskbar.h
@@ -30,7 +30,7 @@ class TaskBar;
 class TaskBarApp;
 class TrayApp;
 
-class EdgeTrigger: public YWindow, public YTimerListener {
+class EdgeTrigger: public YDndWindow, public YTimerListener {
 public:
     EdgeTrigger(TaskBar *owner);
     virtual ~EdgeTrigger();
--- icewm-1.9.1.orig/src/ywindow.cc
+++ icewm-1.9.1/src/ywindow.cc
@@ -132,8 +132,7 @@ YWindow::YWindow(YWindow *parent, Window
     fEventMask(KeyPressMask|KeyReleaseMask|FocusChangeMask|
                LeaveWindowMask|EnterWindowMask),
     fWinGravity(NorthWestGravity), fBitGravity(ForgetGravity),
-    accel(nullptr),
-    XdndDragSource(None), XdndDropTarget(None)
+    accel(nullptr)
 {
     if (fHandle != None) {
         MSG(("adopting window %lX", fHandle));
@@ -962,7 +961,7 @@ void YWindow::handleCrossing(const XCros
     }
 }
 
-void YWindow::handleClientMessage(const XClientMessageEvent &message) {
+void YWindow::handleClientMessage(const XClientMessageEvent& message) {
     if (message.message_type == _XA_WM_PROTOCOLS
         && message.format == 32
         && message.data.l[0] == long(_XA_WM_DELETE_WINDOW))
@@ -982,7 +981,10 @@ void YWindow::handleClientMessage(const
             gotFocus();
 #endif
     }
-    else if (message.message_type == XA_XdndEnter) {
+}
+
+void YDndWindow::handleClientMessage(const XClientMessageEvent& message) {
+    if (message.message_type == XA_XdndEnter) {
         handleXdndEnter(message);
     }
     else if (message.message_type == XA_XdndLeave) {
@@ -1000,6 +1002,9 @@ void YWindow::handleClientMessage(const
     else if (message.message_type == XA_XdndFinished) {
         handleXdndFinished(message);
     }
+    else {
+        YWindow::handleClientMessage(message);
+    }
 }
 
 void YWindow::handleVisibility(const XVisibilityEvent& visibility) {
@@ -1436,6 +1441,10 @@ void YWindow::removeAccelerator(unsigned
     } else parent()->removeAccelerator(key, mod, win);
 }
 
+void YWindow::deleteProperty(Atom property) {
+    XDeleteProperty(xapp->display(), handle(), property);
+}
+
 void YWindow::setProperty(Atom prop, Atom type, const Atom* values, int count) {
     XChangeProperty(xapp->display(), handle(), prop, type, 32, PropModeReplace,
                     reinterpret_cast<const unsigned char *>(values), count);
@@ -1463,19 +1472,23 @@ void YWindow::setToplevel(bool enabled)
     }
 }
 
-void YWindow::setDND(bool enabled) {
-    if (isDragDrop() != enabled) {
-        flags = enabled ? (flags | wfDragDrop) : (flags &~ wfDragDrop);
-        if (isDragDrop()) {
-            enum { XdndCurrentVersion = 5, };
-            setProperty(XA_XdndAware, XA_ATOM, XdndCurrentVersion);
-        } else {
-            XDeleteProperty(xapp->display(), handle(), XA_XdndAware);
-        }
+YDndWindow::YDndWindow(YWindow* parent, Window win, int depth,
+                       Visual* visual, Colormap colormap) :
+    YWindow(parent, win, depth, visual, colormap),
+    XdndDragSource(None),
+    XdndDropTarget(None)
+{
+}
+
+void YDndWindow::setDND(bool enabled) {
+    if (enabled) {
+        setProperty(XA_XdndAware, XA_ATOM, XdndCurrentVersion);
+    } else {
+        deleteProperty(XA_XdndAware);
     }
 }
 
-void YWindow::sendXdndStatus(bool acceptDrop, Atom dropAction) {
+void YDndWindow::sendXdndStatus(bool acceptDrop, Atom dropAction) {
     if (XdndDragSource) {
         int x_root = 0, y_root = 0;
         mapToGlobal(x_root, y_root);
@@ -1492,31 +1505,29 @@ void YWindow::sendXdndStatus(bool accept
     }
 }
 
-void YWindow::handleXdndEnter(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndEnter(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndEnter) {
-        enum { XdndCurrentVersion = 5, };
         const long* data = message.data.l;
         long version = ((data[1] >> 24) & 0xF);
+        MSG(("XdndEnter source=0x%lX version=%ld %ld %ld %ld",
+              data[0], version, data[2], data[3], data[4]));
         if (version <= XdndCurrentVersion) {
-            MSG(("XdndEnter source=%lX", data[0]));
             XdndDragSource = static_cast<Window>(data[0]);
-            memcpy(XdndDataTypes, &data[2], sizeof(XdndDataTypes));
         } else {
             XdndDragSource = None;
-            memset(XdndDataTypes, 0, sizeof(XdndDataTypes));
         }
         XdndDropTarget = None;
     }
 }
 
-void YWindow::handleXdndLeave(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndLeave(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndLeave) {
         Window source = static_cast<Window>(message.data.l[0]);
-        MSG(("XdndLeave source=%lX", source));
+        MSG(("XdndLeave source=0x%lX", source));
         if (source == XdndDragSource && XdndDragSource) {
             if (XdndDropTarget) {
-                YWindow* win = nullptr;
-                if (windowContext.find(XdndDropTarget, &win))
+                YWindow* win = windowContext.find(XdndDropTarget);
+                if (win)
                     win->handleDNDLeave();
                 XdndDropTarget = None;
             }
@@ -1525,16 +1536,15 @@ void YWindow::handleXdndLeave(const XCli
     }
 }
 
-void YWindow::handleXdndPosition(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndPosition(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndPosition && XdndDragSource) {
         const long* data = message.data.l;
         XdndDragSource = static_cast<Window>(data[0]);
-        XdndUserAction = data[4];
         int x = short(data[2] >> 16);
         int y = short(data[2] & 0xFFFF);
 
-        MSG(("XdndPosition source=%lX %d:%d time=%ld action=%ld window=%ld",
-              data[0], x, y, data[3], data[4], XdndDropTarget));
+        MSG(("XdndPosition 0x%lX %s 0x%lX %d:%d",
+             data[0], xapp->atomName(data[4]), handle(), x, y));
 
         Window target = handle(), child = None;
         int nx, ny;
@@ -1553,44 +1563,49 @@ void YWindow::handleXdndPosition(const X
         YWindow* pwin = nullptr;
         if (target != XdndDropTarget) {
             if (XdndDropTarget) {
-                YWindow *ptr = nullptr;
-                if (windowContext.find(XdndDropTarget, &ptr))
+                YWindow* ptr = windowContext.find(XdndDropTarget);
+                if (ptr)
                     ptr->handleDNDLeave();
             }
             XdndDropTarget = target;
             if (XdndDropTarget) {
-                YWindow *ptr = nullptr;
-                if (windowContext.find(XdndDropTarget, &ptr)) {
+                YWindow* ptr = windowContext.find(XdndDropTarget);
+                if (ptr) {
                     ptr->handleDNDEnter();
                     pwin = ptr;
                 }
             }
         }
-        if (pwin == nullptr && XdndDropTarget) { // !!! optimize this
-            windowContext.find(XdndDropTarget, &pwin);
+        if (pwin == nullptr && XdndDropTarget) {
+            pwin = windowContext.find(XdndDropTarget);
         }
         if (pwin)
             pwin->handleDNDPosition(nx, ny);
-        MSG(("XdndPosition %d:%d target=%ld", nx, ny, XdndDropTarget));
-        sendXdndStatus(false, None);
+        MSG(("XdndPosition 0x%lX %s 0x%lX %d:%d",
+             data[0], xapp->atomName(data[4]), XdndDropTarget, nx, ny));
+        sendXdndStatus();
     }
 }
 
-void YWindow::handleXdndStatus(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndStatus(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndStatus) {
-        MSG(("XdndStatus"));
+        MSG(("XdndStatus target=0x%lX accept=%s",
+             message.data.l[0], boolstr(message.data.l[1] & 1)));
     }
 }
 
-void YWindow::handleXdndDrop(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndDrop(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndDrop) {
-        MSG(("XdndDrop"));
+        MSG(("XdndDrop source=0x%lx time=%ld.%03ld", message.data.l[0],
+              message.data.l[2] / 1000, message.data.l[2] % 1000));
     }
 }
 
-void YWindow::handleXdndFinished(const XClientMessageEvent& message) {
+void YDndWindow::handleXdndFinished(const XClientMessageEvent& message) {
     if (message.message_type == XA_XdndFinished) {
-        MSG(("XdndFinished"));
+        MSG(("XdndFinished target=0x%lX accept=%s action=%s",
+              message.data.l[0], boolstr(message.data.l[1] & 1),
+              xapp->atomName(message.data.l[2])));
     }
 }
 
--- icewm-1.9.1.orig/src/ywindow.h
+++ icewm-1.9.1/src/ywindow.h
@@ -194,7 +194,6 @@ public:
     virtual void gotFocus();
     virtual void lostFocus();
 
-    bool isDragDrop() const { return hasbit(flags, wfDragDrop); }
     bool isToplevel() const { return hasbit(flags, wfToplevel); }
     void setToplevel(bool toplevel);
 
@@ -211,20 +210,12 @@ public:
     void setWinGravity(int gravity);
     void setBitGravity(int gravity);
 
+    void deleteProperty(Atom property);
     void setProperty(Atom prop, Atom type, const Atom* values, int count);
     void setProperty(Atom property, Atom propType, Atom value);
     void setNetWindowType(Atom window_type);
     void setNetOpacity(Atom opacity);
     void setNetPid();
-    void setDND(bool enabled);
-
-    void sendXdndStatus(bool acceptDrop, Atom dropAction);
-    virtual void handleXdndEnter(const XClientMessageEvent& message);
-    virtual void handleXdndLeave(const XClientMessageEvent& message);
-    virtual void handleXdndPosition(const XClientMessageEvent& message);
-    virtual void handleXdndStatus(const XClientMessageEvent& message);
-    virtual void handleXdndDrop(const XClientMessageEvent& message);
-    virtual void handleXdndFinished(const XClientMessageEvent& message);
 
     virtual void handleDNDEnter();
     virtual void handleDNDLeave();
@@ -265,7 +256,6 @@ private:
         wfToplevel  = 1 << 4,
         wfNullSize  = 1 << 5,
         wfFocused   = 1 << 6,
-        wfDragDrop  = 1 << 7,
     };
 
     Window create();
@@ -315,11 +305,6 @@ private:
     static unsigned long lastEnterNotifySerial;
     static void updateEnterNotifySerial(const XEvent& event);
 
-    Window XdndDragSource;
-    Window XdndDropTarget;
-    long XdndDataTypes[3];
-    long XdndUserAction;
-
     static YAutoScroll *fAutoScroll;
 
     void addIgnoreUnmap(Window w);
@@ -327,6 +312,29 @@ private:
     void removeAllIgnoreUnmap(Window w);
 };
 
+class YDndWindow : public YWindow {
+protected:
+    YDndWindow(YWindow* parent = nullptr, Window win = 0, int depth = 0,
+               Visual* visual = nullptr, Colormap colormap = 0);
+    void setDND(bool enabled = true);
+
+    void handleClientMessage(const XClientMessageEvent& message) override;
+
+private:
+    void sendXdndStatus(bool acceptDrop = false, Atom dropAction = None);
+    void handleXdndEnter(const XClientMessageEvent& message);
+    void handleXdndLeave(const XClientMessageEvent& message);
+    void handleXdndPosition(const XClientMessageEvent& message);
+    void handleXdndStatus(const XClientMessageEvent& message);
+    void handleXdndDrop(const XClientMessageEvent& message);
+    void handleXdndFinished(const XClientMessageEvent& message);
+
+    Window XdndDragSource;
+    Window XdndDropTarget;
+
+    enum { XdndCurrentVersion = 5, };
+};
+
 class YDesktop: public YWindow {
 public:
     YDesktop(YWindow *aParent = nullptr, Window win = 0);
