1 // FbWinFrame.hh for Fluxbox Window Manager 2 // Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 22 #ifndef FBWINFRAME_HH 23 #define FBWINFRAME_HH 24 25 #include "WindowState.hh" 26 27 #include "FbTk/FbWindow.hh" 28 #include "FbTk/EventHandler.hh" 29 #include "FbTk/RefCount.hh" 30 #include "FbTk/Color.hh" 31 #include "FbTk/LayerItem.hh" 32 #include "FbTk/TextButton.hh" 33 #include "FbTk/Container.hh" 34 #include "FbTk/Shape.hh" 35 #include "FbTk/Signal.hh" 36 37 #include <vector> 38 #include <memory> 39 40 class FbWinFrameTheme; 41 class BScreen; 42 class IconButton; 43 class Focusable; 44 template <class T> class FocusableTheme; 45 46 namespace FbTk { 47 class ImageControl; 48 template <class T> class Command; 49 class Texture; 50 } 51 52 /// holds a window frame with a client window 53 /// (see: <a href="fluxbox_fbwinframe.png">image</a>) 54 class FbWinFrame:public FbTk::EventHandler { 55 public: 56 // STRICTINTERNAL means it doesn't go external automatically when no titlebar 57 enum TabMode { NOTSET = 0, INTERNAL = 1, EXTERNAL }; 58 59 /// Toolbar placement on the screen 60 enum TabPlacement{ 61 // top and bottom placement 62 TOPLEFT = 1, TOP, TOPRIGHT, 63 BOTTOMLEFT, BOTTOM, BOTTOMRIGHT, 64 // left and right placement 65 LEFTBOTTOM, LEFT, LEFTTOP, 66 RIGHTBOTTOM, RIGHT, RIGHTTOP, 67 68 DEFAULT = TOPLEFT 69 }; 70 71 /// create a top level window 72 FbWinFrame(BScreen &screen, unsigned int client_depth, WindowState &state, 73 FocusableTheme<FbWinFrameTheme> &theme); 74 75 /// destroy frame 76 ~FbWinFrame(); 77 78 void hide(); 79 void show(); isVisible() const80 bool isVisible() const { return m_visible; } 81 82 void move(int x, int y); 83 void resize(unsigned int width, unsigned int height); 84 /// resize client to specified size and resize frame to it 85 void resizeForClient(unsigned int width, unsigned int height, int win_gravity=ForgetGravity, unsigned int client_bw = 0); 86 87 // for when there needs to be an atomic move+resize operation 88 void moveResizeForClient(int x, int y, 89 unsigned int width, unsigned int height, 90 int win_gravity=ForgetGravity, unsigned int client_bw = 0, bool move = true, bool resize = true); 91 92 // can elect to ignore move or resize (mainly for use of move/resize individual functions 93 void moveResize(int x, int y, 94 unsigned int width, unsigned int height, 95 bool move = true, bool resize = true); 96 97 // move without transparency or special effects (generally when dragging) 98 void quietMoveResize(int x, int y, 99 unsigned int width, unsigned int height); 100 101 /// some outside move/resize happened, and we need to notify all of our windows 102 /// in case of transparency 103 void notifyMoved(bool clear); 104 void clearAll(); 105 106 /// set focus/unfocus style 107 void setFocus(bool newvalue); 108 setFocusTitle(const FbTk::BiDiString & str)109 void setFocusTitle(const FbTk::BiDiString &str) { m_label.setText(str); } 110 bool setTabMode(TabMode tabmode); updateTabProperties()111 void updateTabProperties() { alignTabs(); } 112 113 /// Alpha settings 114 void setAlpha(bool focused, int value); 115 int getAlpha(bool focused) const; 116 void applyAlpha(); 117 118 void setDefaultAlpha(); 119 bool getUseDefaultAlpha() const; 120 121 /// add a button to the left of the label 122 void addLeftButton(FbTk::Button *btn); 123 /// add a button to the right of the label 124 void addRightButton(FbTk::Button *btn); 125 /// remove all buttons from titlebar 126 void removeAllButtons(); 127 /// adds a button to tab container 128 void createTab(FbTk::Button &button); 129 /// removes a specific button from label window 130 void removeTab(IconButton *id); 131 /// move label button to the left 132 void moveLabelButtonLeft(FbTk::TextButton &btn); 133 /// move label button to the right 134 void moveLabelButtonRight(FbTk::TextButton &btn); 135 /// move label button to the given location( x and y are relative to the root window) 136 void moveLabelButtonTo(FbTk::TextButton &btn, int x, int y); 137 /// move the first label button to the left of the second 138 void moveLabelButtonLeftOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); 139 //move the first label button to the right of the second 140 void moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); 141 /// attach a client window for client area 142 void setClientWindow(FbTk::FbWindow &win); 143 /// remove attached client window 144 void removeClient(); 145 /// redirect events to another eventhandler 146 void setEventHandler(FbTk::EventHandler &evh); 147 /// remove any handler for the windows 148 void removeEventHandler(); 149 sizeHints() const150 const SizeHints &sizeHints() const { return m_state.size_hints; } setSizeHints(const SizeHints & hint)151 void setSizeHints(const SizeHints &hint) { m_state.size_hints = hint; } 152 153 void applySizeHints(unsigned int &width, unsigned int &height, 154 bool maximizing = false) const; 155 void displaySize(unsigned int width, unsigned int height) const; 156 setDecorationMask(unsigned int mask)157 void setDecorationMask(unsigned int mask) { m_state.deco_mask = mask; } 158 void applyDecorations(bool do_move = true); 159 void applyState(); 160 161 // this function translates its arguments according to win_gravity 162 // if win_gravity is negative, it does an inverse translation 163 void gravityTranslate(int &x, int &y, int win_gravity, unsigned int client_bw, bool move_frame = false); setActiveGravity(int gravity,unsigned int orig_client_bw)164 void setActiveGravity(int gravity, unsigned int orig_client_bw) { m_state.size_hints.win_gravity = gravity; m_active_orig_client_bw = orig_client_bw; } 165 166 /** 167 @name Event handlers 168 */ 169 //@{ 170 void exposeEvent(XExposeEvent &event); 171 void configureNotifyEvent(XConfigureEvent &event); 172 void handleEvent(XEvent &event); 173 //@} 174 175 void reconfigure(); 176 void setShapingClient(FbTk::FbWindow *win, bool always_update); updateShape()177 void updateShape() { m_shape.update(); } 178 179 /** 180 @name accessors 181 */ 182 //@{ x() const183 int x() const { return m_window.x(); } y() const184 int y() const { return m_window.y(); } width() const185 unsigned int width() const { return m_window.width(); } height() const186 unsigned int height() const { return m_window.height(); } 187 188 // extra bits for tabs 189 int xOffset() const; 190 int yOffset() const; 191 int widthOffset() const; 192 int heightOffset() const; 193 window() const194 const FbTk::FbWindow &window() const { return m_window; } window()195 FbTk::FbWindow &window() { return m_window; } 196 /// @return titlebar window titlebar() const197 const FbTk::FbWindow &titlebar() const { return m_titlebar; } titlebar()198 FbTk::FbWindow &titlebar() { return m_titlebar; } label() const199 const FbTk::FbWindow &label() const { return m_label; } label()200 FbTk::FbWindow &label() { return m_label; } 201 tabcontainer() const202 const FbTk::Container &tabcontainer() const { return m_tab_container; } tabcontainer()203 FbTk::Container &tabcontainer() { return m_tab_container; } 204 205 /// @return clientarea window clientArea() const206 const FbTk::FbWindow &clientArea() const { return m_clientarea; } clientArea()207 FbTk::FbWindow &clientArea() { return m_clientarea; } 208 /// @return handle window handle() const209 const FbTk::FbWindow &handle() const { return m_handle; } handle()210 FbTk::FbWindow &handle() { return m_handle; } gripLeft() const211 const FbTk::FbWindow &gripLeft() const { return m_grip_left; } gripLeft()212 FbTk::FbWindow &gripLeft() { return m_grip_left; } gripRight() const213 const FbTk::FbWindow &gripRight() const { return m_grip_right; } gripRight()214 FbTk::FbWindow &gripRight() { return m_grip_right; } focused() const215 bool focused() const { return m_state.focused; } theme() const216 FocusableTheme<FbWinFrameTheme> &theme() const { return m_theme; } 217 /// @return titlebar height titlebarHeight() const218 unsigned int titlebarHeight() const { return (m_use_titlebar?m_titlebar.height()+m_titlebar.borderWidth():0); } handleHeight() const219 unsigned int handleHeight() const { return (m_use_handle?m_handle.height()+m_handle.borderWidth():0); } 220 /// @return size of button 221 unsigned int buttonHeight() const; externalTabMode() const222 bool externalTabMode() const { return m_tabmode == EXTERNAL && m_use_tabs; } 223 layerItem() const224 const FbTk::LayerItem &layerItem() const { return m_layeritem; } layerItem()225 FbTk::LayerItem &layerItem() { return m_layeritem; } 226 frameExtentSig()227 FbTk::Signal<> &frameExtentSig() { return m_frame_extent_sig; } 228 /// @returns true if the window is inside titlebar, 229 /// assuming window is an event window that was generated for this frame. 230 bool insideTitlebar(Window win) const; 231 232 /// @returns context for window, 233 /// assuming window is an event window that was generated for this frame. 234 int getContext(Window win, int x=0, int y=0, int last_x=0, int last_y=0, bool doBorders=false); 235 236 //@} 237 238 private: 239 void redrawTitlebar(); 240 241 /// reposition titlebar items 242 void reconfigureTitlebar(); 243 /** 244 @name render helper functions 245 */ 246 //@{ 247 void renderAll(); 248 void renderTitlebar(); 249 void renderHandles(); 250 void renderTabContainer(); // and labelbuttons 251 252 void renderButtons(); // subset of renderTitlebar - don't call directly 253 254 //@} 255 256 // these return true/false for if something changed 257 bool hideTitlebar(); 258 bool showTitlebar(); 259 bool hideTabs(); 260 bool showTabs(); 261 bool hideHandle(); 262 bool showHandle(); 263 bool setBorderWidth(bool do_move = true); 264 265 // check which corners should be rounded 266 int getShape() const; 267 268 /** 269 @name apply pixmaps depending on focus 270 */ 271 //@{ 272 void applyAll(); 273 void applyTitlebar(); 274 void applyHandles(); 275 void applyTabContainer(); // and label buttons 276 void applyButtons(); // only called within applyTitlebar 277 278 #if 0 279 void getCurrentFocusPixmap(Pixmap &label_pm, Pixmap &title_pm, 280 FbTk::Color &label_color, FbTk::Color &title_color); 281 #endif 282 283 /// initiate inserted button for current theme 284 void applyButton(FbTk::Button &btn); 285 286 void alignTabs(); 287 //@} 288 289 /// initiate some commont variables 290 void init(); 291 292 BScreen &m_screen; 293 294 FocusableTheme<FbWinFrameTheme> &m_theme; ///< theme to be used 295 FbTk::ImageControl &m_imagectrl; ///< Image control for rendering 296 WindowState &m_state; 297 298 /** 299 @name windows 300 */ 301 //@{ 302 FbTk::FbWindow m_window; ///< base window that holds each decorations (ie titlebar, handles) 303 // want this deleted before the windows in it 304 FbTk::LayerItem m_layeritem; 305 306 FbTk::FbWindow m_titlebar; ///< titlebar window 307 FbTk::Container m_tab_container; ///< Holds tabs 308 FbTk::TextButton m_label; ///< holds title 309 FbTk::FbWindow m_handle; ///< handle between grips 310 FbTk::FbWindow m_grip_right, ///< rightgrip 311 m_grip_left; ///< left grip 312 FbTk::FbWindow m_clientarea; ///< window that sits behind client window to fill gaps @see setClientWindow 313 //@} 314 315 FbTk::Signal<> m_frame_extent_sig; 316 317 typedef std::vector<FbTk::Button *> ButtonList; 318 ButtonList m_buttons_left, ///< buttons to the left 319 m_buttons_right; ///< buttons to the right 320 typedef std::list<FbTk::TextButton *> LabelList; 321 int m_bevel; ///< bevel between titlebar items and titlebar 322 bool m_use_titlebar; ///< if we should use titlebar 323 bool m_use_tabs; ///< if we should use tabs (turns them off in external mode only) 324 bool m_use_handle; ///< if we should use handle 325 bool m_visible; ///< if we are currently showing 326 ///< do we use screen or window alpha settings ? (0 = window, 1 = default, 2 = default and window never set) 327 328 /** 329 @name pixmaps and colors for rendering 330 */ 331 //@{ 332 333 // 0-unfocus, 1-focus 334 struct Face { Pixmap pm[2]; FbTk::Color color[2]; }; 335 // 0-unfocus, 1-focus, 2-pressed 336 struct BtnFace { Pixmap pm[3]; FbTk::Color color[3]; }; 337 338 Face m_title_face; 339 Face m_label_face; 340 Face m_tabcontainer_face; 341 Face m_handle_face; 342 Face m_grip_face; 343 BtnFace m_button_face; 344 345 //@} 346 347 TabMode m_tabmode; 348 349 unsigned int m_active_orig_client_bw; 350 351 bool m_need_render; 352 int m_button_size; ///< size for all titlebar buttons 353 int m_alpha[2]; // 0-unfocused, 1-focused 354 355 FbTk::Shape m_shape; 356 }; 357 358 #endif // FBWINFRAME_HH 359