From 3d73a90a7b50a50d1c95b72da871e071f4f07cfb Mon Sep 17 00:00:00 2001
From: fluxgen <fluxgen>
Date: Fri, 25 Apr 2003 12:32:57 +0000
Subject: optimized transparent

---
 src/FbTk/Menu.cc | 357 +++++++++++++++++++++++++++++++++++--------------------
 src/FbTk/Menu.hh |   5 +-
 2 files changed, 230 insertions(+), 132 deletions(-)

diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index fd6745b..caa731c 100644
--- a/src/FbTk/Menu.cc
+++ b/src/FbTk/Menu.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Menu.cc,v 1.13 2003/04/20 13:49:26 fluxgen Exp $
+// $Id: Menu.cc,v 1.14 2003/04/25 12:32:57 fluxgen Exp $
 
 //use GNU extensions
 #ifndef	 _GNU_SOURCE
@@ -46,6 +46,31 @@
 
 using namespace std;
 
+namespace {
+Pixmap getRootPixmap(int screen_num) {
+    Pixmap root_pm = 0;
+    // get root pixmap for transparency
+    Display *disp = FbTk::App::instance()->display();
+    Atom real_type;
+    int real_format;
+    unsigned long items_read, items_left;
+    unsigned int *data;
+    if (XGetWindowProperty(disp, RootWindow(disp, screen_num), 
+                           XInternAtom(disp, "_XROOTPMAP_ID", false),
+                           0L, 1L, 
+                           false, XA_PIXMAP, &real_type,
+                           &real_format, &items_read, &items_left, 
+                           (unsigned char **) &data) == Success && 
+        items_read) { 
+        root_pm = (Pixmap) (*data);                  
+        XFree(data);
+    }
+
+    return root_pm; 
+}
+
+}; // end anonymous namespace
+
 namespace FbTk {
 
 static Menu *shown = 0;
@@ -62,7 +87,8 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
     m_screen_height(DisplayHeight(m_display, screen_num)),
     m_alignment(ALIGNDONTCARE),
     m_border_width(0),
-    m_themeobserver(*this), m_trans(new Transparent(0, 0, 255, screen_num)) {
+    m_themeobserver(*this), m_trans(new Transparent(0, 0, 255, screen_num)),
+    m_need_update(true) {
 
     // make sure we get updated when the theme is reloaded
     tm.addListener(m_themeobserver);
@@ -106,24 +132,7 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
 
     menu.height = menu.title_h + 2 + menu.frame_h;
 
-    // get root pixmap for transparency
-    Display *disp = FbTk::App::instance()->display();
-    Atom real_type;
-    int real_format;
-    unsigned long items_read, items_left;
-    unsigned int *data;
-    if (XGetWindowProperty(disp, RootWindow(disp, screen_num), 
-                           XInternAtom(disp, "_XROOTPMAP_ID", false),
-                           0L, 1L, 
-                           false, XA_PIXMAP, &real_type,
-                           &real_format, &items_read, &items_left, 
-                           (unsigned char **) &data) == Success && 
-        items_read) { 
-        m_root_pm = (Pixmap) (*data);                  
-        XFree(data);
-    } else 
-        m_root_pm = 0;
-
+    m_root_pm = getRootPixmap(screen_num);
     m_trans->setSource(m_root_pm, screen_num);
     m_trans->setAlpha(s_alpha);
 
@@ -136,7 +145,7 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
 
     //create menu window
     menu.window = XCreateWindow(m_display, RootWindow(m_display, screen_num), 
-                                menu.x, menu.y, menu.width, menu.height,  // pos and size
+                                menu.x, menu.y, menu.width, menu.height,
                                 0, CopyFromParent,
                                 InputOutput, CopyFromParent, attrib_mask, &attrib);
 
@@ -213,6 +222,7 @@ int Menu::insert(MenuItem *item, int pos) {
     } else {
         menuitems.insert(menuitems.begin() + pos, item);
     }
+    m_need_update = true; // we need to redraw the menu
     return menuitems.size();
 }
 
@@ -248,7 +258,7 @@ int Menu::remove(unsigned int index) {
         which_sub = -1;
     else if (static_cast<unsigned int>(which_sub) > index)
         which_sub--;
-
+    m_need_update = true; // we need to redraw the menu
     return menuitems.size();
 }
 
@@ -257,6 +267,7 @@ void Menu::removeAll() {
         delete menuitems.back();
         menuitems.pop_back();
     }
+    m_need_update = true;
 }
 
 void Menu::raise() {
@@ -276,6 +287,7 @@ void Menu::enableTitle() {
 }
 
 void Menu::update() {
+
     if (menu.bevel_w > 10) // clamp to "normal" size
         menu.bevel_w = 10;
     if (m_border_width > 20)
@@ -357,11 +369,11 @@ void Menu::update() {
     const FbTk::Texture &frame_tex = m_theme.frameTexture();
     if (frame_tex.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
         menu.frame_pixmap = None;
-        menu.frame.setBackgroundColor(frame_tex.color());
+        //        menu.frame.setBackgroundColor(frame_tex.color());
     } else {
         menu.frame_pixmap =
             m_image_ctrl.renderImage(menu.width, menu.frame_h, frame_tex);
-        menu.frame.setBackgroundPixmap(menu.frame_pixmap);
+        //        menu.frame.setBackgroundPixmap(menu.frame_pixmap);
     }
 
     if (tmp)
@@ -398,22 +410,49 @@ void Menu::update() {
     menu.frame.moveResize(0, ((title_vis) ? menu.title.y() + menu.title.height() + 
                               menu.title.borderWidth()*2 : 0), 
                           menu.window.width(), menu.frame_h);
+
+    // render pixmaps
+    Display *disp = FbTk::App::instance()->display();
+
+    XWindowAttributes attr;
+
+    if (m_need_update && (m_frame_pm.width() != menu.frame.width() ||
+                          m_frame_pm.height() != menu.frame.height() )){
+        XGetWindowAttributes(disp, menu.frame.window(), &attr);
+        m_frame_pm = FbTk::FbPixmap(menu.frame.window(),
+                                    menu.frame.width(), menu.frame.height(),
+                                    attr.depth);
+
+        if (m_frame_pm.drawable() == 0)
+            cerr<<"Can't create pixmap!"<<endl;
+
+       
+    }
+
+    menu.frame.setBackgroundPixmap(m_frame_pm.drawable());
+
     clearWindow();
 
     if (title_vis && visible) 
         redrawTitle();
 
-    unsigned int i = 0;
-    for (i = 0; visible && i < menuitems.size(); i++) {
-        if (i == (unsigned int)which_sub) {
-            drawItem(i, true, false, false);
-            drawSubmenu(i);
-        } else
-            drawItem(i, false, false, false);
+    if (m_need_update) {
+        for (unsigned int i = 0; visible && i < menuitems.size(); i++) {
+            if (i == (unsigned int)which_sub) {
+                drawItem(i, true, false, false);
+                drawSubmenu(i);
+            } else
+                drawItem(i, false, false, false);
+        }
+
+        if (m_parent && visible)
+            m_parent->drawSubmenu(m_parent->which_sub);
     }
 
-    if (m_parent && visible)
-        m_parent->drawSubmenu(m_parent->which_sub);
+    menu.frame.clear();
+
+    if (m_trans.get() && m_trans->alpha() != s_alpha)
+        m_trans->setAlpha(s_alpha);
 
     m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
     m_trans->render(menu.window.x() + menu.frame.x() - menu.window.borderWidth(),
@@ -421,7 +460,8 @@ void Menu::update() {
                     0, 0,
                     menu.frame.width(), menu.frame.height());
 
-                      
+                    
+    m_need_update = false;
     menu.window.showSubwindows();
 }
 
@@ -438,11 +478,6 @@ void Menu::show() {
         shown = this;
     }
 
-    m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
-    m_trans->render(menu.window.x() + menu.frame.x(), 
-                    menu.window.y() + menu.frame.y(),
-                    0, 0,
-                    menu.frame.width(), menu.frame.height());
 }
 
 
@@ -484,12 +519,32 @@ void Menu::internal_hide() {
 
 
 void Menu::move(int x, int y) {
+    if (m_trans.get() && m_trans->alpha() != s_alpha)
+        m_trans->setAlpha(s_alpha);
+
+    if ((menu.x != x || menu.y != y) && m_trans->alpha() != 255) {
+
+        Pixmap root_pm = getRootPixmap(menu.window.screenNumber());
+
+        if (m_root_pm != root_pm) {
+            m_trans->setSource(root_pm, menu.window.screenNumber());
+            m_root_pm = root_pm;
+        }
+        menu.frame.clear();
+        m_trans->setDest(menu.frame.window(), menu.window.screenNumber());
+        m_trans->render(x, y,
+                        0, 0,
+                        menu.frame.width(), menu.frame.height());
+
+    }
+        
     menu.x = x;
     menu.y = y;
     menu.window.move(x, y);
 
     if (which_sub != -1)
         drawSubmenu(which_sub);
+
 }
 
 
@@ -518,13 +573,22 @@ void Menu::redrawTitle() {
                   m_theme.titleTextGC(), // graphic context
                   text, len,  // text string with lenght
                   dx, font.ascent() + menu.bevel_w);  // position
+    if (m_trans.get() && m_trans->alpha() != s_alpha)
+        m_trans->setAlpha(s_alpha);
 
-    m_trans->setDest(menu.title.window(), menu.title.screenNumber());
-    m_trans->render(menu.window.x() + menu.title.x() - menu.window.borderWidth(), 
-                    menu.window.y() + menu.title.y() - menu.window.borderWidth(), 
-                    menu.title.x(), menu.title.y(),                      
-                    menu.title.width(), menu.title.height());
+    if (m_trans->alpha() != 255) {
+        Pixmap root_pm = getRootPixmap(menu.window.screenNumber());
 
+        if (m_root_pm != root_pm) {
+            m_trans->setSource(root_pm, menu.title.screenNumber());
+            m_root_pm = root_pm;
+        }
+        m_trans->setDest(menu.title.window(), menu.title.screenNumber());
+        m_trans->render(menu.window.x() + menu.title.x() - menu.window.borderWidth(), 
+                        menu.window.y() + menu.title.y() - menu.window.borderWidth(), 
+                        menu.title.x(), menu.title.y(),                      
+                        menu.title.width(), menu.title.height());
+    }
 
 }
 
@@ -538,68 +602,70 @@ void Menu::drawSubmenu(unsigned int index) {
             itmp->submenu()->internal_hide();
     }
 
-    if (index < menuitems.size()) {
-        MenuItem *item = menuitems[index];
-        if (item->submenu() && visible && (! item->submenu()->isTorn()) &&
-            item->isEnabled()) {
+    if (index >= menuitems.size())
+        return;
+
+    MenuItem *item = menuitems[index];
+    if (item->submenu() && visible && (! item->submenu()->isTorn()) &&
+        item->isEnabled()) {
 			
-            if (item->submenu()->m_parent != this)
-                item->submenu()->m_parent = this;
+        if (item->submenu()->m_parent != this)
+            item->submenu()->m_parent = this;
 			
-            int sbl = index / menu.persub, i = index - (sbl * menu.persub),
-                x = menu.x +
-                ((menu.item_w * (sbl + 1)) + menu.window.borderWidth()), y;
+        int sbl = index / menu.persub, i = index - (sbl * menu.persub),
+            x = menu.x +
+            ((menu.item_w * (sbl + 1)) + menu.window.borderWidth()), y;
 		
-            if (m_alignment == ALIGNTOP) {
-                y = (((shifted) ? menu.y_shift : menu.y) +
-                     ((title_vis) ? menu.title_h + menu.title.borderWidth() : 0) -
-                     ((item->submenu()->title_vis) ?
-                      item->submenu()->menu.title_h + menu.window.borderWidth() : 0));
-            } else {
-                y = (((shifted) ? menu.y_shift : menu.y) +
-                     (menu.item_h * i) +
-                     ((title_vis) ? menu.title_h + menu.window.borderWidth() : 0) -
-                     ((item->submenu()->title_vis) ?
-                      item->submenu()->menu.title_h + menu.window.borderWidth() : 0));
-            }
+        if (m_alignment == ALIGNTOP) {
+            y = (((shifted) ? menu.y_shift : menu.y) +
+                 ((title_vis) ? menu.title_h + menu.title.borderWidth() : 0) -
+                 ((item->submenu()->title_vis) ?
+                  item->submenu()->menu.title_h + menu.window.borderWidth() : 0));
+        } else {
+            y = (((shifted) ? menu.y_shift : menu.y) +
+                 (menu.item_h * i) +
+                 ((title_vis) ? menu.title_h + menu.window.borderWidth() : 0) -
+                 ((item->submenu()->title_vis) ?
+                  item->submenu()->menu.title_h + menu.window.borderWidth() : 0));
+        }
 			
-            if (m_alignment == ALIGNBOTTOM &&
-                (y + item->submenu()->menu.height) > ((shifted) ? menu.y_shift :
-                                                      menu.y) + menu.height) {
-                y = (((shifted) ? menu.y_shift : menu.y) +
-                     menu.height - item->submenu()->menu.height);
-            }
+        if (m_alignment == ALIGNBOTTOM &&
+            (y + item->submenu()->menu.height) > ((shifted) ? menu.y_shift :
+                                                  menu.y) + menu.height) {
+            y = (((shifted) ? menu.y_shift : menu.y) +
+                 menu.height - item->submenu()->menu.height);
+        }
 
-            if ((x + item->submenu()->width()) > m_screen_width) {
-                x = ((shifted) ? menu.x_shift : menu.x) -
-                    item->submenu()->width() - menu.window.borderWidth();
-            }
+        if ((x + item->submenu()->width()) > m_screen_width) {
+            x = ((shifted) ? menu.x_shift : menu.x) -
+                item->submenu()->width() - menu.window.borderWidth();
+        }
 			
-            if (x < 0)
-                x = 0;
+        if (x < 0)
+            x = 0;
 
-            if ((y + item->submenu()->height()) > m_screen_height) {
-                y = m_screen_height - item->submenu()->height() -
-                    menu.window.borderWidth() * 2;
-            }
+        if ((y + item->submenu()->height()) > m_screen_height) {
+            y = m_screen_height - item->submenu()->height() -
+                menu.window.borderWidth() * 2;
+        }
 			
-            if (y < 0)
-                y = 0;
+        if (y < 0)
+            y = 0;
 
-            item->submenu()->move(x, y);
-            if (! moving)
-                drawItem(index, true);
+        item->submenu()->move(x, y);
+        if (! moving)
+            drawItem(index, true);
 		
-            if (! item->submenu()->isVisible()) {
-                item->submenu()->show();
-                item->submenu()->raise();
-            }
+        if (! item->submenu()->isVisible()) {
+            item->submenu()->show();
+            item->submenu()->raise();
+        }
 			
-            item->submenu()->moving = moving;
-            which_sub = index;
-        } else
-            which_sub = -1;
-    }
+        item->submenu()->moving = moving;
+        which_sub = index;
+    } else
+        which_sub = -1;
+
 }
 
 
@@ -659,7 +725,7 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
          m_theme.frameTextGC());
     GC tgc =
         (highlight ? m_theme.hiliteTextGC() :
-         /*else*/ (item->isEnabled() ? m_theme.frameTextGC() : m_theme.disableTextGC() ) );
+         (item->isEnabled() ? m_theme.frameTextGC() : m_theme.disableTextGC() ) );
 	
     sel_x = item_x;
 	
@@ -670,8 +736,19 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
     sel_y = item_y + quarter_w;
 
     if (clear) {
-        XClearArea(m_display, menu.frame.window(), item_x, item_y, menu.item_w, menu.item_h,
-                   False);
+
+        GC def_gc = DefaultGC(m_display, menu.frame.screenNumber());
+        if (menu.frame_pixmap == 0) {
+            XSetForeground(m_display, def_gc, m_theme.frameTexture().color().pixel());
+            m_frame_pm.fillRectangle(def_gc, item_x, item_y, menu.item_w, menu.item_h);
+        } else {
+
+            m_frame_pm.copyArea(menu.frame_pixmap, def_gc,
+                                item_x, item_y,
+                                menu.item_w, menu.item_h, 
+                                item_x, item_y);
+        }    
+
     } else if (! (x == y && y == -1 && w == h && h == 0)) {
         // calculate the which part of the hilite to redraw
         if (! (std::max(item_x, x) <= (signed) std::min(item_x + menu.item_w, x + w) &&
@@ -690,44 +767,44 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
         int text_ry = item_y + (menu.bevel_w / 2);
         if (! (std::max(text_x, x) <= (signed) std::min(text_x + text_w, x + w) &&
                std::max(text_ry, y) <= (signed) std::min(text_ry + text_h, y + h)))
-            dotext = False;
+            dotext = false;
 		
         // check if we need to redraw the select pixmap/menu bullet
         if (! (std::max(sel_x, x) <= (signed) std::min(sel_x + half_w, x + w) &&
                std::max(sel_y, y) <= (signed) std::min(sel_y + half_w, y + h)))
-            dosel = False;
+            dosel = false;
 	
     }
 	
     if (dohilite && highlight && (menu.hilite_pixmap != ParentRelative)) {
         if (menu.hilite_pixmap) {
-            XCopyArea(m_display, menu.hilite_pixmap, menu.frame.window(),
-                      m_theme.hiliteGC(), hoff_x, hoff_y,
-                      hilite_w, hilite_h, hilite_x, hilite_y);
-        } else {
-            XFillRectangle(m_display, menu.frame.window(),
-                           m_theme.hiliteGC(),
-                           hilite_x, hilite_y, hilite_w, hilite_h);
+            m_frame_pm.copyArea(menu.hilite_pixmap,
+                                m_theme.hiliteGC(), hoff_x, hoff_y,
+                                hilite_w, hilite_h, hilite_x, hilite_y);
+        } else {            
+            m_frame_pm.fillRectangle(m_theme.hiliteGC(),
+                                     hilite_x, hilite_y, hilite_w, hilite_h);
         }
+        
     } 
 	
     if (dosel && item->isSelected() &&
         (menu.sel_pixmap != ParentRelative)) {
         if (menu.sel_pixmap) {
-            XCopyArea(m_display, 
-                      highlight ? menu.frame_pixmap : menu.sel_pixmap, menu.frame.window(),
-                      m_theme.hiliteGC(), 0, 0,
-                      half_w, half_w, sel_x, sel_y);
+            m_frame_pm.copyArea(highlight ? menu.frame_pixmap : menu.sel_pixmap,
+                                m_theme.hiliteGC(), 
+                                0, 0,
+                                half_w, half_w, 
+                                sel_x, sel_y);
         } else {
-            XFillRectangle(m_display, menu.frame.window(),
-                           m_theme.hiliteGC(),
-                           sel_x, sel_y, half_w, half_w);
+            m_frame_pm.fillRectangle(m_theme.hiliteGC(),
+                                     sel_x, sel_y, half_w, half_w);
         }
+        
     }
 	
     if (dotext && text) {
-        m_theme.frameFont().drawText(
-                                     menu.frame.window(), // drawable
+        m_theme.frameFont().drawText(m_frame_pm.drawable(), // drawable
                                      screenNumber(),
                                      tgc,
                                      text, len, // text string and lenght
@@ -737,7 +814,7 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
     if (dosel && item->submenu()) {
         switch (m_theme.bullet()) {
         case MenuTheme::SQUARE:
-            XDrawRectangle(m_display, menu.frame.window(), gc, sel_x, sel_y, half_w, half_w);
+            m_frame_pm.drawRectangle(gc, sel_x, sel_y, half_w, half_w);
             break;
 
         case MenuTheme::TRIANGLE:
@@ -759,8 +836,8 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
                 tri[2].y = -4;
             }
 			
-            XFillPolygon(m_display, menu.frame.window(), gc, tri, 3, Convex,
-                         CoordModePrevious);
+            m_frame_pm.fillPolygon(gc, tri, 3, Convex,
+                                   CoordModePrevious);
             break;
 			
         case MenuTheme::DIAMOND:
@@ -775,25 +852,40 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_
             dia[3].x = -3;
             dia[3].y = 3;
 
-            XFillPolygon(m_display, menu.frame.window(), gc, dia, 4, Convex,
-                         CoordModePrevious);
+            m_frame_pm.fillPolygon(gc, dia, 4, Convex,
+                                   CoordModePrevious);
             break;
         default:
             break;
         }
     }
 
-    if (render_trans) {
-        m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
+    XClearArea(m_display, menu.frame.window(),
+               item_x, item_y,
+               menu.item_w, menu.item_h, False);
+
+    if (m_trans.get() && m_trans->alpha() != s_alpha)
+        m_trans->setAlpha(s_alpha);
+
+    if (m_trans->alpha() != 255) {                               
+        Pixmap root_pm = getRootPixmap(menu.window.screenNumber());
+
+        if (m_root_pm != root_pm) {
+            m_trans->setSource(root_pm, menu.window.screenNumber());
+            m_root_pm = root_pm;
+        }
+        
+        m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());        
         m_trans->render(menu.window.x() + menu.frame.x() + item_x - 
                         menu.window.borderWidth(), 
-                         menu.window.y() + menu.frame.y() + item_y - 
+                        menu.window.y() + menu.frame.y() + item_y - 
                         menu.window.borderWidth(),
-
-                         item_x, item_y,
-                         menu.item_w, menu.item_h);
-                        
+                        item_x, item_y,
+                        menu.item_w, menu.item_h);
     }
+
+    XSync(m_display, False);
+    
 }
 
 
@@ -1085,20 +1177,23 @@ void Menu::leaveNotifyEvent(XCrossingEvent &ce) {
 
 
 void Menu::reconfigure() {
+    m_need_update = true; // redraw items
+
     menu.bevel_w = m_theme.bevelWidth();
     m_border_width = m_theme.borderWidth();
+
     if (menu.bevel_w > 10) // clamp to "normal" size
         menu.bevel_w = 10;
     if (menu.bevel_w < 0)
         menu.bevel_w = 1;
+
     if (m_border_width > 20) // clamp to normal size
         m_border_width = 20;
     if (m_border_width < 0)
         m_border_width = 0;
 
     menu.window.setBackgroundColor(m_theme.borderColor());
-    menu.title.setBackgroundColor(m_theme.borderColor());
-    menu.frame.setBackgroundColor(m_theme.borderColor());
+    menu.title.setBackgroundColor(m_theme.borderColor());    
 
     menu.window.setBorderColor(m_theme.borderColor());
     menu.title.setBorderColor(m_theme.borderColor());
@@ -1107,7 +1202,7 @@ void Menu::reconfigure() {
     menu.window.setBorderWidth(m_border_width);
     menu.title.setBorderWidth(m_border_width);
 
-    if (m_trans.get())
+    if (m_trans.get() && m_trans->alpha() != s_alpha)
         m_trans->setAlpha(s_alpha);
 
     update();
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index 2408e28..6be2570 100644
--- a/src/FbTk/Menu.hh
+++ b/src/FbTk/Menu.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Menu.hh,v 1.12 2003/04/20 14:20:14 fluxgen Exp $
+// $Id: Menu.hh,v 1.13 2003/04/25 12:32:11 fluxgen Exp $
 
 #ifndef	 FBTK_MENU_HH
 #define	 FBTK_MENU_HH
@@ -38,6 +38,7 @@
 #include "Command.hh"
 #include "Observer.hh"
 #include "XLayerItem.hh"
+#include "FbPixmap.hh"
 
 namespace FbTk {
 
@@ -203,6 +204,8 @@ private:
     std::auto_ptr<Transparent> m_trans;
     Drawable m_root_pm;
     static unsigned char s_alpha;
+    FbPixmap m_frame_pm;
+    bool m_need_update;
 };
 
 }; // end namespace FbTk
-- 
cgit v0.11.2