From 1cc7b60aa2c2e7a26f9ff6f1461ca0b8a97be8de Mon Sep 17 00:00:00 2001 From: simonb Date: Sun, 7 Jan 2007 11:55:14 +0000 Subject: per-window transparency, including apps and menu support, plus some infrastructure and related changes. Thanks for original patch from Julien Trolet, dmxen at sourceforge dot net --- ChangeLog | 14 +++++++ nls/fluxbox-nls.hh | 2 + src/BoolMenuItem.hh | 29 ++++++++++++++- src/FbTk/Menu.hh | 2 +- src/FbTk/MenuItem.hh | 16 ++++---- src/FbTk/Resource.hh | 1 + src/FbWinFrame.cc | 68 +++++++++++++++++++++++++++------ src/FbWinFrame.hh | 11 ++++++ src/IntResMenuItem.hh | 59 +++++++++++++++++++++++++++-- src/Makefile.am | 3 +- src/MenuCreator.cc | 101 ++++++++++++++++++++++++++++++++++++++++---------- src/Remember.cc | 50 +++++++++++++++++++++++++ src/Remember.hh | 8 ++++ src/Screen.cc | 8 ++-- src/Slit.cc | 2 +- src/Toolbar.cc | 4 +- src/Window.cc | 8 ++++ src/Window.hh | 17 +++++++++ 18 files changed, 351 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6f72ef..ff1e160 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ (Format: Year/Month/Day) Changes for 1.0rc3: +*07/01/07: + * Support per-window transparency settings. + - new "Transparency" menu in the window menu + - new apps file attribute: + [alpha] {int int} (or just {int}) + Where numbers represent focused and unfocused transparency, + respectively. One number only will be used for both. + - Also, show toggle status for shade and stick in window menu. + (Simon and thanks Julien Trolet, dmxen at sourceforge dot net) + sf.net patch #1511042, feature #1108692 + fluxbox-nls.hh AlphaMenu.hh/cc BoolMenuItem.hh FbTk/Menu.hh + FbTk/MenuItem.hh FbTk/Resource.hh FbWinFrame.hh/cc IntResMenuItem.hh/cc + MenuCreator.cc ObjectResource.hh Remember.hh/cc Screen.cc Slit.cc + Window.hh/cc Toolbar.cc Makefile.am *07/01/06: * Updated nb_NO translations (thanks emptydoor at users dot sf dot net) nls/nb_NO/Translation.m diff --git a/nls/fluxbox-nls.hh b/nls/fluxbox-nls.hh index 845216f..53d06aa 100644 --- a/nls/fluxbox-nls.hh +++ b/nls/fluxbox-nls.hh @@ -148,6 +148,7 @@ enum { RememberUnknown = 10, RememberWorkspace = 11, RememberHead = 12, + RememberAlpha = 13, ScreenSet = 12, ScreenAnotherWMRunning = 1, @@ -200,6 +201,7 @@ enum { WindowmenuShade = 8, WindowmenuStick = 9, WindowmenuKill = 10, + WindowmenuDefaultAlpha = 11, WorkspaceSet = 17, WorkspaceDefaultNameFormat = 1, diff --git a/src/BoolMenuItem.hh b/src/BoolMenuItem.hh index 914185d..29eef15 100644 --- a/src/BoolMenuItem.hh +++ b/src/BoolMenuItem.hh @@ -38,6 +38,7 @@ public: BoolMenuItem(const FbTk::FbString &label, bool &item): FbTk::MenuItem(label), m_item(item) { FbTk::MenuItem::setSelected(m_item); + setToggleItem(true); } bool isSelected() const { return m_item; } // toggle state @@ -50,4 +51,30 @@ private: bool &m_item; }; -#endif // BOOLRESMENUITEM_HH +/// a bool menu item +template +class BoolResMenuItem: public FbTk::MenuItem { +public: + BoolResMenuItem(const FbTk::FbString &label, Type &res, + FbTk::RefCount &cmd): + FbTk::MenuItem(label, cmd), m_res(res) { + FbTk::MenuItem::setSelected(*m_res); + setToggleItem(true); + } + BoolResMenuItem(const FbTk::FbString &label, Type &res): + FbTk::MenuItem(label), m_res(res) { + FbTk::MenuItem::setSelected(*m_res); + setToggleItem(true); + } + bool isSelected() const { return *m_res; } + // toggle state + void click(int button, int time) { setSelected(!*m_res); FbTk::MenuItem::click(button, time); } + void setSelected(bool value) { + m_res = value; + FbTk::MenuItem::setSelected(*m_res); + } +private: + Type &m_res; +}; + +#endif // BOOLMENUITEM_HH diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh index 7863fcb..28eb70a 100644 --- a/src/FbTk/Menu.hh +++ b/src/FbTk/Menu.hh @@ -116,7 +116,7 @@ public: /// set label string void setLabel(const FbString &labelstr); /// move menu to x,y - void move(int x, int y); + virtual void move(int x, int y); virtual void updateMenu(int active_index = -1); void setItemSelected(unsigned int index, bool val); void setItemEnabled(unsigned int index, bool val); diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh index 94f0775..d73c270 100644 --- a/src/FbTk/MenuItem.hh +++ b/src/FbTk/MenuItem.hh @@ -90,21 +90,21 @@ public: virtual ~MenuItem() { } inline void setCommand(RefCount &cmd) { m_command = cmd; } - virtual inline void setSelected(bool selected) { m_selected = selected; } - virtual inline void setEnabled(bool enabled) { m_enabled = enabled; } - virtual inline void setLabel(const FbString &label) { m_label = label; } - virtual inline void setToggleItem(bool val) { m_toggle_item = val; } + virtual void setSelected(bool selected) { m_selected = selected; } + virtual void setEnabled(bool enabled) { m_enabled = enabled; } + virtual void setLabel(const FbString &label) { m_label = label; } + virtual void setToggleItem(bool val) { m_toggle_item = val; } void setIcon(const std::string &filename, int screen_num); virtual Menu *submenu() { return m_submenu; } /** @name accessors */ //@{ - virtual inline const std::string &label() const { return m_label; } + virtual const std::string &label() const { return m_label; } virtual const Menu *submenu() const { return m_submenu; } - virtual inline bool isEnabled() const { return m_enabled; } - virtual inline bool isSelected() const { return m_selected; } - virtual inline bool isToggleItem() const { return m_toggle_item; } + virtual bool isEnabled() const { return m_enabled; } + virtual bool isSelected() const { return m_selected; } + virtual bool isToggleItem() const { return m_toggle_item; } virtual unsigned int width(const MenuTheme &theme) const; virtual unsigned int height(const MenuTheme &theme) const; virtual void draw(FbDrawable &drawable, diff --git a/src/FbTk/Resource.hh b/src/FbTk/Resource.hh index bdce09d..55eeddc 100644 --- a/src/FbTk/Resource.hh +++ b/src/FbTk/Resource.hh @@ -192,6 +192,7 @@ public: /// @return string value of resource std::string getString() const; + inline T& get() { return m_value; } inline T& operator*() { return m_value; } inline const T& operator*() const { return m_value; } inline T *operator->() { return &m_value; } diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index e41d1df..5d191d0 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc @@ -83,6 +83,7 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr m_use_handle(true), m_focused(false), m_visible(false), + m_use_default_alpha(2), m_button_pm(0), m_tabmode(screen.getDefaultInternalTabs()?INTERNAL:EXTERNAL), m_active_gravity(0), @@ -91,6 +92,9 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr m_button_size(1), m_width_before_shade(1), m_height_before_shade(1), + m_shaded(false), + m_focused_alpha(0), + m_unfocused_alpha(0), m_double_click_time(0), m_themelistener(*this), m_shape(new Shape(m_window, theme.shapePlace())), @@ -443,7 +447,7 @@ void FbWinFrame::alignTabs() { void FbWinFrame::notifyMoved(bool clear) { // not important if no alpha... - unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + unsigned char alpha = getAlpha(m_focused); if (alpha == 255) return; @@ -505,8 +509,8 @@ void FbWinFrame::setFocus(bool newvalue) { m_focused = newvalue; - if (FbTk::Transparent::haveRender() && theme().focusedAlpha() != theme().unfocusedAlpha()) { - unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + if (FbTk::Transparent::haveRender() && getAlpha(true) != getAlpha(false)) { // different alpha for focused and unfocused + unsigned char alpha = getAlpha(m_focused); if (FbTk::Transparent::haveComposite()) { m_tab_container.setAlpha(255); m_window.setOpaque(alpha); @@ -527,6 +531,46 @@ void FbWinFrame::setFocus(bool newvalue) { clearAll(); } +void FbWinFrame::setAlpha(bool focused, unsigned char alpha) { + if (m_use_default_alpha == 2) + { + /// Set basic defaults + m_focused_alpha = getAlpha(true); + m_unfocused_alpha = getAlpha(false); + } + m_use_default_alpha = 0; + + if (focused) + m_focused_alpha = alpha; + else + m_unfocused_alpha = alpha; + + if(m_focused == focused) + m_window.setOpaque(alpha); +} + +unsigned char FbWinFrame::getAlpha(bool focused) const +{ + return getUseDefaultAlpha() ? + (focused ? theme().focusedAlpha() : theme().unfocusedAlpha()) + : (focused ? m_focused_alpha : m_unfocused_alpha); +} + +void FbWinFrame::setUseDefaultAlpha(bool default_alpha) +{ + if (getUseDefaultAlpha() == default_alpha) + return; + + if (!default_alpha && m_use_default_alpha == 2) { + m_focused_alpha = theme().focusedAlpha(); + m_unfocused_alpha = theme().unfocusedAlpha(); + } + + m_use_default_alpha = default_alpha; + + m_window.setOpaque(getAlpha(m_focused)); +} + void FbWinFrame::setDoubleClickTime(unsigned int time) { m_double_click_time = time; } @@ -1056,7 +1100,7 @@ void FbWinFrame::reconfigure() { // update transparency settings if (FbTk::Transparent::haveRender()) { unsigned char alpha = - (m_focused ? theme().focusedAlpha() : theme().unfocusedAlpha()); + getAlpha(m_focused); if (FbTk::Transparent::haveComposite()) { m_tab_container.setAlpha(255); m_window.setOpaque(alpha); @@ -1281,7 +1325,7 @@ void FbWinFrame::applyTitlebar() { getCurrentFocusPixmap(label_pm, title_pm, label_color, title_color); - unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + unsigned char alpha = getAlpha (m_focused); m_titlebar.setAlpha(alpha); m_label.setAlpha(alpha); @@ -1332,7 +1376,7 @@ void FbWinFrame::renderHandles() { void FbWinFrame::applyHandles() { - unsigned char alpha = (m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + unsigned char alpha = getAlpha (m_focused); m_handle.setAlpha(alpha); m_grip_left.setAlpha(alpha); m_grip_right.setAlpha(alpha); @@ -1452,7 +1496,7 @@ void FbWinFrame::applyButton(FbTk::Button &btn) { btn.setPressedColor(m_button_pressed_color); if (focused()) { // focused - btn.setAlpha(theme().focusedAlpha()); + btn.setAlpha(getAlpha(true)); btn.setGC(m_theme.buttonPicFocusGC()); if (m_button_pm) @@ -1460,7 +1504,7 @@ void FbWinFrame::applyButton(FbTk::Button &btn) { else btn.setBackgroundColor(m_button_color); } else { // unfocused - btn.setAlpha(theme().unfocusedAlpha()); + btn.setAlpha(getAlpha(false)); btn.setGC(m_theme.buttonPicUnfocusGC()); if (m_button_unfocused_pm) @@ -1513,7 +1557,7 @@ void FbWinFrame::getCurrentFocusPixmap(Pixmap &label_pm, Pixmap &title_pm, } void FbWinFrame::applyTabContainer() { - m_tab_container.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + m_tab_container.setAlpha(getAlpha(m_focused)); // do the parent container Pixmap tabcontainer_pm = None; @@ -1608,7 +1652,7 @@ void FbWinFrame::applyFocusLabel(FbTk::TextButton &button) { button.setGC(theme().labelTextFocusGC()); button.setJustify(theme().justify()); - button.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + button.setAlpha(getAlpha(m_focused)); if (m_labelbutton_focused_pm != 0) { button.setBackgroundPixmap(m_labelbutton_focused_pm); @@ -1621,7 +1665,7 @@ void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) { button.setGC(theme().labelTextActiveGC()); button.setJustify(theme().justify()); - button.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + button.setAlpha(getAlpha(m_focused)); if (m_labelbutton_active_pm != 0) { button.setBackgroundPixmap(m_labelbutton_active_pm); @@ -1634,7 +1678,7 @@ void FbWinFrame::applyUnfocusLabel(FbTk::TextButton &button) { button.setGC(theme().labelTextUnfocusGC()); button.setJustify(theme().justify()); - button.setAlpha(m_focused?theme().focusedAlpha():theme().unfocusedAlpha()); + button.setAlpha(getAlpha(m_focused)); if (m_labelbutton_unfocused_pm != 0) { button.setBackgroundPixmap(m_labelbutton_unfocused_pm); diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index 26076ed..182add4 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh @@ -127,6 +127,13 @@ public: bool setTabMode(TabMode tabmode); inline void updateTabProperties() { alignTabs(); } + /// Alpha settings + void setAlpha(bool focused, unsigned char value); + unsigned char getAlpha(bool focused) const; + + void setUseDefaultAlpha(bool use_default); + bool getUseDefaultAlpha() const { return m_use_default_alpha; } + /// add a button to the left of the label void addLeftButton(FbTk::Button *btn); /// add a button to the right of the label @@ -322,6 +329,8 @@ private: bool m_use_handle; ///< if we should use handle bool m_focused; ///< focused/unfocused mode bool m_visible; ///< if we are currently showing + unsigned char m_use_default_alpha; + ///< do we use screen or window alpha settings ? (0 = window, 1 = default, 2 = default and window never set) /** @name pixmaps and colors for rendering @@ -377,6 +386,8 @@ private: unsigned int m_width_before_shade, ///< width before shade, so we can restore it when we unshade m_height_before_shade; ///< height before shade, so we can restore it when we unshade bool m_shaded; ///< wheter we're shaded or not + unsigned char m_focused_alpha; ///< focused alpha value + unsigned char m_unfocused_alpha; ///< unfocused alpha value unsigned int m_double_click_time; ///< the time period that's considerd to be a double click struct MouseButtonAction { FbTk::RefCount click; ///< what to do when we release mouse button diff --git a/src/IntResMenuItem.hh b/src/IntResMenuItem.hh index a0e102d..0be2775 100644 --- a/src/IntResMenuItem.hh +++ b/src/IntResMenuItem.hh @@ -27,18 +27,71 @@ #include "MenuItem.hh" #include "Resource.hh" +#include + /// Changes an resource integer value between min and max +template class IntResMenuItem: public FbTk::MenuItem { public: - IntResMenuItem(const FbTk::FbString &label, FbTk::Resource &res, int min_val, int max_val, FbTk::Menu &host_menu); + IntResMenuItem(const FbTk::FbString &label, Type &res, int min_val, int max_val, FbTk::Menu &host_menu) : + FbTk::MenuItem(label, host_menu), m_org_label(FbTk::MenuItem::label()), + m_max(max_val), m_min(min_val), m_res(res) { + updateLabel(); + } + + /* Utility, but doesn't get found in anonymous namespace? */ + std::string appendIntValue(const std::string &label, int value) { + char *buff = new char[label.size() + 16]; + sprintf(buff, "%s: %d", label.c_str(), value); + std::string ret(buff); + delete [] buff; + return ret; + } + + void click(int button, int time) { + static int last_time = -201; + int inc_val = 1; + // check double click + //!! TODO: must have some sort of "global" double click time in FbTk + if (time - last_time <= 200) + inc_val = 5; + - void click(int button, int time); + last_time = time; + + if ((button == 4 || button == 3)&& *m_res < m_max) // scroll up + m_res.get() += inc_val; + else if ((button == 5 || button == 1) && *m_res > m_min) // scroll down + m_res.get() -= inc_val; + + // clamp value + if (*m_res > m_max) + m_res.get() = m_max; + else if (*m_res < m_min) + m_res.get() = m_min; + + // update label + updateLabel(); + // call other commands + FbTk::MenuItem::click(button, time); + + // show new value, which for us means forcing a full menu update + // since the text is drawn onto the background! + if (menu()) { + menu()->frameWindow().updateBackground(false); + menu()->clearWindow(); + } + } + void updateLabel() { + setLabel(appendIntValue(m_org_label, *m_res)); + } + private: std::string m_org_label; ///< original label const int m_max; ///< maximum value the integer can have const int m_min; ///< minimum value the integer can have - FbTk::Resource &m_res; ///< resource item to be changed + Type &m_res; ///< resource item to be changed }; #endif // INTRESMENUITEM_HH diff --git a/src/Makefile.am b/src/Makefile.am index b86e2c9..5b74800 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,7 +100,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ Workspace.cc Workspace.hh \ FbCommands.hh FbCommands.cc LayerMenu.hh LayerMenu.cc \ Layer.hh \ - IntResMenuItem.hh IntResMenuItem.cc FbMenu.hh FbMenu.cc \ + IntResMenuItem.hh FbMenu.hh FbMenu.cc \ WinClient.hh WinClient.cc \ Strut.hh \ Xinerama.hh \ @@ -116,6 +116,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ TextTheme.hh TextTheme.cc \ BorderTheme.hh BorderTheme.cc \ CommandDialog.hh CommandDialog.cc SendToMenu.hh SendToMenu.cc \ + AlphaMenu.hh AlphaMenu.cc ObjectResource.hh \ CompareWindow.hh \ Parser.hh Parser.cc FbMenuParser.hh FbMenuParser.cc \ StyleMenuItem.hh StyleMenuItem.cc \ diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc index 31ef06d..5264a4d 100644 --- a/src/MenuCreator.cc +++ b/src/MenuCreator.cc @@ -35,7 +35,9 @@ #include "WorkspaceMenu.hh" #include "LayerMenu.hh" #include "SendToMenu.hh" +#include "AlphaMenu.hh" #include "Layer.hh" +#include "BoolMenuItem.hh" #include "FbMenuParser.hh" #include "StyleMenuItem.hh" @@ -50,6 +52,7 @@ #include "FbTk/FileUtil.hh" #include "FbTk/MenuSeparator.hh" #include "FbTk/MenuIcon.hh" +#include "FbTk/Transparent.hh" #include @@ -155,7 +158,7 @@ private: FbTk::Menu *m_menu; }; -class MenuContext: public LayerObject { +class MenuContext: public LayerObject, public AlphaObject { public: void moveToLayer(int layer_number) { if (WindowCmd::window() == 0) @@ -167,6 +170,43 @@ public: return -1; return WindowCmd::window()->layerItem().getLayerNum(); } + + int getFocusedAlpha() const { + if (WindowCmd::window() == 0) + return 255; + return WindowCmd::window()->getFocusedAlpha(); + } + + int getUnfocusedAlpha() const { + if (WindowCmd::window() == 0) + return 255; + return WindowCmd::window()->getUnfocusedAlpha(); + } + + bool getUseDefaultAlpha() const { + if (WindowCmd::window() == 0) + return true; + return WindowCmd::window()->getUseDefaultAlpha(); + } + + void setFocusedAlpha(int alpha) { + if (WindowCmd::window() == 0) + return; + WindowCmd::window()->setFocusedAlpha(alpha); + } + + void setUnfocusedAlpha(int alpha) { + if (WindowCmd::window() == 0) + return; + WindowCmd::window()->setUnfocusedAlpha(alpha); + } + + void setUseDefaultAlpha(bool use_default) { + if (WindowCmd::window() == 0) + return; + WindowCmd::window()->setUseDefaultAlpha(use_default); + } + }; static void translateMenuItem(Parser &parse, ParseItem &item, FbTk::StringConvertor &labelconvertor); @@ -489,6 +529,7 @@ FbTk::Menu *MenuCreator::createMenuType(const string &type, int screen_num) { "lower", "sendto", "layer", + "alpha", "extramenus", "separator", "close", @@ -510,9 +551,14 @@ bool MenuCreator::createWindowMenuItem(const string &type, typedef FbTk::RefCount RefCmd; _FB_USES_NLS; + static MenuContext context; + if (type == "shade") { - RefCmd shade_cmd(new WindowCmd(&FluxboxWindow::shade)); - menu.insert(label.empty()?_FB_XTEXT(Windowmenu, Shade, "Shade", "Shade the window"):label, shade_cmd); + static ObjectResource res(&WindowCmd::window, &FluxboxWindow::isShaded, &FluxboxWindow::shade, false); + menu.insert(new BoolResMenuItem >( + label.empty()?_FB_XTEXT(Windowmenu, Shade, "Shade", "Shade the window"):label, + res)); + } else if (type == "maximize") { RefCmd maximize_cmd(new WindowCmd(&FluxboxWindow::maximizeFull)); RefCmd maximize_vert_cmd(new WindowCmd(&FluxboxWindow::maximizeVertical)); @@ -532,41 +578,60 @@ bool MenuCreator::createWindowMenuItem(const string &type, maximize_item->setCommand(3, maximize_horiz_cmd); menu.insert(maximize_item); } else if (type == "iconify") { - RefCmd iconify_cmd(new WindowCmd(&FluxboxWindow::iconify)); - menu.insert(label.empty() ? - _FB_XTEXT(Windowmenu, Iconify, - "Iconify", "Iconify the window") : - label, iconify_cmd); + static ObjectResource res(&WindowCmd::window, &FluxboxWindow::isIconic, &FluxboxWindow::toggleIconic, false); + menu.insert(new BoolResMenuItem >( + label.empty() ? + _FB_XTEXT(Windowmenu, Iconify, + "Iconify", "Iconify the window") : + label, res)); } else if (type == "close") { RefCmd close_cmd(new WindowCmd(&FluxboxWindow::close)); menu.insert(label.empty() ? _FB_XTEXT(Windowmenu, Close, - "Close", "Close the window") : + "Close", "Close the window") : label, close_cmd); } else if (type == "kill" || type == "killwindow") { RefCmd kill_cmd(new WindowCmd(&FluxboxWindow::kill)); menu.insert(label.empty() ? _FB_XTEXT(Windowmenu, Kill, - "Kill", "Kill the window"): + "Kill", "Kill the window"): label, kill_cmd); } else if (type == "lower") { RefCmd lower_cmd(new WindowCmd(&FluxboxWindow::lower)); menu.insert( label.empty() ? _FB_XTEXT(Windowmenu, Lower, - "Lower", "Lower the window"): + "Lower", "Lower the window"): label, lower_cmd); } else if (type == "raise") { RefCmd raise_cmd(new WindowCmd(&FluxboxWindow::raise)); menu.insert(label.empty() ? _FB_XTEXT(Windowmenu, Raise, - "Raise", "Raise the window"): + "Raise", "Raise the window"): label, raise_cmd); + } else if (type == "stick") { - RefCmd stick_cmd(new WindowCmd(&FluxboxWindow::stick)); - menu.insert(label.empty() ? - _FB_XTEXT(Windowmenu, Stick, - "Stick", "Stick the window"): - label, stick_cmd); + static ObjectResource res(&WindowCmd::window, &FluxboxWindow::isStuck, &FluxboxWindow::stick, false); + menu.insert(new BoolResMenuItem >( + label.empty() ? + _FB_XTEXT(Windowmenu, Stick, + "Stick", "Stick the window"): + label, res)); +#ifdef HAVE_XRENDER + } else if (type == "alpha") { + if (FbTk::Transparent::haveComposite() || + FbTk::Transparent::haveRender()) { + BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); + if (screen == 0) + return false; + + menu.insert(label.empty() ? _FB_XTEXT(Configmenu, Transparency, "Transparency", + "Menu containing various transparency options"): label, + new AlphaMenu(screen->menuTheme(), + screen->imageControl(), + *screen->layerManager().getLayer(Layer::MENU), + context)); + } +#endif // HAVE_XRENDER } else if (type == "extramenus") { BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); BScreen::ExtraMenus::iterator it = screen->extraWindowMenus().begin(); @@ -584,8 +649,6 @@ bool MenuCreator::createWindowMenuItem(const string &type, if (screen == 0) return false; - static MenuContext context; - FbTk::Menu *submenu = new LayerMenu(screen->menuTheme(), screen->imageControl(), *screen->layerManager().getLayer(Layer::MENU), diff --git a/src/Remember.cc b/src/Remember.cc index f084677..6db1f9c 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -40,6 +40,7 @@ #include "FbTk/MenuItem.hh" #include "FbTk/App.hh" #include "FbTk/stringstream.hh" +#include "FbTk/Transparent.hh" #include @@ -155,6 +156,10 @@ FbTk::Menu *createRememberMenu(BScreen &screen) { Remember::REM_DECOSTATE)); menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Shaded, "Shaded", "Remember shaded"), Remember::REM_SHADEDSTATE)); + if (FbTk::Transparent::haveComposite() + || FbTk::Transparent::haveRender()) + menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Alpha, "Transparency", "Remember window tranparency settings"), + Remember::REM_ALPHA)); menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, Layer, "Layer", "Remember Layer"), Remember::REM_LAYER)); menu->insert(new RememberMenuItem(_FB_XTEXT(Remember, SaveOnClose, "Save on close", "Save remembered attributes on close"), @@ -241,6 +246,7 @@ Application::Application(bool grouped) tabstate_remember = workspace_remember = head_remember = + alpha_remember = save_on_close_remember = false; } @@ -477,6 +483,30 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) { else had_error = 1; } + } else if (strcasecmp(str_key.c_str(), "Alpha") == 0) { + int focused_a, unfocused_a; + if (sscanf(str_label.c_str(), "%i %i", &focused_a, &unfocused_a) == 2) + { + // clamp; + if (focused_a > 255) + focused_a = 255; + if (unfocused_a > 255) + unfocused_a = 255; + if (focused_a <= 0) + focused_a = 0; + if (unfocused_a <= 0) + unfocused_a = 0; + + app.rememberAlpha(focused_a, unfocused_a); + } else if (sscanf(str_label.c_str(), "%i", &focused_a) == 1) { + if (focused_a > 255) + focused_a = 255; + if (focused_a <= 0) + focused_a = 0; + app.rememberAlpha(focused_a, focused_a); + } + else + had_error = 1; } else if (strcasecmp(str_key.c_str(), "Sticky") == 0) { app.rememberStuckstate((strcasecmp(str_label.c_str(), "yes") == 0)); } else if (strcasecmp(str_key.c_str(), "Jump") == 0) { @@ -807,6 +837,12 @@ void Remember::save() { if (a.save_on_close_remember) { apps_file << " [Close]\t{" << ((a.save_on_close)?"yes":"no") << "}" << endl; } + if (a.alpha_remember) { + if (a.focused_alpha == a.unfocused_alpha) + apps_file << " [Alpha]\t{" << a.focused_alpha << "}" << endl; + else + apps_file << " [Alpha]\t{" << a.focused_alpha << " " << a.unfocused_alpha << "}" << endl; + } apps_file << "[end]" << endl; } apps_file.close(); @@ -860,6 +896,8 @@ bool Remember::isRemembered(WinClient &winclient, Attribute attrib) { case REM_SAVEONCLOSE: return app->save_on_close_remember; break; + case REM_ALPHA: + return app->alpha_remember; case REM_LASTATTRIB: default: return false; // should never get here @@ -903,6 +941,9 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) { case REM_STUCKSTATE: app->rememberStuckstate(win->isStuck()); break; + case REM_ALPHA: + app->rememberAlpha(win->frame().getAlpha(true), win->frame().getAlpha(false)); + break; // case REM_TABSTATE: // break; case REM_JUMPWORKSPACE: @@ -957,6 +998,9 @@ void Remember::forgetAttrib(WinClient &winclient, Attribute attrib) { case REM_SHADEDSTATE: app->forgetShadedstate(); break; + case REM_ALPHA: + app->forgetAlpha(); + break; // case REM_TABSTATE: // break; case REM_JUMPWORKSPACE: @@ -1004,6 +1048,12 @@ void Remember::setupFrame(FluxboxWindow &win) { if (app->decostate_remember) win.setDecorationMask(app->decostate); + if (app->alpha_remember) { + win.frame().setUseDefaultAlpha(false); + win.frame().setAlpha(true,app->focused_alpha); + win.frame().setAlpha(false,app->unfocused_alpha); + } + BScreen &screen = winclient.screen(); // now check if fluxbox is restarting diff --git a/src/Remember.hh b/src/Remember.hh index 42edca3..d78e226 100644 --- a/src/Remember.hh +++ b/src/Remember.hh @@ -58,6 +58,7 @@ public: inline void forgetJumpworkspace() { jumpworkspace_remember = false; } inline void forgetLayer() { layer_remember = false; } inline void forgetSaveOnClose() { save_on_close_remember = false; } + inline void forgetAlpha() { alpha_remember = false; } inline void rememberWorkspace(int ws) { workspace = ws; workspace_remember = true; } @@ -85,6 +86,8 @@ public: { layer = layernum; layer_remember = true; } inline void rememberSaveOnClose(bool state) { save_on_close = state; save_on_close_remember = true; } + inline void rememberAlpha(int focused_a, int unfocused_a) + { focused_alpha = focused_a; unfocused_alpha = unfocused_a; alpha_remember = true; } bool workspace_remember; @@ -103,6 +106,10 @@ public: // 2 - lowerleft // 3 - lowerright + bool alpha_remember; + int focused_alpha; + int unfocused_alpha; + bool shadedstate_remember; bool shadedstate; @@ -161,6 +168,7 @@ public: //REM_TABSTATE, ... external tabs disabled atm REM_WORKSPACE, REM_HEAD, + REM_ALPHA, REM_LASTATTRIB // not actually used }; diff --git a/src/Screen.cc b/src/Screen.cc index 5ea6202..58f195a 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -1689,7 +1689,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { *resource.max_over_tabs, save_and_reconfigure)); FbTk::MenuItem *tab_width_item = - new IntResMenuItem(_FB_XTEXT(Configmenu, ExternalTabWidth, + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Configmenu, ExternalTabWidth, "External Tab Width", "Width of external-style tabs"), resource.tab_width, 10, 3000, /* silly number */ @@ -1791,7 +1791,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { } FbTk::MenuItem *focused_alpha_item = - new IntResMenuItem(_FB_XTEXT(Configmenu, FocusedAlpha, + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Configmenu, FocusedAlpha, "Focused Window Alpha", "Transparency level of the focused window"), resource.focused_alpha, 0, 255, *alpha_menu); @@ -1799,7 +1799,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { alpha_menu->insert(focused_alpha_item); FbTk::MenuItem *unfocused_alpha_item = - new IntResMenuItem(_FB_XTEXT(Configmenu, + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Configmenu, UnfocusedAlpha, "Unfocused Window Alpha", "Transparency level of unfocused windows"), @@ -1809,7 +1809,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { alpha_menu->insert(unfocused_alpha_item); FbTk::MenuItem *menu_alpha_item = - new IntResMenuItem(_FB_XTEXT(Configmenu, MenuAlpha, + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Configmenu, MenuAlpha, "Menu Alpha", "Transparency level of menu"), resource.menu_alpha, 0, 255, *alpha_menu); menu_alpha_item->setCommand(saverc_cmd); diff --git a/src/Slit.cc b/src/Slit.cc index e95708e..e9e2e91 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -1276,7 +1276,7 @@ void Slit::setupMenu() { // this saves resources and clears the slit window to update alpha value FbTk::MenuItem *alpha_menuitem = - new IntResMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), m_rc_alpha, 0, 255, m_slitmenu); // setup command for alpha value diff --git a/src/Toolbar.cc b/src/Toolbar.cc index c0d3f88..4d2f191 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -845,7 +845,7 @@ void Toolbar::setupMenus(bool skip_new_placement) { reconfig_toolbar_and_save_resource)); MenuItem *toolbar_menuitem = - new IntResMenuItem(_FB_XTEXT(Toolbar, WidthPercent, + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Toolbar, WidthPercent, "Toolbar width percent", "Percentage of screen width taken by toolbar"), m_rc_width_percent, @@ -922,7 +922,7 @@ void Toolbar::setupMenus(bool skip_new_placement) { // this saves resources and clears the slit window to update alpha value FbTk::MenuItem *alpha_menuitem = - new IntResMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), + new IntResMenuItem< FbTk::Resource >(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), m_rc_alpha, 0, 255, menu()); // setup command for alpha value diff --git a/src/Window.cc b/src/Window.cc index 56bf796..ca42c96 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -49,6 +49,7 @@ #include "FbTk/KeyUtil.hh" #include "FbTk/SimpleCommand.hh" #include "FbTk/Select2nd.hh" +#include "FbTk/Transparent.hh" #ifdef HAVE_CONFIG_H #include "config.h" @@ -1503,6 +1504,13 @@ void FluxboxWindow::show() { frame().show(); } +void FluxboxWindow::toggleIconic() { + if (isIconic()) + deiconify(); + else + iconify(); +} + /** Unmaps the window and removes it from workspace list */ diff --git a/src/Window.hh b/src/Window.hh index 142b451..429747f 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -201,6 +201,19 @@ public: void hide(bool interrupt_moving); void iconify(); void deiconify(bool reassoc = true, bool do_raise = true); + + // ------------------ + // Per window transparency addons + unsigned char getFocusedAlpha() const { return frame().getAlpha(true); } + unsigned char getUnfocusedAlpha() const { return frame().getAlpha(false); } + void setFocusedAlpha(unsigned char alpha) { frame().setAlpha(true, alpha); } + void setUnfocusedAlpha(unsigned char alpha) { frame().setAlpha(false, alpha); } + void updateAlpha(bool focused, unsigned char alpha) { frame().setAlpha(focused, alpha); } + + bool getUseDefaultAlpha() const { return frame().getUseDefaultAlpha(); } + void setUseDefaultAlpha(bool default_alpha) { frame().setUseDefaultAlpha(default_alpha); } + // ------------------ + /// close current client void close(); /// kill current client @@ -225,6 +238,8 @@ public: void shadeOff(); /// toggles sticky void stick(); + /// toggles iconic + void toggleIconic(); void raise(); void lower(); void tempRaise(); @@ -320,7 +335,9 @@ public: inline bool isManaged() const { return m_initialized; } inline bool isFocused() const { return focused; } bool isVisible() const; + inline bool isIconic() { return iconic; } inline bool isIconic() const { return iconic; } + inline bool isShaded() { return shaded; } inline bool isShaded() const { return shaded; } inline bool isFullscreen() const { return fullscreen; } inline bool isMaximized() const { return maximized == MAX_FULL; } -- cgit v0.11.2