LOGIN / SIGN UP
2 Author: Claes Nästén
Date: Sun Nov 01 23:37:08 +0100 2009
Subject: Preserve ordering between restarts, ref #202
    Two new atoms were introduces to keep track of the ordering within Frames
    _PEKWM_FRAME_ORDER and which client is the active one _PEKWM_FRAME_ACTIVE.
    
    Restart tests on my PC seems to be working ok.

src/Frame.cc
 
407 @@ -407,13 +407,32 @@
407
408 //! @brief Adds child to the frame.
409 void
410 Frame::addChild (PWinObj *child)
411 Frame::addChild (PWinObj *child, std::list<PWinObj*>::iterator *it)
412 {
413 PDecor::addChild(child);
414 PDecor::addChild(child, it);
415 AtomUtil::setLong(child->getWindow(), Atoms::getAtom(PEKWM_FRAME_ID), _id);
416 child->lower();
417 }
418
419 /**
420 * Add child preserving order from the previous pekwm run.
421 */
422 void
423 Frame::addChildOrdered (Client *child)
424 {
425 Client *client;
426
427 list<PWinObj*>::iterator it(_child_list.begin());
428 for (; it != _child_list.end(); ++it) {
429 client = static_cast<Client*>(*it);
430 if (child->getInitialFrameOrder() < client->getInitialFrameOrder()) {
431 break;
432 }
433 }
434
435 addChild(child, &it);
436 }
437
438 //! @brief Removes child from the frame.
439 void
440 Frame::removeChild (PWinObj *child, bool do_delete)
...  
476 @@ -457,21 +476,29 @@
476 Workspaces::instance()->updateClientStackingList(true, true);
477 }
478
460 //! @brief
480 /**
481 * Called when child order is updated, re-sets the titles and updates
482 * the _PEKWM_FRAME hints.
483 */
484 void
485 Frame::updatedChildOrder(void)
486 {
487 titleClear();
488
489 Client *client;
490 list<PWinObj*>::iterator it(_child_list.begin());
472 for (; it != _child_list.end(); ++it) {
473 titleAdd(static_cast<Client*>(*it)->getTitle());
493 for (long num = 0; it != _child_list.end(); ++num, ++it) {
494 client = static_cast<Client*>(*it);
495 client->setPekwmFrameOrder(num);
496 titleAdd(client->getTitle());
497 }
498
499 updatedActiveChild();
500 }
501
483 //! @brief
503 /**
504 * Set the active title and update the _PEKWM_FRAME hints.
505 */
506 void
507 Frame::updatedActiveChild(void)
508 {
...  
506 @@ -479,9 +506,9 @@
506
507 list<PWinObj*>::iterator it(_child_list.begin());
508 for (uint i = 0; it != _child_list.end(); ++i, ++it) {
509 static_cast<Client*>(*it)->setPekwmFrameActive(_child == *it);
510 if (_child == *it) {
511 titleSetActive(i);
485 break;
513 }
514 }
515
...  

src/Client.cc
 
187 @@ -187,6 +187,7 @@
187 // don't want to spread the giveInputFocuses
188 bool do_focus = is_new ? Config::instance()->isFocusNew() : false;
189 bool do_autogroup = true;
190 bool is_active = getPekwmFrameActive();
191
192 // If pekwm is already running, check against autoproperty then
193 // tagged frame. If starting up, check if it has a FRAME_ID and if not
...  
213 @@ -212,8 +213,10 @@
213 _parent = Frame::findFrameFromID(id);
214 if (_parent) {
215 Frame *frame = static_cast<Frame*>(_parent);
215 frame->addChild(this);
216 frame->activateChild(this);
218 frame->addChildOrdered(this);
219 if (is_active) {
220 frame->activateChild(this);
221 }
222 do_focus = frame->isFocused();
223 }
224 }
...  
855 @@ -852,6 +855,8 @@
855 if (AtomUtil::getString(_window, Atoms::getAtom(PEKWM_TITLE), str)) {
856 _title.setUser(Util::to_wide_str(str));
857 }
858
859 _state.initial_frame_order = getPekwmFrameOrder();
860 }
861
862 //! @brief Read _NET_WM_ICON from client window.
...  
1670 @@ -1665,3 +1670,44 @@
1670 delete _strut;
1671 _strut = 0;
1672 }
1673
1674 /**
1675 * Get _PEKWM_FRAME_ORDER hint from client, return < 0 on failure.
1676 */
1677 long
1678 Client::getPekwmFrameOrder(void)
1679 {
1680 long num = -1;
1681 AtomUtil::getLong(_window, Atoms::getAtom(PEKWM_FRAME_ORDER), num);
1682 return num;
1683 }
1684
1685 /**
1686 * Update _PEKWM_FRAME_ORDER hint on client window.
1687 */
1688 void
1689 Client::setPekwmFrameOrder(long num)
1690 {
1691 AtomUtil::setLong(_window, Atoms::getAtom(PEKWM_FRAME_ORDER), num);
1692 }
1693
1694 /**
1695 * Get _PEKWM_FRAME_ACTIVE hint from client window, return true if
1696 * client is treated as active.
1697 */
1698 bool
1699 Client::getPekwmFrameActive(void)
1700 {
1701 long act = 0;
1702 return (AtomUtil::getLong(_window, Atoms::getAtom(PEKWM_FRAME_ACTIVE), act)
1703 && act == 1);
1704 }
1705
1706 /**
1707 * Set _PEKWM_FRAME_ACTIVE hint on client window.
1708 */
1709 void
1710 Client::setPekwmFrameActive(bool act)
1711 {
1712 AtomUtil::setLong(_window, Atoms::getAtom(PEKWM_FRAME_ACTIVE), act ? 1 : 0);
1713 }
...  

src/Client.hh
 
158 @@ -158,6 +158,7 @@
158 inline bool isShaded(void) const { return _state.shaded; }
159 inline bool isFullscreen(void) const { return _state.fullscreen; }
160 inline bool isPlaced(void) const { return _state.placed; }
161 inline uint getInitialFrameOrder(void) const { return _state.initial_frame_order; }
162 inline uint getSkip(void) const { return _state.skip; }
163 inline bool isSkip(Skip skip) const { return (_state.skip&skip); }
164 inline uint getDecorState(void) const { return _state.decor; }
...  
260 @@ -259,6 +260,11 @@
260 void readName(void);
261 void readIconName(void);
262 void removeStrutHint(void);
263
264 long getPekwmFrameOrder(void);
265 void setPekwmFrameOrder(long num);
266 bool getPekwmFrameActive(void);
267 void setPekwmFrameActive(bool active);
268
269 private:
270 bool titleApplyRule(std::wstring &wtitle);
...  
333 @@ -327,7 +333,8 @@
333 public:
334 State(void)
335 : maximized_vert(false), maximized_horz(false), shaded(false), fullscreen(false),
330 placed(false), skip(0), decor(DECOR_TITLEBAR|DECOR_BORDER),
337 placed(false), initial_frame_order(0),
338 skip(0), decor(DECOR_TITLEBAR|DECOR_BORDER),
339 cfg_deny(CFG_DENY_NO), demands_attention(true) { }
340 ~State(void) { }
341
...  
344 @@ -337,6 +344,7 @@
344
345 // pekwm states
346 bool placed;
347 uint initial_frame_order; /**< Initial frame position */
348 uint skip, decor, cfg_deny;
349 bool demands_attention; /**< If true, the client requires attention from the user. */
350 } _state;
...