Changeset View
Changeset View
Standalone View
Standalone View
layers.cpp
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | |||||
60 | them in the same layer. | 60 | them in the same layer. | ||
61 | 61 | | |||
62 | Most transients are in the same layer as their mainwindow, | 62 | Most transients are in the same layer as their mainwindow, | ||
63 | see Workspace::constrainedStackingOrder(), they may also be in higher layers, but | 63 | see Workspace::constrainedStackingOrder(), they may also be in higher layers, but | ||
64 | they should never be below their mainwindow. | 64 | they should never be below their mainwindow. | ||
65 | 65 | | |||
66 | When some client attribute changes (above/below flag, transiency...), | 66 | When some client attribute changes (above/below flag, transiency...), | ||
67 | Workspace::updateClientLayer() should be called in order to make | 67 | Workspace::updateClientLayer() should be called in order to make | ||
68 | sure it's moved to the appropriate layer ClientList if needed. | 68 | sure it's moved to the appropriate layer QList<X11Client *> if needed. | ||
69 | 69 | | |||
70 | Currently the things that affect client in which layer a client | 70 | Currently the things that affect client in which layer a client | ||
71 | belongs: KeepAbove/Keep Below flags, window type, fullscreen | 71 | belongs: KeepAbove/Keep Below flags, window type, fullscreen | ||
72 | state and whether the client is active, mainclient (transiency). | 72 | state and whether the client is active, mainclient (transiency). | ||
73 | 73 | | |||
74 | Make sure updateStackingOrder() is called in order to make | 74 | Make sure updateStackingOrder() is called in order to make | ||
75 | Workspace::stackingOrder() up to date and propagated to the world. | 75 | Workspace::stackingOrder() up to date and propagated to the world. | ||
76 | Using Workspace::blockStackingUpdates() (or the StackingUpdatesBlocker | 76 | Using Workspace::blockStackingUpdates() (or the StackingUpdatesBlocker | ||
Show All 37 Lines | |||||
114 | 114 | | |||
115 | void Workspace::updateStackingOrder(bool propagate_new_clients) | 115 | void Workspace::updateStackingOrder(bool propagate_new_clients) | ||
116 | { | 116 | { | ||
117 | if (block_stacking_updates > 0) { | 117 | if (block_stacking_updates > 0) { | ||
118 | if (propagate_new_clients) | 118 | if (propagate_new_clients) | ||
119 | blocked_propagating_new_clients = true; | 119 | blocked_propagating_new_clients = true; | ||
120 | return; | 120 | return; | ||
121 | } | 121 | } | ||
122 | ToplevelList new_stacking_order = constrainedStackingOrder(); | 122 | QList<Toplevel *> new_stacking_order = constrainedStackingOrder(); | ||
123 | bool changed = (force_restacking || new_stacking_order != stacking_order); | 123 | bool changed = (force_restacking || new_stacking_order != stacking_order); | ||
124 | force_restacking = false; | 124 | force_restacking = false; | ||
125 | stacking_order = new_stacking_order; | 125 | stacking_order = new_stacking_order; | ||
126 | if (changed || propagate_new_clients) { | 126 | if (changed || propagate_new_clients) { | ||
127 | propagateClients(propagate_new_clients); | 127 | propagateClients(propagate_new_clients); | ||
128 | emit stackingOrderChanged(); | 128 | emit stackingOrderChanged(); | ||
129 | if (m_compositor) { | 129 | if (m_compositor) { | ||
130 | m_compositor->addRepaintFull(); | 130 | m_compositor->addRepaintFull(); | ||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Line(s) | 158 | { | |||
206 | int pos = 0; | 206 | int pos = 0; | ||
207 | xcb_window_t *cl(nullptr); | 207 | xcb_window_t *cl(nullptr); | ||
208 | if (propagate_new_clients) { | 208 | if (propagate_new_clients) { | ||
209 | cl = new xcb_window_t[ manual_overlays.count() + desktops.count() + clients.count()]; | 209 | cl = new xcb_window_t[ manual_overlays.count() + desktops.count() + clients.count()]; | ||
210 | for (const auto win : manual_overlays) { | 210 | for (const auto win : manual_overlays) { | ||
211 | cl[pos++] = win; | 211 | cl[pos++] = win; | ||
212 | } | 212 | } | ||
213 | // TODO this is still not completely in the map order | 213 | // TODO this is still not completely in the map order | ||
214 | for (ClientList::ConstIterator it = desktops.constBegin(); it != desktops.constEnd(); ++it) | 214 | for (auto it = desktops.constBegin(); it != desktops.constEnd(); ++it) | ||
215 | cl[pos++] = (*it)->window(); | 215 | cl[pos++] = (*it)->window(); | ||
216 | for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it) | 216 | for (auto it = clients.constBegin(); it != clients.constEnd(); ++it) | ||
217 | cl[pos++] = (*it)->window(); | 217 | cl[pos++] = (*it)->window(); | ||
218 | rootInfo()->setClientList(cl, pos); | 218 | rootInfo()->setClientList(cl, pos); | ||
219 | delete [] cl; | 219 | delete [] cl; | ||
220 | } | 220 | } | ||
221 | 221 | | |||
222 | cl = new xcb_window_t[ manual_overlays.count() + stacking_order.count()]; | 222 | cl = new xcb_window_t[ manual_overlays.count() + stacking_order.count()]; | ||
223 | pos = 0; | 223 | pos = 0; | ||
224 | for (ToplevelList::ConstIterator it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { | 224 | for (auto it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) { | ||
225 | if ((*it)->isClient()) | 225 | if ((*it)->isClient()) | ||
226 | cl[pos++] = (*it)->window(); | 226 | cl[pos++] = (*it)->window(); | ||
227 | } | 227 | } | ||
228 | for (const auto win : manual_overlays) { | 228 | for (const auto win : manual_overlays) { | ||
229 | cl[pos++] = win; | 229 | cl[pos++] = win; | ||
230 | } | 230 | } | ||
231 | rootInfo()->setClientListStacking(cl, pos); | 231 | rootInfo()->setClientListStacking(cl, pos); | ||
232 | delete [] cl; | 232 | delete [] cl; | ||
233 | 233 | | |||
234 | // Make the cached stacking order invalid here, in case we need the new stacking order before we get | 234 | // Make the cached stacking order invalid here, in case we need the new stacking order before we get | ||
235 | // the matching event, due to X being asynchronous. | 235 | // the matching event, due to X being asynchronous. | ||
236 | markXStackingOrderAsDirty(); | 236 | markXStackingOrderAsDirty(); | ||
237 | } | 237 | } | ||
238 | 238 | | |||
239 | /** | 239 | /** | ||
240 | * Returns topmost visible client. Windows on the dock, the desktop | 240 | * Returns topmost visible client. Windows on the dock, the desktop | ||
241 | * or of any other special kind are excluded. Also if the window | 241 | * or of any other special kind are excluded. Also if the window | ||
242 | * doesn't accept focus it's excluded. | 242 | * doesn't accept focus it's excluded. | ||
243 | */ | 243 | */ | ||
244 | // TODO misleading name for this method, too many slightly different ways to use it | 244 | // TODO misleading name for this method, too many slightly different ways to use it | ||
245 | AbstractClient* Workspace::topClientOnDesktop(int desktop, int screen, bool unconstrained, bool only_normal) const | 245 | AbstractClient* Workspace::topClientOnDesktop(int desktop, int screen, bool unconstrained, bool only_normal) const | ||
246 | { | 246 | { | ||
247 | // TODO Q_ASSERT( block_stacking_updates == 0 ); | 247 | // TODO Q_ASSERT( block_stacking_updates == 0 ); | ||
248 | ToplevelList list; | 248 | QList<Toplevel *> list; | ||
249 | if (!unconstrained) | 249 | if (!unconstrained) | ||
250 | list = stacking_order; | 250 | list = stacking_order; | ||
251 | else | 251 | else | ||
252 | list = unconstrained_stacking_order; | 252 | list = unconstrained_stacking_order; | ||
253 | for (int i = list.size() - 1; | 253 | for (int i = list.size() - 1; | ||
254 | i >= 0; | 254 | i >= 0; | ||
255 | --i) { | 255 | --i) { | ||
256 | AbstractClient *c = qobject_cast<AbstractClient*>(list.at(i)); | 256 | AbstractClient *c = qobject_cast<AbstractClient*>(list.at(i)); | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | 313 | { | |||
317 | c->cancelAutoRaise(); | 317 | c->cancelAutoRaise(); | ||
318 | 318 | | |||
319 | StackingUpdatesBlocker blocker(this); | 319 | StackingUpdatesBlocker blocker(this); | ||
320 | 320 | | |||
321 | unconstrained_stacking_order.removeAll(c); | 321 | unconstrained_stacking_order.removeAll(c); | ||
322 | unconstrained_stacking_order.prepend(c); | 322 | unconstrained_stacking_order.prepend(c); | ||
323 | if (!nogroup && c->isTransient()) { | 323 | if (!nogroup && c->isTransient()) { | ||
324 | // lower also all windows in the group, in their reversed stacking order | 324 | // lower also all windows in the group, in their reversed stacking order | ||
325 | ClientList wins; | 325 | QList<X11Client *> wins; | ||
326 | if (auto group = c->group()) { | 326 | if (auto group = c->group()) { | ||
327 | wins = ensureStackingOrder(group->members()); | 327 | wins = ensureStackingOrder(group->members()); | ||
328 | } | 328 | } | ||
329 | for (int i = wins.size() - 1; | 329 | for (int i = wins.size() - 1; | ||
330 | i >= 0; | 330 | i >= 0; | ||
331 | --i) { | 331 | --i) { | ||
332 | if (wins[ i ] != c) | 332 | if (wins[ i ] != c) | ||
333 | lowerClient(wins[ i ], true); | 333 | lowerClient(wins[ i ], true); | ||
Show All 11 Lines | 342 | { | |||
345 | 345 | | |||
346 | c->cancelAutoRaise(); | 346 | c->cancelAutoRaise(); | ||
347 | 347 | | |||
348 | StackingUpdatesBlocker blocker(this); | 348 | StackingUpdatesBlocker blocker(this); | ||
349 | 349 | | |||
350 | unconstrained_stacking_order.removeAll(c); | 350 | unconstrained_stacking_order.removeAll(c); | ||
351 | bool lowered = false; | 351 | bool lowered = false; | ||
352 | // first try to put it below the bottom-most window of the application | 352 | // first try to put it below the bottom-most window of the application | ||
353 | for (ToplevelList::Iterator it = unconstrained_stacking_order.begin(); | 353 | for (auto it = unconstrained_stacking_order.begin(); | ||
354 | it != unconstrained_stacking_order.end(); | 354 | it != unconstrained_stacking_order.end(); | ||
355 | ++it) { | 355 | ++it) { | ||
356 | AbstractClient *client = qobject_cast<AbstractClient*>(*it); | 356 | AbstractClient *client = qobject_cast<AbstractClient*>(*it); | ||
357 | if (!client) { | 357 | if (!client) { | ||
358 | continue; | 358 | continue; | ||
359 | } | 359 | } | ||
360 | if (AbstractClient::belongToSameApplication(client, c)) { | 360 | if (AbstractClient::belongToSameApplication(client, c)) { | ||
361 | unconstrained_stacking_order.insert(it, c); | 361 | unconstrained_stacking_order.insert(it, c); | ||
▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Line(s) | |||||
480 | } | 480 | } | ||
481 | 481 | | |||
482 | void Workspace::restoreSessionStackingOrder(X11Client *c) | 482 | void Workspace::restoreSessionStackingOrder(X11Client *c) | ||
483 | { | 483 | { | ||
484 | if (c->sessionStackingOrder() < 0) | 484 | if (c->sessionStackingOrder() < 0) | ||
485 | return; | 485 | return; | ||
486 | StackingUpdatesBlocker blocker(this); | 486 | StackingUpdatesBlocker blocker(this); | ||
487 | unconstrained_stacking_order.removeAll(c); | 487 | unconstrained_stacking_order.removeAll(c); | ||
488 | for (ToplevelList::Iterator it = unconstrained_stacking_order.begin(); // from bottom | 488 | for (auto it = unconstrained_stacking_order.begin(); // from bottom | ||
489 | it != unconstrained_stacking_order.end(); | 489 | it != unconstrained_stacking_order.end(); | ||
490 | ++it) { | 490 | ++it) { | ||
491 | X11Client *current = qobject_cast<X11Client *>(*it); | 491 | X11Client *current = qobject_cast<X11Client *>(*it); | ||
492 | if (!current) { | 492 | if (!current) { | ||
493 | continue; | 493 | continue; | ||
494 | } | 494 | } | ||
495 | if (current->sessionStackingOrder() > c->sessionStackingOrder()) { | 495 | if (current->sessionStackingOrder() > c->sessionStackingOrder()) { | ||
496 | unconstrained_stacking_order.insert(it, c); | 496 | unconstrained_stacking_order.insert(it, c); | ||
497 | return; | 497 | return; | ||
498 | } | 498 | } | ||
499 | } | 499 | } | ||
500 | unconstrained_stacking_order.append(c); | 500 | unconstrained_stacking_order.append(c); | ||
501 | } | 501 | } | ||
502 | 502 | | |||
503 | /** | 503 | /** | ||
504 | * Returns a stacking order based upon \a list that fulfills certain contained. | 504 | * Returns a stacking order based upon \a list that fulfills certain contained. | ||
505 | */ | 505 | */ | ||
506 | ToplevelList Workspace::constrainedStackingOrder() | 506 | QList<Toplevel *> Workspace::constrainedStackingOrder() | ||
507 | { | 507 | { | ||
508 | ToplevelList layer[ NumLayers ]; | 508 | QList<Toplevel *> layer[ NumLayers ]; | ||
509 | 509 | | |||
510 | // build the order from layers | 510 | // build the order from layers | ||
511 | QVector< QMap<Group*, Layer> > minimum_layer(screens()->count()); | 511 | QVector< QMap<Group*, Layer> > minimum_layer(screens()->count()); | ||
512 | for (ToplevelList::ConstIterator it = unconstrained_stacking_order.constBegin(), | 512 | for (auto it = unconstrained_stacking_order.constBegin(), | ||
513 | end = unconstrained_stacking_order.constEnd(); it != end; ++it) { | 513 | end = unconstrained_stacking_order.constEnd(); it != end; ++it) { | ||
514 | Layer l = (*it)->layer(); | 514 | Layer l = (*it)->layer(); | ||
515 | 515 | | |||
516 | const int screen = (*it)->screen(); | 516 | const int screen = (*it)->screen(); | ||
517 | X11Client *c = qobject_cast<X11Client *>(*it); | 517 | X11Client *c = qobject_cast<X11Client *>(*it); | ||
518 | QMap< Group*, Layer >::iterator mLayer = minimum_layer[screen].find(c ? c->group() : nullptr); | 518 | QMap< Group*, Layer >::iterator mLayer = minimum_layer[screen].find(c ? c->group() : nullptr); | ||
519 | if (mLayer != minimum_layer[screen].end()) { | 519 | if (mLayer != minimum_layer[screen].end()) { | ||
520 | // If a window is raised above some other window in the same window group | 520 | // If a window is raised above some other window in the same window group | ||
521 | // which is in the ActiveLayer (i.e. it's fulscreened), make sure it stays | 521 | // which is in the ActiveLayer (i.e. it's fulscreened), make sure it stays | ||
522 | // above that window (see #95731). | 522 | // above that window (see #95731). | ||
523 | if (*mLayer == ActiveLayer && (l > BelowLayer)) | 523 | if (*mLayer == ActiveLayer && (l > BelowLayer)) | ||
524 | l = ActiveLayer; | 524 | l = ActiveLayer; | ||
525 | *mLayer = l; | 525 | *mLayer = l; | ||
526 | } else if (c) { | 526 | } else if (c) { | ||
527 | minimum_layer[screen].insertMulti(c->group(), l); | 527 | minimum_layer[screen].insertMulti(c->group(), l); | ||
528 | } | 528 | } | ||
529 | layer[ l ].append(*it); | 529 | layer[ l ].append(*it); | ||
530 | } | 530 | } | ||
531 | ToplevelList stacking; | 531 | QList<Toplevel *> stacking; | ||
532 | for (int lay = FirstLayer; lay < NumLayers; ++lay) { | 532 | for (int lay = FirstLayer; lay < NumLayers; ++lay) { | ||
533 | stacking += layer[lay]; | 533 | stacking += layer[lay]; | ||
534 | } | 534 | } | ||
535 | // now keep transients above their mainwindows | 535 | // now keep transients above their mainwindows | ||
536 | // TODO this could(?) use some optimization | 536 | // TODO this could(?) use some optimization | ||
537 | for (int i = stacking.size() - 1; i >= 0;) { | 537 | for (int i = stacking.size() - 1; i >= 0;) { | ||
538 | // Index of the main window for the current transient window. | 538 | // Index of the main window for the current transient window. | ||
539 | int i2 = -1; | 539 | int i2 = -1; | ||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Line(s) | 630 | if (--block_stacking_updates == 0) { | |||
631 | updateStackingOrder(blocked_propagating_new_clients); | 631 | updateStackingOrder(blocked_propagating_new_clients); | ||
632 | if (effects) | 632 | if (effects) | ||
633 | static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowStacking(); | 633 | static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowStacking(); | ||
634 | } | 634 | } | ||
635 | } | 635 | } | ||
636 | 636 | | |||
637 | namespace { | 637 | namespace { | ||
638 | template <class T> | 638 | template <class T> | ||
639 | QList<T*> ensureStackingOrderInList(const ToplevelList &stackingOrder, const QList<T*> &list) | 639 | QList<T*> ensureStackingOrderInList(const QList<Toplevel *> &stackingOrder, const QList<T*> &list) | ||
640 | { | 640 | { | ||
641 | static_assert(std::is_base_of<Toplevel, T>::value, | 641 | static_assert(std::is_base_of<Toplevel, T>::value, | ||
642 | "U must be derived from T"); | 642 | "U must be derived from T"); | ||
643 | // TODO Q_ASSERT( block_stacking_updates == 0 ); | 643 | // TODO Q_ASSERT( block_stacking_updates == 0 ); | ||
644 | if (list.count() < 2) | 644 | if (list.count() < 2) | ||
645 | return list; | 645 | return list; | ||
646 | // TODO is this worth optimizing? | 646 | // TODO is this worth optimizing? | ||
647 | QList<T*> result = list; | 647 | QList<T*> result = list; | ||
648 | for (auto it = stackingOrder.begin(); | 648 | for (auto it = stackingOrder.begin(); | ||
649 | it != stackingOrder.end(); | 649 | it != stackingOrder.end(); | ||
650 | ++it) { | 650 | ++it) { | ||
651 | T *c = qobject_cast<T*>(*it); | 651 | T *c = qobject_cast<T*>(*it); | ||
652 | if (!c) { | 652 | if (!c) { | ||
653 | continue; | 653 | continue; | ||
654 | } | 654 | } | ||
655 | if (result.removeAll(c) != 0) | 655 | if (result.removeAll(c) != 0) | ||
656 | result.append(c); | 656 | result.append(c); | ||
657 | } | 657 | } | ||
658 | return result; | 658 | return result; | ||
659 | } | 659 | } | ||
660 | } | 660 | } | ||
661 | 661 | | |||
662 | // Ensure list is in stacking order | 662 | // Ensure list is in stacking order | ||
663 | ClientList Workspace::ensureStackingOrder(const ClientList& list) const | 663 | QList<X11Client *> Workspace::ensureStackingOrder(const QList<X11Client *> &list) const | ||
664 | { | 664 | { | ||
665 | return ensureStackingOrderInList(stacking_order, list); | 665 | return ensureStackingOrderInList(stacking_order, list); | ||
666 | } | 666 | } | ||
667 | 667 | | |||
668 | QList<AbstractClient*> Workspace::ensureStackingOrder(const QList<AbstractClient*> &list) const | 668 | QList<AbstractClient*> Workspace::ensureStackingOrder(const QList<AbstractClient*> &list) const | ||
669 | { | 669 | { | ||
670 | return ensureStackingOrderInList(stacking_order, list); | 670 | return ensureStackingOrderInList(stacking_order, list); | ||
671 | } | 671 | } | ||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | 720 | if (mainWindow->isDock()) { | |||
721 | return false; | 721 | return false; | ||
722 | } | 722 | } | ||
723 | } | 723 | } | ||
724 | 724 | | |||
725 | return true; | 725 | return true; | ||
726 | } | 726 | } | ||
727 | 727 | | |||
728 | // Returns all windows in their stacking order on the root window. | 728 | // Returns all windows in their stacking order on the root window. | ||
729 | ToplevelList Workspace::xStackingOrder() const | 729 | QList<Toplevel *> Workspace::xStackingOrder() const | ||
730 | { | 730 | { | ||
731 | if (m_xStackingDirty) { | 731 | if (m_xStackingDirty) { | ||
732 | const_cast<Workspace*>(this)->updateXStackingOrder(); | 732 | const_cast<Workspace*>(this)->updateXStackingOrder(); | ||
733 | } | 733 | } | ||
734 | return x_stacking; | 734 | return x_stacking; | ||
735 | } | 735 | } | ||
736 | 736 | | |||
737 | void Workspace::updateXStackingOrder() | 737 | void Workspace::updateXStackingOrder() | ||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Line(s) | |||||
780 | { | 780 | { | ||
781 | X11Client *other = nullptr; | 781 | X11Client *other = nullptr; | ||
782 | if (detail == XCB_STACK_MODE_OPPOSITE) { | 782 | if (detail == XCB_STACK_MODE_OPPOSITE) { | ||
783 | other = workspace()->findClient(Predicate::WindowMatch, above); | 783 | other = workspace()->findClient(Predicate::WindowMatch, above); | ||
784 | if (!other) { | 784 | if (!other) { | ||
785 | workspace()->raiseOrLowerClient(this); | 785 | workspace()->raiseOrLowerClient(this); | ||
786 | return; | 786 | return; | ||
787 | } | 787 | } | ||
788 | ToplevelList::const_iterator it = workspace()->stackingOrder().constBegin(), | 788 | auto it = workspace()->stackingOrder().constBegin(), | ||
789 | end = workspace()->stackingOrder().constEnd(); | 789 | end = workspace()->stackingOrder().constEnd(); | ||
790 | while (it != end) { | 790 | while (it != end) { | ||
791 | if (*it == this) { | 791 | if (*it == this) { | ||
792 | detail = XCB_STACK_MODE_ABOVE; | 792 | detail = XCB_STACK_MODE_ABOVE; | ||
793 | break; | 793 | break; | ||
794 | } else if (*it == other) { | 794 | } else if (*it == other) { | ||
795 | detail = XCB_STACK_MODE_BELOW; | 795 | detail = XCB_STACK_MODE_BELOW; | ||
796 | break; | 796 | break; | ||
Show All 13 Lines | 809 | if (other && other->frameGeometry().intersects(frameGeometry())) | |||
810 | workspace()->lowerClientRequest(this, src, timestamp); | 810 | workspace()->lowerClientRequest(this, src, timestamp); | ||
811 | return; | 811 | return; | ||
812 | } | 812 | } | ||
813 | 813 | | |||
814 | if (!other) | 814 | if (!other) | ||
815 | other = workspace()->findClient(Predicate::WindowMatch, above); | 815 | other = workspace()->findClient(Predicate::WindowMatch, above); | ||
816 | 816 | | |||
817 | if (other && detail == XCB_STACK_MODE_ABOVE) { | 817 | if (other && detail == XCB_STACK_MODE_ABOVE) { | ||
818 | ToplevelList::const_iterator it = workspace()->stackingOrder().constEnd(), | 818 | auto it = workspace()->stackingOrder().constEnd(), | ||
819 | begin = workspace()->stackingOrder().constBegin(); | 819 | begin = workspace()->stackingOrder().constBegin(); | ||
820 | while (--it != begin) { | 820 | while (--it != begin) { | ||
821 | 821 | | |||
822 | if (*it == other) { // the other one is top on stack | 822 | if (*it == other) { // the other one is top on stack | ||
823 | it = begin; // invalidate | 823 | it = begin; // invalidate | ||
824 | src = NET::FromTool; // force | 824 | src = NET::FromTool; // force | ||
825 | break; | 825 | break; | ||
826 | } | 826 | } | ||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |