removed
fluxgen fluxgen
D
src/Tab.cc
@@ -1,1206 +0,0 @@
-// Tab.cc for Fluxbox Window Manager -// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen at linuxmail.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: Tab.cc,v 1.56 2003/04/09 13:18:36 fluxgen Exp $ - -#include "Tab.hh" - -#include "Window.hh" -#include "i18n.hh" -#include "DrawUtil.hh" -#include "Screen.hh" -#include "fluxbox.hh" -#include "ImageControl.hh" - -#include <iostream> -using namespace std; - -bool Tab::m_stoptabs = false; -Tab::t_tabplacementlist Tab::m_tabplacementlist[] = { - {PTOP, "Top"}, - {PBOTTOM, "Bottom"}, - {PLEFT, "Left"}, - {PRIGHT, "Right"}, - {PNONE, "none"} -}; - -Tab::t_tabplacementlist Tab::m_tabalignmentlist[] = { - {ALEFT, "Left"}, - {ACENTER, "Center"}, - {ARIGHT, "Right"}, - {ARELATIVE, "Relative"}, - {ANONE, "none"} -}; - -Tab::Tab(FluxboxWindow *win, Tab *prev, Tab *next) { - //set default values - - m_focus = m_moving = false; - m_configured = true; // only set to false before Fluxbox::reconfigure - m_move_x = m_move_y = 0; - m_prev = prev; m_next = next; - m_win = win; - m_display = BaseDisplay::getXDisplay(); - - if ((m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) && - m_win->getScreen()->isTabRotateVertical() && - !m_win->isShaded()) { - m_size_w = m_win->getScreen()->getTabHeight(); - m_size_h = m_win->getScreen()->getTabWidth(); - } else { - m_size_w = m_win->getScreen()->getTabWidth(); - m_size_h = m_win->getScreen()->getTabHeight(); - } - - createTabWindow(); - - calcIncrease(); -} - -Tab::~Tab() { - - disconnect(); - - Fluxbox::instance()->removeTabSearch(m_tabwin); - XDestroyWindow(m_display, m_tabwin); -} - - -//---------------- createTabWindow --------------- -// (private) -// Creates the Window for tab to be above the title window. -// This should only be called by the constructor. -//------------------------------------------------- -void Tab::createTabWindow() { - unsigned long attrib_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | - CWColormap | CWOverrideRedirect | CWEventMask; - XSetWindowAttributes attrib; - attrib.background_pixmap = None; - attrib.background_pixel = attrib.border_pixel = - m_win->getScreen()->getWindowStyle()->tab.border_color.pixel(); - attrib.colormap = m_win->getScreen()->colormap(); - attrib.override_redirect = True; - attrib.event_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | ExposureMask | EnterWindowMask; - //Notice that m_size_w gets the TOTAL width of tabs INCLUDING borders - m_tabwin = XCreateWindow(m_display, m_win->getScreen()->getRootWindow(), - -30000, -30000, //TODO: So that it wont flicker or - // appear before the window do - m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, - m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, - m_win->getScreen()->getWindowStyle()->tab.border_width, - m_win->getScreen()->getDepth(), InputOutput, - m_win->getScreen()->getVisual(), attrib_mask, &attrib); - - //set grab - XGrabButton(m_display, Button1, Mod1Mask, m_tabwin, True, - ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, - GrabModeAsync, None, Fluxbox::instance()->getMoveCursor()); - - //save to tabsearch - Fluxbox::instance()->saveTabSearch(m_tabwin, this); - - XMapSubwindows(m_display, m_tabwin); - // don't show if the window is iconified - if (!m_win->isIconic()) - XMapWindow(m_display, m_tabwin); - - decorate(); -} - -//-------------- focus -------------------- -// Called when the focus changes in m_win -// updates pixmap or color and draws the tab -//----------------------------------------- -void Tab::focus() { - - if (m_win->isFocused()) { - if (m_focus_pm) - XSetWindowBackgroundPixmap(m_display, m_tabwin, m_focus_pm); - else - XSetWindowBackground(m_display, m_tabwin, m_focus_pixel); - } else { - if (m_unfocus_pm) - XSetWindowBackgroundPixmap(m_display, m_tabwin, m_unfocus_pm); - else - XSetWindowBackground(m_display, m_tabwin, m_unfocus_pixel); - } - XClearWindow(m_display, m_tabwin); - draw(false); -} - -//-------------- raise -------------------- -// Raises the tabs in the tablist -//----------------------------------------- -void Tab::raise() { - //get first tab - /* - Tab *tab = 0; - //raise tabs - Workspace::Stack st; - for (tab = getFirst(this); tab!=0; tab = tab->m_next) { - st.push_back(tab->m_tabwin); - } - m_win->getScreen()->raiseWindows(st); - */ -} - -//-------------- lower -------------------- -// Lowers the tabs in the tablist AND -// the windows the tabs relate to -//----------------------------------------- -void Tab::lower() { - Tab *current = this; - FluxboxWindow *win = 0; //convenience - //this have to be done in the correct order, otherwise we'll switch the window - //being ontop in the group - do { - XLowerWindow(m_display, current->m_tabwin); //lower tabwin and tabs window - win = current->getWindow(); - win->lower(); - - current = current->next(); //get next - if (current == 0) - current = getFirst(this); //there weren't any after, get the first - - } while (current != this); -} - -//-------------- loadTheme ----------------- -// loads the texture with the correct -// width and height, this is necessary in -// vertical and relative tab modes -// TODO optimize this -//------------------------------------------ -void Tab::loadTheme() { - FbTk::ImageControl *image_ctrl = m_win->getScreen()->getImageControl(); - Pixmap tmp = m_focus_pm; - const FbTk::Texture *texture = &(m_win->getScreen()->getWindowStyle()->tab.l_focus); - - if (texture->type() & FbTk::Texture::PARENTRELATIVE ) { - const FbTk::Texture &pt = m_win->getScreen()->getWindowStyle()->tab.t_focus; - if (pt.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { - m_focus_pm = None; - m_focus_pixel = pt.color().pixel(); - } else - m_focus_pm = - image_ctrl->renderImage(m_size_w, m_size_h, pt); - - if (tmp) image_ctrl->removeImage(tmp); - - } else { - if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { - m_focus_pm = None; - m_focus_pixel = texture->color().pixel(); - } else - m_focus_pm = - image_ctrl->renderImage(m_size_w, m_size_h, *texture); - if (tmp) image_ctrl->removeImage(tmp); - } - - tmp = m_unfocus_pm; - texture = &(m_win->getScreen()->getWindowStyle()->tab.l_unfocus); - - if (texture->type() & FbTk::Texture::PARENTRELATIVE ) { - const FbTk::Texture &pt = m_win->getScreen()->getWindowStyle()->tab.t_unfocus; - if (pt.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { - m_unfocus_pm = None; - m_unfocus_pixel = pt.color().pixel(); - } else - m_unfocus_pm = - image_ctrl->renderImage(m_size_w, m_size_h, pt); - } else { - if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) { - m_unfocus_pm = None; - m_unfocus_pixel = texture->color().pixel(); - } else - m_unfocus_pm = - image_ctrl->renderImage(m_size_w, m_size_h, *texture); - } - - if (tmp) image_ctrl->removeImage(tmp); -} - -/** - decorates the tab with current theme -*/ -void Tab::decorate() { - loadTheme(); - - XSetWindowBorderWidth(m_display, m_tabwin, - m_win->getScreen()->getWindowStyle()->tab.border_width); - XSetWindowBorder(m_display, m_tabwin, - m_win->getScreen()->getWindowStyle()->tab.border_color.pixel()); -} - -/** - Deiconifies the tab - Used from FluxboxWindow to deiconify the tab when the window is deiconfied -*/ -void Tab::deiconify() { - XMapWindow(m_display, m_tabwin); -} - -/** - Iconifies the tab. - Used from FluxboxWindow to hide tab win when window is iconified - disconnects itself from the list -*/ -void Tab::iconify() { - disconnect(); - withdraw(); - if(!Fluxbox::instance()->useTabs() && !m_next && !m_prev)//if we don't want to use tabs that much - m_win->setTab(false);//let's get rid of this loner tab -} - -/** - Unmaps the tab from display -*/ -void Tab::withdraw() { - XUnmapWindow(m_display, m_tabwin); -} - -/** - Set/reset the the sticky on all windows in the list -*/ -void Tab::stick() { - Tab *tab; - - bool wasstuck = m_win->isStuck(); - - //now do stick for all windows in the list - for (tab = getFirst(this); tab != 0; tab = tab->m_next) { - FluxboxWindow *win = tab->m_win; //just for convenience - if (wasstuck) { - win->blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; - win->blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT; - win->stuck = false; - - } else { - win->stuck = true; - BScreen *screen = win->getScreen(); - if (!win->isIconic() && !(win->getWorkspaceNumber() != - screen->getCurrentWorkspaceID())) { - screen->reassociateWindow(win, screen->getCurrentWorkspaceID(), true); - } - - win->blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; - win->blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; - } - - win->setState(win->current_state); - } - -} - -/** - Resize the window's in the tablist -*/ -void Tab::resize() { - Tab *tab; - - //now move and resize the windows in the list - for (tab = getFirst(this); tab != 0; tab = tab->m_next) { - if (tab!=this) { - tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), - m_win->getWidth(), m_win->getHeight()); - } - } - - // need to resize tabs if in relative mode - if (m_win->getScreen()->getTabAlignment() == ARELATIVE) { - calcIncrease(); - setPosition(); - } -} - -/** - Shades the windows in the tablist -*/ -void Tab::shade() { - Tab *tab; - - for(tab = getFirst(this); tab != 0; tab = tab->m_next) { - if (tab==this) - continue; - tab->m_win->shade(); - } - - if (m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) { - resizeGroup(); - calcIncrease(); - } - - if (!(m_win->getScreen()->getTabPlacement() == PTOP)) - setPosition(); -} - -/** - Draws the tab - if pressed = true then it draws the tab in pressed - mode else it draws it in normal mode - TODO: the "draw in pressed mode" -*/ -void Tab::draw(bool pressed) const { - XClearWindow(m_display, m_tabwin); - - if (m_win->getTitle().size() == 0) // we don't have anything to draw - return; - - GC gc = ((m_win->isFocused()) ? m_win->getScreen()->getWindowStyle()->tab.l_text_focus_gc : - m_win->getScreen()->getWindowStyle()->tab.l_text_unfocus_gc); - - Theme::WindowStyle *winstyle = m_win->getScreen()->getWindowStyle(); - size_t dlen = m_win->getTitle().size(); - - size_t max_width = m_size_w; // special cases in rotated mode - if (winstyle->tab.font.isRotated() && !m_win->isShaded()) - max_width = m_size_h; - - int dx = DrawUtil::doAlignment(max_width, 1, //m_win->frame.bevel_w, - winstyle->tab.justify, - winstyle->tab.font, - m_win->getTitle().c_str(), m_win->getTitle().size(), dlen); - - int dy = winstyle->tab.font.ascent() + 1; //m_win->frame.bevel_w; - bool rotate = false; - // swap dx and dy if we're rotated - if (winstyle->tab.font.isRotated() && !m_win->isShaded()) { - int tmp = dy; - dy = m_size_h - dx; // upside down (reverse direction) - dx = tmp; - rotate = true; - } - // draw normal without rotation - winstyle->tab.font.drawText( - m_tabwin, - m_win->getScreen()->getScreenNumber(), - gc, - m_win->getTitle().c_str(), dlen, - dx, dy, - rotate); -} - -/** -Helper for the Tab::setPosition() call -returns the y position component correctly -according to shading in cases PBOTTOM and -isShaded() -*/ -int Tab::setPositionShadingHelper(bool shaded) { - if (shaded) { - return m_win->getYFrame() + m_win->getTitleHeight() + - m_win->getScreen()->getBorderWidth2x(); - } else { - return m_win->getYFrame() + m_win->getHeight() + - m_win->getScreen()->getBorderWidth2x(); - } -} - -/** -Helpers for correct alignment of tabs used -by the setPosition() call -return x/y positions correctly according to -alignment, the 1st for cases PTOP and PBOTTOM -the 2nd for cases PLEFT and PRIGHT -*/ -int Tab::setPositionTBAlignHelper(Alignment align) { - switch(align) { - - case ARELATIVE: - case ALEFT: - return m_win->getXFrame(); - break; - case ACENTER: - return calcCenterXPos(); - break; - case ARIGHT: - return m_win->getXFrame() + m_win->getWidth() + - m_win->getScreen()->getBorderWidth2x() - m_size_w; - default: -#ifdef DEBUG - cerr << __FILE__ << ":" <<__LINE__ << ": " << - "Unsupported Alignment" << endl; -#endif //DEBUG - return 0; - break; - } -} - -int Tab::setPositionLRAlignHelper(Alignment align) { - switch(align) { - case ALEFT: - return m_win->getYFrame() - m_size_h + m_win->getHeight() + - m_win->getScreen()->getBorderWidth2x(); - break; - case ACENTER: - return calcCenterYPos(); - break; - case ARELATIVE: - case ARIGHT: - return m_win->getYFrame(); - break; - default: -#ifdef DEBUG - cerr << __FILE__ << ":"<< __LINE__ << ": " << - "Unsupported Alignment" << endl; -#endif //DEBUG - return 0; - break; - } -} - -/** - Position tab ( follow the m_win pos ). - (and resize) - Set new position of the other tabs in the chain -*/ -void Tab::setPosition() { - //don't do anything if the tablist is freezed - if (m_stoptabs) - return; - - Tab *tab; - int pos_x = 0, pos_y = 0; - - m_stoptabs = true; //freeze tablist - - //and check for max tabs - - //Tab placement + alignment - switch (m_win->getScreen()->getTabPlacement()) { - case PTOP: - pos_y = m_win->getYFrame() - m_size_h; - pos_x = setPositionTBAlignHelper( - m_win->getScreen()->getTabAlignment()); - break; - case PBOTTOM: - pos_y = setPositionShadingHelper(m_win->isShaded()); - pos_x = setPositionTBAlignHelper( - m_win->getScreen()->getTabAlignment()); - break; - case PLEFT: - pos_x = m_win->isShaded() ? - setPositionTBAlignHelper(m_win->getScreen()->getTabAlignment()) : - m_win->getXFrame() - m_size_w; - pos_y = m_win->isShaded() ? - setPositionShadingHelper(true) : - setPositionLRAlignHelper(m_win->getScreen()->getTabAlignment()); - break; - case PRIGHT: - pos_x = m_win->isShaded() ? - setPositionTBAlignHelper(m_win->getScreen()->getTabAlignment()) : - m_win->getXFrame() + m_win->getWidth() + - m_win->getScreen()->getBorderWidth2x(); - pos_y = m_win->isShaded() ? - setPositionShadingHelper(true) : - setPositionLRAlignHelper(m_win->getScreen()->getTabAlignment()); - break; - default: - if(m_win->isShaded()) { - pos_y = setPositionShadingHelper(true); - pos_x = setPositionTBAlignHelper( - m_win->getScreen()->getTabAlignment()); - } else { - setPositionShadingHelper(false); - } - break; - } - - for (tab = getFirst(this); - tab!=0; - pos_x += tab->m_inc_x, pos_y += tab->m_inc_y, - tab = tab->m_next){ - - XMoveWindow(m_display, tab->m_tabwin, pos_x, pos_y); - - //dont move FluxboxWindow if the iterator = this - if (tab != this) { - tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), - m_win->getWidth(), m_win->getHeight()); - } - } - - m_stoptabs = false;//thaw tablist -} - -//Moves the tab to the left -void Tab::movePrev() { - insert(m_prev); -} - -//Moves the tab to the next tab if m_next != 0 -void Tab::moveNext() { - if(m_next == 0) - return; - Tab *tmp = m_next; - disconnect(); - tmp->insert(this); -} - - -/** - calculates m_inc_x and m_inc_y for tabs - used for positioning the tabs. -*/ -void Tab::calcIncrease() { - Tab *tab; - int inc_x = 0, inc_y = 0; - unsigned int i = 0, tabs = numObjects(); - - if (m_win->getScreen()->getTabPlacement() == PTOP || - m_win->getScreen()->getTabPlacement() == PBOTTOM || - m_win->isShaded()) { - inc_y = 0; - - switch(m_win->getScreen()->getTabAlignment()) { - case ALEFT: - inc_x = m_size_w; - break; - case ACENTER: - inc_x = m_size_w; - break; - case ARIGHT: - inc_x = -m_size_w; - break; - case ARELATIVE: - inc_x = calcRelativeWidth(); - break; - default: - break; - } - } else if (m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) { - inc_x = 0; - - switch(m_win->getScreen()->getTabAlignment()) { - case ALEFT: - inc_y = -m_size_h; - break; - case ACENTER: - inc_y = m_size_h; - break; - case ARIGHT: - inc_y = m_size_h; - break; - case ARELATIVE: - inc_y = calcRelativeHeight(); - break; - default: - break; - } - } - - for (tab = getFirst(this); tab!=0; tab = tab->m_next, i++) { - - //TODO: move this out from here? - if ((m_win->getScreen()->getTabPlacement() == PTOP || - m_win->getScreen()->getTabPlacement() == PBOTTOM || - m_win->isShaded()) && - m_win->getScreen()->getTabAlignment() == ARELATIVE) { - if (!((m_win->getWidth() + - m_win->getScreen()->getBorderWidth2x()) % tabs) || - i >= ((m_win->getWidth() + - m_win->getScreen()->getBorderWidth2x()) % tabs)) { - tab->setTabWidth(inc_x); - tab->m_inc_x = inc_x; - } else { // adding 1 extra pixel to get tabs like win width - tab->setTabWidth(inc_x + 1); - tab->m_inc_x = inc_x + 1; - } - tab->m_inc_y = inc_y; - } else if (m_win->getScreen()->getTabAlignment() == ARELATIVE) { - if (!((m_win->getHeight() + - m_win->getScreen()->getBorderWidth2x()) % tabs) || - i >= ((m_win->getHeight() + - m_win->getScreen()->getBorderWidth2x()) % tabs)) { - - tab->setTabHeight(inc_y); - tab->m_inc_y = inc_y; - } else { - // adding 1 extra pixel to get tabs match window width - tab->setTabHeight(inc_y + 1); - tab->m_inc_y = inc_y + 1; - } - tab->m_inc_x = inc_x; - } else { // non relative modes - tab->m_inc_x = inc_x; - tab->m_inc_y = inc_y; - } - } -} - -/** - Handle button press event here. -*/ -void Tab::buttonPressEvent(XButtonEvent *be) { - //draw in pressed mode - draw(true); - - //invoke root menu with auto-tab? - /* if (be->button == 3) { - BScreen *screen = m_win->getScreen(); - Rootmenu *rootmenu = screen->getRootmenu(); - if (! rootmenu->isVisible()) { - Fluxbox::instance()->checkMenu(); - screen->getRootmenu()->move(be->x_root, be->y_root-rootmenu->titleHeight()); - rootmenu->setAutoGroupWindow(m_win->getClientWindow()); - rootmenu->show(); - } - } - - //otherwise let the window handle the event - else { - //set window to titlewindow so we can take advantage of drag function - be->window = m_win->frame().titlebar().window(); - - //call windows buttonpress eventhandler - m_win->buttonPressEvent(*be); - } - */ -} - -/** - Handle button release event here. - If tab is dropped then it should try to find - the window where the tab where dropped. -*/ -void Tab::buttonReleaseEvent(XButtonEvent *be) { - - if (m_moving) { - - m_moving = false; - - //erase tabmoving rectangle - XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), - m_win->getScreen()->getOpGC(), - m_move_x, m_move_y, - m_size_w, m_size_h); - - Fluxbox::instance()->ungrab(); - XUngrabPointer(m_display, CurrentTime); - - //storage of window and pos of window where we dropped the tab - Window child; - int dest_x = 0, dest_y = 0; - - //find window on coordinates of buttonReleaseEvent - if (XTranslateCoordinates(m_display, m_win->getScreen()->getRootWindow(), - m_win->getScreen()->getRootWindow(), - be->x_root, be->y_root, &dest_x, &dest_y, &child)) { - - Tab *tab = Fluxbox::instance()->searchTab(child); - FluxboxWindow *win = Fluxbox::instance()->searchWindow(child); - if(win!=0 && m_win->getScreen()->isSloppyWindowGrouping()) - win->setTab(true); - //search tablist for a tabwindow - if ( (tab!=0) || (m_win->getScreen()->isSloppyWindowGrouping() && - (win!=0) && (tab = win->getTab())!=0)) { - - if (tab == this) // inserting ourself to ourself causes a disconnect - return; - - // do only attach a hole chain if we dropped the - // first tab in the dropped chain... - if (m_prev) - disconnect(); - - // attach this tabwindow chain to the tabwindow chain we found. - tab->insert(this); - - } else { //Dropped nowhere - disconnect(); - - // convenience - unsigned int placement = m_win->getScreen()->getTabPlacement(); - - // (ab)using dest_x and dest_y - dest_x = be->x_root; - dest_y = be->y_root; - - if (placement == PTOP || placement == PBOTTOM || m_win->isShaded()) { - if (placement == PBOTTOM && !m_win->isShaded()) - dest_y -= m_win->getHeight(); - else if (placement != PTOP && m_win->isShaded()) - dest_y -= m_win->getTitleHeight(); - else // PTOP - dest_y += m_win->getTitleHeight(); - - switch(m_win->getScreen()->getTabAlignment()) { - case ACENTER: - dest_x -= (m_win->getWidth() / 2) - (m_size_w / 2); - break; - case ARIGHT: - dest_x -= m_win->getWidth() - m_size_w; - break; - default: - break; - } - - } else { // PLEFT & PRIGHT - if (placement == PRIGHT) - dest_x = be->x_root - m_win->getWidth(); - - switch(m_win->getScreen()->getTabAlignment()) { - case ACENTER: - dest_y -= (m_win->getHeight() / 2) - (m_size_h / 2); - break; - case ALEFT: - dest_y -= m_win->getHeight() - m_size_h; - break; - default: - break; - } - } - //TODO: this causes an calculate increase event, even if we - // only are moving a window - m_win->moveResize(dest_x, dest_y, m_win->getWidth(), m_win->getHeight()); - - if(!Fluxbox::instance()->useTabs()) - m_win->setTab(false);//Remove tab from window, as it is now alone... - } - } - } else { - - //raise this tabwindow - raise(); - - //set window to title window soo we can use m_win handler for menu - be->window = m_win->frame().titlebar().window(); - - //call windows buttonrelease event handler so it can popup a menu if needed - m_win->buttonReleaseEvent(*be); - } - -} - -//------------- exposeEvent ------------ -// Handle expose event here. -// Draws the tab unpressed -//-------------------------------------- -void Tab::exposeEvent(XExposeEvent *ee) { - draw(false); -} - -//----------- motionNotifyEvent -------- -// Handles motion event here -// Draws the rectangle of moving tab -//-------------------------------------- -void Tab::motionNotifyEvent(XMotionEvent *me) { - - Fluxbox *fluxbox = Fluxbox::instance(); - - //if mousebutton 2 is pressed - if (me->state & Button2Mask) { - if (!m_moving) { - m_moving = true; - - XGrabPointer(m_display, me->window, False, Button2MotionMask | - ButtonReleaseMask, GrabModeAsync, GrabModeAsync, - None, fluxbox->getMoveCursor(), CurrentTime); - - fluxbox->grab(); - - m_move_x = me->x_root - 1; - m_move_y = me->y_root - 1; - - XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), - m_win->getScreen()->getOpGC(), - m_move_x, m_move_y, - m_size_w, m_size_h); - - } else { - - int dx = me->x_root - 1, dy = me->y_root - 1; - - dx -= m_win->getScreen()->getBorderWidth(); - dy -= m_win->getScreen()->getBorderWidth(); - - if (m_win->getScreen()->getEdgeSnapThreshold()) { - int drx = m_win->getScreen()->getWidth() - (dx + 1); - - if (dx > 0 && dx < drx && dx < m_win->getScreen()->getEdgeSnapThreshold()) - dx = 0; - else if (drx > 0 && drx < m_win->getScreen()->getEdgeSnapThreshold()) - dx = m_win->getScreen()->getWidth() - 1; - - int dtty, dbby, dty, dby; - - dty = dy - dtty; - dby = dbby - (dy + 1); - - if (dy > 0 && dty < m_win->getScreen()->getEdgeSnapThreshold()) - dy = dtty; - else if (dby > 0 && dby < m_win->getScreen()->getEdgeSnapThreshold()) - dy = dbby - 1; - - } - - //erase rectangle - XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), - m_win->getScreen()->getOpGC(), - m_move_x, m_move_y, - m_size_w, m_size_h); - - //redraw rectangle at new pos - m_move_x = dx; - m_move_y = dy; - XDrawRectangle(m_display, m_win->getScreen()->getRootWindow(), - m_win->getScreen()->getOpGC(), - m_move_x, m_move_y, - m_size_w, m_size_h); - - } - } -} - -//-------------- getFirst() --------- -// Returns the first Tab in the chain -// of currentchain. -//----------------------------------- -Tab *Tab::getFirst(Tab *current) { - if (!current) - return 0; - - Tab *i=current; - - for (; i->m_prev != 0; i = i->m_prev); - return i; -} - -//-------------- getLast() --------- -// Returns the last Tab in the chain -// of currentchain. -//----------------------------------- -Tab *Tab::getLast(Tab *current) { - if (!current) - return 0; - Tab *i=current; - - for (; i->m_next != 0; i = i->m_next); - return i; -} - -//-------------- insert ------------ -// (private) -// Inserts a tab in the chain -//---------------------------------- -void Tab::insert(Tab *tab) { - - if (!tab || tab == this) //dont insert if the tab = 0 or the tab = this - return; - - Tab *first = getFirst(this); - - //if the tab already in chain then disconnect it - for (; first!=0; first = first->m_next) { - if (first==tab) { -#ifdef DEBUG - cerr<<"Tab already in chain. Disconnecting!"<<endl; -#endif // DEBUG - tab->disconnect(); - break; - } - } - - //get last tab in the chain to be inserted - Tab *last = tab; - for (; last->m_next!=0; last=last->m_next); - //do sticky before we connect it to the chain - //sticky bit on window - if (m_win->isStuck() != tab->m_win->isStuck()) { - tab->m_win->stuck = !m_win->stuck; // it will toggle - tab->stick(); //this will set all the m_wins in the list - } - - //connect the tab to this chain - - if (m_next) - m_next->m_prev = last; - tab->m_prev = this; - last->m_next = m_next; - - m_next = tab; - - bool resize_tabs = false; - - //TODO: cleanup and optimize - //move and resize all windows in the tablist we inserted - //only from first tab of the inserted chain to the last - for (; tab!=last->m_next; tab=tab->m_next) { - if (m_win->isShaded() != tab->m_win->isShaded()) { - tab->m_stoptabs = true; // we don't want any actions performed on the - // tabs, just the tab windows! - if (m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) - resize_tabs = true; - - // if the window we are grouping to, we need to shade the tab window - // _after_ reconfigure - if(m_win->isShaded()) { - tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), - m_win->getWidth(), m_win->getHeight()); - tab->m_win->shade(); - } else { - tab->m_win->shade(); // switch to correct shade state - tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), - m_win->getWidth(), m_win->getHeight()); - } - - tab->m_stoptabs = false; - - // both window have the same shaded state and have different sizes, - // checking this so that I'll only do shade on windows if configure did - // anything. - } else if ((m_win->getWidth() != tab->m_win->getWidth()) || - (m_win->getHeight() != tab->m_win->getHeight())) { - - tab->m_win->moveResize(m_win->getXFrame(), m_win->getYFrame(), - m_win->getWidth(), m_win->getHeight()); - - // need to shade the tab window as configure will mess it up - if (m_win->isShaded()) - tab->m_win->shade(); - } - } - - // resize if in relative mode or resize_tabs is true - if(m_win->getScreen()->getTabAlignment() == ARELATIVE || - resize_tabs) { - resizeGroup(); - calcIncrease(); - } - // reposition tabs - setPosition(); -} - -//---------- disconnect() -------------- -// Disconnects the tab from any chain -//-------------------------------------- -void Tab::disconnect() { - Tab *tmp = 0; - - Fluxbox *fluxbox = Fluxbox::instance(); - if (m_prev) { //if this have a chain to "the left" (previous tab) then set it's next to this next - m_prev->m_next = m_next; - if(!m_next && !fluxbox->useTabs())//Only two tabs in list, remove tab from remaining window - m_prev->m_win->setTab(false); - else - tmp = m_prev; - } - if (m_next) { //if this have a chain to "the right" (next tab) then set it's prev to this prev - m_next->m_prev = m_prev; - if(!m_prev && !fluxbox->useTabs())//Only two tabs in list, remove tab from remaining window - m_next->m_win->setTab(false); - else - tmp = m_next; - } - - //mark as no chain, previous and next. - m_prev = 0; - m_next = 0; - - //reposition the tabs - if (tmp) { - if (m_win->getScreen()->getTabAlignment() == ARELATIVE) - tmp->calcIncrease(); - tmp->setPosition(); - } - - if (m_win->getScreen()->getTabAlignment() == ARELATIVE) - calcIncrease(); - - setPosition(); -} - -// ------------ setTabWidth -------------- -// Sets Tab width _including_ borders -// --------------------------------------- -void Tab::setTabWidth(unsigned int w) { - if (w > m_win->getScreen()->getWindowStyle()->tab.border_width_2x && - w != m_size_w) { - m_size_w = w; - XResizeWindow(m_display, m_tabwin, - m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, - m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x); - - loadTheme(); // rerender themes to right size - focus(); // redraw the window - } -} - -// ------------ setTabHeight --------- -// Sets Tab height _including_ borders -// --------------------------------------- -void Tab::setTabHeight(unsigned int h) { - if (h > m_win->getScreen()->getWindowStyle()->tab.border_width_2x && - h != m_size_h) { - m_size_h = h; - XResizeWindow(m_display, m_tabwin, - m_size_w - m_win->getScreen()->getWindowStyle()->tab.border_width_2x, - m_size_h - m_win->getScreen()->getWindowStyle()->tab.border_width_2x); - - loadTheme(); // rerender themes to right size - focus(); // redraw the window - } -} - -// ------------ resizeGroup -------------- -// This function is used when (un)shading -// to get right size/width of tabs when -// PLeft || PRight && isTabRotateVertical -// --------------------------------------- -void Tab::resizeGroup() { - - Tab *first; - for (first = getFirst(this); first != 0; first = first->m_next) { - if ((m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) && - m_win->getScreen()->isTabRotateVertical() && - !m_win->isShaded()) { - first->setTabWidth(m_win->getScreen()->getTabHeight()); - first->setTabHeight(m_win->getScreen()->getTabWidth()); - } else { - first->setTabWidth(m_win->getScreen()->getTabWidth()); - first->setTabHeight(m_win->getScreen()->getTabHeight()); - } - //TODO: do I have to set this all the time? - first->m_configured = true; //used in Fluxbox::reconfigure() - } -} - -//------------- calcRelativeWidth -------- -// Returns: Calculated width for relative -// alignment -//---------------------------------------- -unsigned int Tab::calcRelativeWidth() { - unsigned int num=0; - //calculate num objs in list (extract this to a function?) - for (Tab *first=getFirst(this); first!=0; first=first->m_next, num++); - - return ((m_win->getWidth() + m_win->getScreen()->getBorderWidth2x())/num); -} - -/** - Returns the number of objects in - the TabGroup. -*/ -unsigned int Tab::numObjects() { - unsigned int num = 0; - for (Tab *tab = getFirst(this); tab != 0; tab = tab->m_next, num++); - return num; -} - -/** - Returns: Calculated height for relative - alignment -*/ -unsigned int Tab::calcRelativeHeight() { - return ((m_win->getHeight() + - m_win->getScreen()->getBorderWidth2x())/numObjects()); -} - -//------------- calcCenterXPos ----------- -// Returns: Calculated x position for -// centered alignment -//---------------------------------------- -unsigned int Tab::calcCenterXPos() { - return (m_win->getXFrame() + ((m_win->getWidth() - - (m_size_w * numObjects())) / 2)); -} - -//------------- calcCenterYPos ----------- -// Returns: Calculated y position for -// centered alignment -//---------------------------------------- -unsigned int Tab::calcCenterYPos() { - return (m_win->getYFrame() + ((m_win->getHeight() - - (m_size_h * numObjects())) / 2)); -} - - -//------- getTabPlacementString ---------- -// Returns the tabplacement string of the -// tabplacement number on success else 0. -//---------------------------------------- -const char *Tab::getTabPlacementString(Tab::Placement placement) { - for (int i=0; i<(PNONE / 5); i++) { - if (m_tabplacementlist[i] == placement) - return m_tabplacementlist[i].string; - } - return 0; -} - -//------- getTabPlacementNum ------------- -// Returns the tabplacement number of the -// tabplacement string on success else -// the type none on failure. -//---------------------------------------- -Tab::Placement Tab::getTabPlacementNum(const char *string) { - for (int i=0; i<(PNONE / 5); i ++) { - if (m_tabplacementlist[i] == string) { - return static_cast<Tab::Placement>(m_tabplacementlist[i].tp); - } - } - return PNONE; -} - -//------- getTabAlignmentString ---------- -// Returns the tabplacement string of the -// tabplacement number on success else 0. -//---------------------------------------- -const char *Tab::getTabAlignmentString(Tab::Alignment alignment) { - for (int i=0; i<ANONE; i++) { - if (m_tabalignmentlist[i] == alignment) - return m_tabalignmentlist[i].string; - } - return 0; -} - -//------- getTabAlignmentNum ------------- -// Returns the tabplacement number of the -// tabplacement string on success else -// the type none on failure. -//---------------------------------------- -Tab::Alignment Tab::getTabAlignmentNum(const char *string) { - for (int i=0; i<ANONE; i++) { - if (m_tabalignmentlist[i] == string) { - return static_cast<Tab::Alignment>(m_tabalignmentlist[i].tp); - } - } - return ANONE; -} - -//---------- addWindowToGroup ------------ -// Add a window the the tabbed group -//---------------------------------------- -bool Tab::addWindowToGroup(FluxboxWindow *otherWindow) -{ - if (!otherWindow || otherWindow == m_win) - return false; - Tab *otherTab = otherWindow->getTab(); - if (!otherTab) - return false; - insert(otherTab); - return true; -}
D
src/Tab.hh
@@ -1,151 +0,0 @@
-// Tab.hh for Fluxbox Window Manager -// Copyright (c) 2001-2002 Henrik Kinnunen (fluxgen@linuxmail.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -// $Id: Tab.hh,v 1.18 2003/04/09 17:20:03 rathnor Exp $ - -#ifndef TAB_HH -#define TAB_HH - -#include <X11/Xlib.h> -#include <strings.h> -//class FluxboxWindow; -#include "Window.hh" -/** -Note: Tab is a friend of FluxboxWindow -*/ -class Tab { -public: - enum Placement{ PTOP = 0, PBOTTOM = 5, PLEFT = 10, PRIGHT = 15, PNONE = 20}; - enum Alignment{ ALEFT = 0, ACENTER, ARIGHT, ARELATIVE, ANONE }; - - Tab(FluxboxWindow *win, Tab *prev=0, Tab *next=0); - ~Tab(); - - void setConfigured(bool value) { m_configured = value; } - Tab *next() { return m_next; } - Tab *prev() { return m_prev; } - Tab *last() { return getLast(this); } - Tab *first() { return getFirst(this); } - FluxboxWindow *getWindow() { return m_win; } - - void focus(); - void decorate(); - void deiconify(); - void iconify(); - void raise(); - void lower(); - void withdraw(); - void stick(); - void resize(); - void shade(); - void setPosition(); //position tab to follow (FluxboxWindow *) m_win - void moveNext(); - void movePrev(); - void insert(Tab *next); - - //event handlers - void buttonReleaseEvent(XButtonEvent *be); - void buttonPressEvent(XButtonEvent *be); - void exposeEvent(XExposeEvent *ee); - void motionNotifyEvent(XMotionEvent *me); - - void disconnect(); - - //accessors - - static const char *getTabPlacementString(Tab::Placement placement); - static Tab::Placement getTabPlacementNum(const char *string); - static const char *getTabAlignmentString(Tab::Alignment alignment); - static Tab::Alignment getTabAlignmentNum(const char *string); - - const Tab *next() const { return m_next; } - const Tab *prev() const { return m_prev; } - const Tab *last() const { return getLast(const_cast<Tab *>(this)); } - const Tab *first() const { return getFirst(const_cast<Tab *>(this)); } - - const FluxboxWindow *getWindow() const { return m_win; } - Window getTabWindow() const { return m_tabwin; } - unsigned int getTabWidth() const { return m_size_w; } - unsigned int getTabHeight() const { return m_size_h; } - - void resizeGroup(); // used when (un)shading windows - void calcIncrease(); - bool configured() const { return m_configured; } - void draw(bool pressed) const; - - bool addWindowToGroup(FluxboxWindow *window); - - static Tab *getFirst(Tab *current); - static Tab *getLast(Tab *current); - -private: - - bool m_configured; - - - //The size of the tab - unsigned int m_size_w; - unsigned int m_size_h; - //Increasements - int m_inc_x; - int m_inc_y; - static const int m_max_tabs; - bool m_focus, m_moving; // moving and focus - void createTabWindow(); // creates the X win of tab - void loadTheme(); // loads the textures with right width and height - int setPositionShadingHelper(bool shaded); - int setPositionTBAlignHelper(Alignment align); - int setPositionLRAlignHelper(Alignment align); - void setTabWidth(unsigned int w); - void setTabHeight(unsigned int h); - unsigned int numObjects(); - unsigned int calcRelativeWidth(); - unsigned int calcRelativeHeight(); - unsigned int calcCenterXPos(); - unsigned int calcCenterYPos(); - int m_move_x, m_move_y; // Move coordinates, holds moving coordinates when draging - Tab *m_prev; - Tab *m_next; - FluxboxWindow *m_win; - Window m_tabwin; - Display *m_display; - Pixmap m_focus_pm, m_unfocus_pm; - unsigned long m_focus_pixel, m_unfocus_pixel; - static bool m_stoptabs; //used to "freeze" the tabs functions - - struct t_tabplacementlist{ - int tp; - const char *string; - inline bool operator == (int p) { - return (tp==p); - } - inline bool operator == (const char *str) { - if (strcasecmp(string, str) == 0) - return true; - return false; - } - }; - static t_tabplacementlist m_tabplacementlist[]; - static t_tabplacementlist m_tabalignmentlist[]; - -}; - -#endif //TAB_HH