news download themes documentation links










Gnome.cc

00001 // Gnome.cc for fluxbox
00002 // Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
00003 //
00004 // Permission is hereby granted, free of charge, to any person obtaining a
00005 // copy of this software and associated documentation files (the "Software"),
00006 // to deal in the Software without restriction, including without limitation
00007 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 // and/or sell copies of the Software, and to permit persons to whom the
00009 // Software is furnished to do so, subject to the following conditions:
00010 //
00011 // The above copyright notice and this permission notice shall be included in
00012 // all copies or substantial portions of the Software.
00013 //
00014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020 // DEALINGS IN THE SOFTWARE.
00021 
00022 // $Id: Gnome.cc,v 1.32 2003/10/02 16:14:41 rathnor Exp $
00023 
00024 #include "Gnome.hh"
00025 
00026 #include "fluxbox.hh"
00027 #include "Window.hh"
00028 #include "Screen.hh"
00029 #include "WinClient.hh"
00030 #include "Workspace.hh"
00031 
00032 #include <iostream>
00033 #include <new>
00034 using namespace std;
00035 
00036 Gnome::Gnome() {
00037     createAtoms();
00038     enableUpdate();
00039 }
00040 
00041 Gnome::~Gnome() {
00042     // destroy gnome windows
00043     while (!m_gnomewindows.empty()) {
00044         XDestroyWindow(FbTk::App::instance()->display(), m_gnomewindows.back());
00045         m_gnomewindows.pop_back();      
00046     }
00047 }
00048 
00049 
00050 void Gnome::initForScreen(BScreen &screen) {
00051     Display *disp = FbTk::App::instance()->display();
00052     // create the GNOME window
00053     Window gnome_win = XCreateSimpleWindow(disp,
00054                                            screen.rootWindow().window(), 0, 0, 5, 5, 0, 0, 0);
00055     // supported WM check
00056     screen.rootWindow().changeProperty(m_gnome_wm_supporting_wm_check, 
00057                                        XA_CARDINAL, 32, 
00058                                        PropModeReplace, (unsigned char *) &gnome_win, 1);
00059 
00060     XChangeProperty(disp, gnome_win, 
00061                     m_gnome_wm_supporting_wm_check, 
00062                     XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &gnome_win, 1);
00063 
00064     // supported gnome atoms
00065     Atom gnomeatomlist[] = {
00066         m_gnome_wm_supporting_wm_check,
00067         m_gnome_wm_win_workspace_names,
00068         m_gnome_wm_win_client_list,
00069         m_gnome_wm_win_state,
00070         m_gnome_wm_win_hints,
00071         m_gnome_wm_win_layer
00072     };
00073     //list atoms that we support
00074     screen.rootWindow().changeProperty(m_gnome_wm_prot, 
00075                                        XA_ATOM, 32, PropModeReplace,
00076                                        (unsigned char *)gnomeatomlist, 
00077                                        (sizeof gnomeatomlist)/sizeof gnomeatomlist[0]);
00078 
00079     m_gnomewindows.push_back(gnome_win);
00080 
00081     updateClientList(screen);
00082     updateWorkspaceNames(screen);
00083     updateWorkspaceCount(screen);
00084     updateCurrentWorkspace(screen);
00085     
00086 }
00087 
00088 void Gnome::setupFrame(FluxboxWindow &win) {
00089     // load gnome state (take queues from the main window of the frame)
00090     Display *disp = FbTk::App::instance()->display();
00091     Atom ret_type;
00092     int fmt;
00093     unsigned long nitems, bytes_after;
00094     long flags, *data = 0;
00095 
00096     if (win.winClient().property(m_gnome_wm_win_state, 0, 1, False, XA_CARDINAL, 
00097                                  &ret_type, &fmt, &nitems, &bytes_after, 
00098                                  (unsigned char **) &data) && data) {
00099         flags = *data;
00100         setState(&win, flags);
00101         XFree (data);
00102     } else {
00103         updateState(win);
00104     }
00105 
00106     // load gnome layer atom
00107     if (XGetWindowProperty(disp, win.clientWindow(), 
00108                            m_gnome_wm_win_layer, 0, 1, False, XA_CARDINAL, 
00109                            &ret_type, &fmt, &nitems, &bytes_after, 
00110                            (unsigned char **) &data) ==  Success && data) {
00111         flags = *data;
00112         setLayer(&win, flags);
00113         XFree (data);
00114     } else {
00115         updateLayer(win);
00116     }
00117 
00118     // load gnome workspace atom
00119     if (XGetWindowProperty(disp, win.clientWindow(), 
00120                            m_gnome_wm_win_workspace, 0, 1, False, XA_CARDINAL, 
00121                            &ret_type, &fmt, &nitems, &bytes_after, 
00122                            (unsigned char **) &data) ==  Success && data) {
00123         unsigned int workspace_num = *data;
00124         if (win.workspaceNumber() != workspace_num) 
00125             win.screen().reassociateWindow(&win, workspace_num, false);
00126         XFree (data);
00127     } else {
00128         updateWorkspace(win);
00129     }
00130 
00131 }
00132 
00133 void Gnome::updateClientList(BScreen &screen) {
00134     size_t num=0;
00135 
00136     // count window clients in each workspace
00137     BScreen::Workspaces::const_iterator workspace_it = 
00138         screen.getWorkspacesList().begin();
00139     BScreen::Workspaces::const_iterator workspace_it_end = 
00140         screen.getWorkspacesList().end();
00141     for (; workspace_it != workspace_it_end; ++workspace_it) {
00142         Workspace::Windows::iterator win_it = 
00143             (*workspace_it)->windowList().begin();
00144         Workspace::Windows::iterator win_it_end = 
00145             (*workspace_it)->windowList().end();
00146         for (; win_it != win_it_end; ++win_it)
00147             num += (*win_it)->numClients();
00148     }
00149     
00150     Window *wl = new Window[num];
00151     if (wl == 0) {
00152         cerr<<"Fatal: Out of memory, can't allocate ("<<num*sizeof (Window)<<") for gnome client list"<<endl;
00153         return;
00154     }
00155 
00156     //add client windows to buffer
00157     workspace_it = screen.getWorkspacesList().begin();
00158     int win=0;
00159     for (; workspace_it != workspace_it_end; ++workspace_it) {
00160     
00161         // Fill in array of window ID's
00162         Workspace::Windows::const_iterator it = 
00163             (*workspace_it)->windowList().begin();
00164         Workspace::Windows::const_iterator it_end = 
00165             (*workspace_it)->windowList().end();        
00166         for (; it != it_end; ++it) {
00167             // TODO!
00168             //check if the window don't want to be visible in the list
00169             //if (! ( (*it)->getGnomeHints() & WIN_STATE_HIDDEN) ) {
00170             std::list<WinClient *>::iterator client_it = 
00171                 (*it)->clientList().begin();
00172             std::list<WinClient *>::iterator client_it_end = 
00173                 (*it)->clientList().end();
00174             for (; client_it != client_it_end; ++client_it)
00175                 wl[win++] = (*client_it)->window();
00176 
00177         }
00178     }
00179     //number of windows to show in client list
00180     num = win;
00181     screen.rootWindow().changeProperty(m_gnome_wm_win_client_list, 
00182                                        XA_CARDINAL, 32,
00183                                        PropModeReplace, (unsigned char *)wl, num);
00184     
00185     delete[] wl;
00186 }
00187 
00188 void Gnome::updateWorkspaceNames(BScreen &screen) {
00189 
00190     int number_of_desks = screen.getWorkspaceNames().size();
00191     const BScreen::WorkspaceNames &workspace_names = screen.getWorkspaceNames();
00192     // convert our desktop names to a char * so we can send it
00193     char *names[number_of_desks];       
00194     
00195     for (int i = 0; i < number_of_desks; i++) {     
00196         names[i] = new char[workspace_names[i].size() + 1];
00197         strcpy(names[i], workspace_names[i].c_str());
00198     }
00199 
00200     XTextProperty  text;    
00201     if (XStringListToTextProperty(names, number_of_desks, &text)) {
00202         XSetTextProperty(FbTk::App::instance()->display(), screen.rootWindow().window(),
00203              &text, m_gnome_wm_win_workspace_names);
00204         XFree(text.value);
00205     }
00206 
00207     // destroy name buffers
00208     for (int i = 0; i < number_of_desks; i++)
00209         delete [] names[i];
00210 }
00211 
00212 void Gnome::updateCurrentWorkspace(BScreen &screen) {
00213     int workspace = screen.currentWorkspaceID();
00214     screen.rootWindow().changeProperty(m_gnome_wm_win_workspace, XA_CARDINAL, 32, PropModeReplace,
00215                                        (unsigned char *)&workspace, 1);
00216 
00217     updateClientList(screen); // make sure the client list is updated too
00218 }
00219 
00220 void Gnome::updateWorkspaceCount(BScreen &screen) {
00221     int numworkspaces = screen.getCount();
00222     screen.rootWindow().changeProperty(m_gnome_wm_win_workspace_count, XA_CARDINAL, 32, PropModeReplace,
00223                                        (unsigned char *)&numworkspaces, 1);
00224 }
00225 
00226 void Gnome::updateWorkspace(FluxboxWindow &win) {
00227     int val = win.workspaceNumber();
00228     if (win.isStuck()) {
00229         val = -1;
00230     }
00231 #ifdef DEBUG
00232     cerr<<__FILE__<<"("<<__LINE__<<"): setting workspace("<<val<<
00233         ") for window("<<&win<<")"<<endl;
00234 #endif // DEBUG
00235 
00236     FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
00237     FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
00238     for (; client_it != client_it_end; ++client_it)
00239         (*client_it)->changeProperty(m_gnome_wm_win_workspace, 
00240                                        XA_CARDINAL, 32, PropModeReplace,
00241                                        (unsigned char *)&val, 1);
00242 }
00243 
00244 void Gnome::updateState(FluxboxWindow &win) {
00245     //translate to gnome win state
00246     int state=0;
00247     if (win.isStuck())
00248         state |= WIN_STATE_STICKY;
00249     if (win.isIconic())
00250         state |= WIN_STATE_MINIMIZED;
00251     if (win.isShaded())
00252         state |= WIN_STATE_SHADED;
00253     
00254     FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
00255     FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
00256     for (; client_it != client_it_end; ++client_it)
00257         (*client_it)->changeProperty(m_gnome_wm_win_state,
00258                                      XA_CARDINAL, 32, 
00259                                      PropModeReplace, (unsigned char *)&state, 1);
00260 }
00261 
00262 void Gnome::updateLayer(FluxboxWindow &win) {
00263     //TODO - map from flux layers to gnome ones
00264     // our layers are in the opposite direction to GNOME
00265     int layernum = Fluxbox::instance()->getDesktopLayer() - win.layerNum();
00266 
00267     FluxboxWindow::ClientList::iterator client_it = win.clientList().begin();
00268     FluxboxWindow::ClientList::iterator client_it_end = win.clientList().end();
00269     for (; client_it != client_it_end; ++client_it)
00270         (*client_it)->changeProperty(m_gnome_wm_win_layer,
00271                                      XA_CARDINAL, 32, PropModeReplace, 
00272                                      (unsigned char *)&layernum, 1);
00273     
00274 }
00275 
00276 void Gnome::updateHints(FluxboxWindow &win) {
00277     //TODO
00278     
00279 }
00280 
00281 bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) {
00282     if (ce.message_type == m_gnome_wm_win_workspace) {
00283 #ifdef DEBUG
00284         cerr<<__FILE__<<"("<<__LINE__<<"): Got workspace atom="<<ce.data.l[0]<<endl;
00285 #endif
00286         if ( winclient !=0 && // the message sent to client window?
00287              ce.data.l[0] >= 0 &&
00288              ce.data.l[0] < (signed)winclient->screen().getCount()) {
00289             winclient->screen().changeWorkspaceID(ce.data.l[0]);
00290                     
00291         } else if (screen!=0 && //the message sent to root window?
00292                    ce.data.l[0] >= 0 &&
00293                    ce.data.l[0] < (signed)screen->getCount())
00294             screen->changeWorkspaceID(ce.data.l[0]);
00295         return true;
00296     } else if (winclient == 0)
00297         return false; 
00298         
00299 
00300     if (ce.message_type == m_gnome_wm_win_state) {
00301 #ifdef DEBUG
00302         cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_STATE"<<endl;
00303 #endif // DEBUG
00304             
00305 #ifdef DEBUG
00306         cerr<<__FILE__<<"("<<__LINE__<<"): Mask of members to change:"<<
00307             hex<<ce.data.l[0]<<dec<<endl; // mask_of_members_to_change
00308         cerr<<"New members:"<<ce.data.l[1]<<endl;
00309 #endif // DEBUG
00310     
00311         if (winclient && winclient->fbwindow()) {
00312             //get new states            
00313             int flag = ce.data.l[0] & ce.data.l[1];
00314             //don't update this when when we set new state
00315             disableUpdate();
00316             // convert to Fluxbox state
00317             setState(winclient->fbwindow(), flag);
00318             // enable update of atom states
00319             enableUpdate();
00320         }
00321     } else if (ce.message_type == m_gnome_wm_win_hints) {
00322 #ifdef DEBUG
00323         cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_HINTS"<<endl;
00324 #endif // DEBUG
00325 
00326     } else if (ce.message_type == m_gnome_wm_win_layer) {
00327 #ifdef DEBUG
00328         cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_LAYER"<<endl;
00329 #endif // DEBUG
00330 
00331         if (winclient && winclient->fbwindow())
00332             setLayer(winclient->fbwindow(), ce.data.l[0]);
00333     } else
00334         return false; //the gnome atom wasn't found or not supported
00335 
00336     return true; // we handled the atom
00337 }
00338 
00339 void Gnome::setState(FluxboxWindow *win, int state) {
00340 #ifdef DEBUG
00341     cerr<<"Gnome: state=0x"<<hex<<state<<dec<<endl;
00342 #endif // DEBUG
00343 
00344     if (state & WIN_STATE_STICKY) {
00345 #ifdef DEBUG
00346         cerr<<"Gnome state: Sticky"<<endl;
00347 #endif // DEBUG
00348         if (!win->isStuck())
00349             win->stick();
00350     } else if (win->isStuck())
00351         win->stick();
00352             
00353     if (state & WIN_STATE_MINIMIZED) {
00354 #ifdef DEBUG
00355         cerr<<"Gnome state: Minimized"<<endl;
00356 #endif // DEBUG
00357         if (win->isIconic())
00358             win->iconify();
00359     } else if (win->isIconic())
00360         win->deiconify(true, true);
00361 
00362     if (state & WIN_STATE_SHADED) {
00363 #ifdef DEBUG
00364         cerr<<"Gnome state: Shade"<<endl;
00365 #endif // DEBUG
00366         if (!win->isShaded())
00367             win->shade();
00368     } else if (win->isShaded())
00369         win->shade();
00370 
00371     /* TODO 
00372        if (state & WIN_STATE_MAXIMIZED_VERT)
00373        cerr<<"Maximize Vert"<<endl;
00374        if (state & WIN_STATE_MAXIMIZED_HORIZ)
00375        cerr<<"Maximize Horiz"<<endl;
00376        if (state & WIN_STATE_HIDDEN)
00377        cerr<<"Hidden"<<endl;
00378        if (state & WIN_STATE_HID_WORKSPACE)
00379        cerr<<"HID Workspace"<<endl;
00380        if (state & WIN_STATE_HID_TRANSIENT)
00381        cerr<<"HID Transient"<<endl;
00382        if (state & WIN_STATE_FIXED_POSITION)
00383        cerr<<"Fixed Position"<<endl;
00384        if (state & WIN_STATE_ARRANGE_IGNORE)
00385        cerr<<"Arrange Ignore"<<endl;            
00386     */
00387 }
00388 
00389 void Gnome::setLayer(FluxboxWindow *win, int layer) {
00390     if (!win) return;
00391     
00392     
00393     switch (layer) {
00394     case WIN_LAYER_DESKTOP:
00395         layer = Fluxbox::instance()->getDesktopLayer();
00396         break;
00397     case WIN_LAYER_BELOW:
00398         layer = Fluxbox::instance()->getBottomLayer();
00399         break;
00400     case WIN_LAYER_NORMAL:
00401         layer = Fluxbox::instance()->getNormalLayer();
00402         break;      
00403     case WIN_LAYER_ONTOP:
00404         layer = Fluxbox::instance()->getTopLayer();
00405         break;
00406     case WIN_LAYER_DOCK:
00407         layer = Fluxbox::instance()->getDockLayer();
00408         break;
00409     case WIN_LAYER_ABOVE_DOCK:
00410         layer = Fluxbox::instance()->getAboveDockLayer();
00411         break;
00412     case WIN_LAYER_MENU:
00413         layer = Fluxbox::instance()->getMenuLayer();
00414         break;
00415     default:
00416         // our windows are in the opposite direction to gnome
00417         layer = Fluxbox::instance()->getDesktopLayer() - layer;
00418         break;
00419     }
00420     win->moveToLayer(layer);
00421 
00422 }
00423 
00424 void Gnome::createAtoms() {
00425     Display *disp = FbTk::App::instance()->display();
00426     m_gnome_wm_win_layer = XInternAtom(disp, "_WIN_LAYER", False);
00427     m_gnome_wm_win_state = XInternAtom(disp, "_WIN_STATE", False);
00428     m_gnome_wm_win_hints = XInternAtom(disp, "_WIN_HINTS", False);
00429     m_gnome_wm_win_app_state = XInternAtom(disp, "_WIN_APP_STATE", False);
00430     m_gnome_wm_win_expanded_size = XInternAtom(disp, "_WIN_EXPANDED_SIZE", False);
00431     m_gnome_wm_win_icons = XInternAtom(disp, "_WIN_ICONS", False);
00432     m_gnome_wm_win_workspace = XInternAtom(disp, "_WIN_WORKSPACE", False);
00433     m_gnome_wm_win_workspace_count = XInternAtom(disp, "_WIN_WORKSPACE_COUNT", False);
00434     m_gnome_wm_win_workspace_names = XInternAtom(disp, "_WIN_WORKSPACE_NAMES", False);
00435     m_gnome_wm_win_client_list = XInternAtom(disp, "_WIN_CLIENT_LIST", False);
00436     m_gnome_wm_prot = XInternAtom(disp, "_WIN_PROTOCOLS", False);
00437     m_gnome_wm_supporting_wm_check = XInternAtom(disp, "_WIN_SUPPORTING_WM_CHECK", False);
00438 }

Fluxbox CVS-Jan-2003




      



Got comments about the page? Send them to webmaster.
If you have general Fluxbox related questions ask them on our irc channel or mailing lists.

Show Source








Designed by aLEczapKA