Changeset View
Changeset View
Standalone View
Standalone View
activation.cpp
Show First 20 Lines • Show All 233 Lines • ▼ Show 20 Line(s) | 230 | { | |||
---|---|---|---|---|---|
234 | if (active_popup && active_popup_client != c && set_active_client_recursion == 0) | 234 | if (active_popup && active_popup_client != c && set_active_client_recursion == 0) | ||
235 | closeActivePopup(); | 235 | closeActivePopup(); | ||
236 | if (m_userActionsMenu->hasClient() && !m_userActionsMenu->isMenuClient(c) && set_active_client_recursion == 0) { | 236 | if (m_userActionsMenu->hasClient() && !m_userActionsMenu->isMenuClient(c) && set_active_client_recursion == 0) { | ||
237 | m_userActionsMenu->close(); | 237 | m_userActionsMenu->close(); | ||
238 | } | 238 | } | ||
239 | StackingUpdatesBlocker blocker(this); | 239 | StackingUpdatesBlocker blocker(this); | ||
240 | ++set_active_client_recursion; | 240 | ++set_active_client_recursion; | ||
241 | updateFocusMousePosition(Cursor::pos()); | 241 | updateFocusMousePosition(Cursor::pos()); | ||
242 | if (active_client != NULL) { | 242 | if (active_client != nullptr) { | ||
243 | // note that this may call setActiveClient( NULL ), therefore the recursion counter | 243 | // note that this may call setActiveClient( NULL ), therefore the recursion counter | ||
244 | active_client->setActive(false); | 244 | active_client->setActive(false); | ||
245 | } | 245 | } | ||
246 | active_client = c; | 246 | active_client = c; | ||
247 | Q_ASSERT(c == NULL || c->isActive()); | 247 | Q_ASSERT(c == nullptr || c->isActive()); | ||
248 | 248 | | |||
249 | if (active_client) { | 249 | if (active_client) { | ||
250 | last_active_client = active_client; | 250 | last_active_client = active_client; | ||
251 | FocusChain::self()->update(active_client, FocusChain::MakeFirst); | 251 | FocusChain::self()->update(active_client, FocusChain::MakeFirst); | ||
252 | active_client->demandAttention(false); | 252 | active_client->demandAttention(false); | ||
253 | 253 | | |||
254 | // activating a client can cause a non active fullscreen window to loose the ActiveLayer status on > 1 screens | 254 | // activating a client can cause a non active fullscreen window to loose the ActiveLayer status on > 1 screens | ||
255 | if (screens()->count() > 1) { | 255 | if (screens()->count() > 1) { | ||
Show All 30 Lines | |||||
286 | * setActiveClient() and the operation is complete. This may not happen | 286 | * setActiveClient() and the operation is complete. This may not happen | ||
287 | * with certain focus policies, though. | 287 | * with certain focus policies, though. | ||
288 | * | 288 | * | ||
289 | * @see setActiveClient | 289 | * @see setActiveClient | ||
290 | * @see requestFocus | 290 | * @see requestFocus | ||
291 | */ | 291 | */ | ||
292 | void Workspace::activateClient(AbstractClient* c, bool force) | 292 | void Workspace::activateClient(AbstractClient* c, bool force) | ||
293 | { | 293 | { | ||
294 | if (c == NULL) { | 294 | if (c == nullptr) { | ||
295 | focusToNull(); | 295 | focusToNull(); | ||
296 | setActiveClient(NULL); | 296 | setActiveClient(nullptr); | ||
297 | return; | 297 | return; | ||
298 | } | 298 | } | ||
299 | raiseClient(c); | 299 | raiseClient(c); | ||
300 | if (!c->isOnCurrentDesktop()) { | 300 | if (!c->isOnCurrentDesktop()) { | ||
301 | ++block_focus; | 301 | ++block_focus; | ||
302 | VirtualDesktopManager::self()->setCurrent(c->desktop()); | 302 | VirtualDesktopManager::self()->setCurrent(c->desktop()); | ||
303 | --block_focus; | 303 | --block_focus; | ||
304 | } | 304 | } | ||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Line(s) | 349 | { | |||
353 | 353 | | |||
354 | if (!c) { | 354 | if (!c) { | ||
355 | focusToNull(); | 355 | focusToNull(); | ||
356 | return; | 356 | return; | ||
357 | } | 357 | } | ||
358 | 358 | | |||
359 | if (flags & ActivityFocus) { | 359 | if (flags & ActivityFocus) { | ||
360 | AbstractClient* modal = c->findModal(); | 360 | AbstractClient* modal = c->findModal(); | ||
361 | if (modal != NULL && modal != c) { | 361 | if (modal != nullptr && modal != c) { | ||
362 | if (!modal->isOnDesktop(c->desktop())) | 362 | if (!modal->isOnDesktop(c->desktop())) | ||
363 | modal->setDesktop(c->desktop()); | 363 | modal->setDesktop(c->desktop()); | ||
364 | if (!modal->isShown(true) && !modal->isMinimized()) // forced desktop or utility window | 364 | if (!modal->isShown(true) && !modal->isMinimized()) // forced desktop or utility window | ||
365 | activateClient(modal); // activating a minimized blocked window will unminimize its modal implicitly | 365 | activateClient(modal); // activating a minimized blocked window will unminimize its modal implicitly | ||
366 | // if the click was inside the window (i.e. handled is set), | 366 | // if the click was inside the window (i.e. handled is set), | ||
367 | // but it has a modal, there's no need to use handled mode, because | 367 | // but it has a modal, there's no need to use handled mode, because | ||
368 | // the modal doesn't get the click anyway | 368 | // the modal doesn't get the click anyway | ||
369 | // raising of the original window needs to be still done | 369 | // raising of the original window needs to be still done | ||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Line(s) | 421 | while (it != stackingOrder().constBegin()) { | |||
429 | if (!(client->isShown(false) && client->isOnCurrentDesktop() && | 429 | if (!(client->isShown(false) && client->isOnCurrentDesktop() && | ||
430 | client->isOnCurrentActivity() && client->isOnScreen(screen))) | 430 | client->isOnCurrentActivity() && client->isOnScreen(screen))) | ||
431 | continue; | 431 | continue; | ||
432 | 432 | | |||
433 | if (client->geometry().contains(Cursor::pos())) { | 433 | if (client->geometry().contains(Cursor::pos())) { | ||
434 | return client; | 434 | return client; | ||
435 | } | 435 | } | ||
436 | } | 436 | } | ||
437 | return 0; | 437 | return nullptr; | ||
438 | } | 438 | } | ||
439 | 439 | | |||
440 | // deactivates 'c' and activates next client | 440 | // deactivates 'c' and activates next client | ||
441 | bool Workspace::activateNextClient(AbstractClient* c) | 441 | bool Workspace::activateNextClient(AbstractClient* c) | ||
442 | { | 442 | { | ||
443 | // if 'c' is not the active or the to-become active one, do nothing | 443 | // if 'c' is not the active or the to-become active one, do nothing | ||
444 | if (!(c == active_client || (should_get_focus.count() > 0 && c == should_get_focus.last()))) | 444 | if (!(c == active_client || (should_get_focus.count() > 0 && c == should_get_focus.last()))) | ||
445 | return false; | 445 | return false; | ||
446 | 446 | | |||
447 | closeActivePopup(); | 447 | closeActivePopup(); | ||
448 | 448 | | |||
449 | if (c != NULL) { | 449 | if (c != nullptr) { | ||
450 | if (c == active_client) | 450 | if (c == active_client) | ||
451 | setActiveClient(NULL); | 451 | setActiveClient(nullptr); | ||
452 | should_get_focus.removeAll(c); | 452 | should_get_focus.removeAll(c); | ||
453 | } | 453 | } | ||
454 | 454 | | |||
455 | // if blocking focus, move focus to the desktop later if needed | 455 | // if blocking focus, move focus to the desktop later if needed | ||
456 | // in order to avoid flickering | 456 | // in order to avoid flickering | ||
457 | if (!focusChangeEnabled()) { | 457 | if (!focusChangeEnabled()) { | ||
458 | focusToNull(); | 458 | focusToNull(); | ||
459 | return true; | 459 | return true; | ||
460 | } | 460 | } | ||
461 | 461 | | |||
462 | if (!options->focusPolicyIsReasonable()) | 462 | if (!options->focusPolicyIsReasonable()) | ||
463 | return false; | 463 | return false; | ||
464 | 464 | | |||
465 | AbstractClient* get_focus = NULL; | 465 | AbstractClient* get_focus = nullptr; | ||
466 | 466 | | |||
467 | const int desktop = VirtualDesktopManager::self()->current(); | 467 | const int desktop = VirtualDesktopManager::self()->current(); | ||
468 | 468 | | |||
469 | if (!get_focus && showingDesktop()) | 469 | if (!get_focus && showingDesktop()) | ||
470 | get_focus = findDesktop(true, desktop); // to not break the state | 470 | get_focus = findDesktop(true, desktop); // to not break the state | ||
471 | 471 | | |||
472 | if (!get_focus && options->isNextFocusPrefersMouse()) { | 472 | if (!get_focus && options->isNextFocusPrefersMouse()) { | ||
473 | get_focus = clientUnderMouse(c ? c->screen() : screens()->current()); | 473 | get_focus = clientUnderMouse(c ? c->screen() : screens()->current()); | ||
474 | if (get_focus && (get_focus == c || get_focus->isDesktop())) { | 474 | if (get_focus && (get_focus == c || get_focus->isDesktop())) { | ||
475 | // should rather not happen, but it cannot get the focus. rest of usability is tested above | 475 | // should rather not happen, but it cannot get the focus. rest of usability is tested above | ||
476 | get_focus = NULL; | 476 | get_focus = nullptr; | ||
477 | } | 477 | } | ||
478 | } | 478 | } | ||
479 | 479 | | |||
480 | if (!get_focus) { // no suitable window under the mouse -> find sth. else | 480 | if (!get_focus) { // no suitable window under the mouse -> find sth. else | ||
481 | // first try to pass the focus to the (former) active clients leader | 481 | // first try to pass the focus to the (former) active clients leader | ||
482 | if (c && c->isTransient()) { | 482 | if (c && c->isTransient()) { | ||
483 | auto leaders = c->mainClients(); | 483 | auto leaders = c->mainClients(); | ||
484 | if (leaders.count() == 1 && FocusChain::self()->isUsableFocusCandidate(leaders.at(0), c)) { | 484 | if (leaders.count() == 1 && FocusChain::self()->isUsableFocusCandidate(leaders.at(0), c)) { | ||
485 | get_focus = leaders.at(0); | 485 | get_focus = leaders.at(0); | ||
486 | raiseClient(get_focus); // also raise - we don't know where it came from | 486 | raiseClient(get_focus); // also raise - we don't know where it came from | ||
487 | } | 487 | } | ||
488 | } | 488 | } | ||
489 | if (!get_focus) { | 489 | if (!get_focus) { | ||
490 | // nope, ask the focus chain for the next candidate | 490 | // nope, ask the focus chain for the next candidate | ||
491 | get_focus = FocusChain::self()->nextForDesktop(c, desktop); | 491 | get_focus = FocusChain::self()->nextForDesktop(c, desktop); | ||
492 | } | 492 | } | ||
493 | } | 493 | } | ||
494 | 494 | | |||
495 | if (get_focus == NULL) // last chance: focus the desktop | 495 | if (get_focus == nullptr) // last chance: focus the desktop | ||
496 | get_focus = findDesktop(true, desktop); | 496 | get_focus = findDesktop(true, desktop); | ||
497 | 497 | | |||
498 | if (get_focus != NULL) | 498 | if (get_focus != nullptr) | ||
499 | requestFocus(get_focus); | 499 | requestFocus(get_focus); | ||
500 | else | 500 | else | ||
501 | focusToNull(); | 501 | focusToNull(); | ||
502 | 502 | | |||
503 | return true; | 503 | return true; | ||
504 | 504 | | |||
505 | } | 505 | } | ||
506 | 506 | | |||
507 | void Workspace::setCurrentScreen(int new_screen) | 507 | void Workspace::setCurrentScreen(int new_screen) | ||
508 | { | 508 | { | ||
509 | if (new_screen < 0 || new_screen >= screens()->count()) | 509 | if (new_screen < 0 || new_screen >= screens()->count()) | ||
510 | return; | 510 | return; | ||
511 | if (!options->focusPolicyIsReasonable()) | 511 | if (!options->focusPolicyIsReasonable()) | ||
512 | return; | 512 | return; | ||
513 | closeActivePopup(); | 513 | closeActivePopup(); | ||
514 | const int desktop = VirtualDesktopManager::self()->current(); | 514 | const int desktop = VirtualDesktopManager::self()->current(); | ||
515 | AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop, new_screen); | 515 | AbstractClient *get_focus = FocusChain::self()->getForActivation(desktop, new_screen); | ||
516 | if (get_focus == NULL) | 516 | if (get_focus == nullptr) | ||
517 | get_focus = findDesktop(true, desktop); | 517 | get_focus = findDesktop(true, desktop); | ||
518 | if (get_focus != NULL && get_focus != mostRecentlyActivatedClient()) | 518 | if (get_focus != nullptr && get_focus != mostRecentlyActivatedClient()) | ||
519 | requestFocus(get_focus); | 519 | requestFocus(get_focus); | ||
520 | screens()->setCurrent(new_screen); | 520 | screens()->setCurrent(new_screen); | ||
521 | } | 521 | } | ||
522 | 522 | | |||
523 | void Workspace::gotFocusIn(const AbstractClient* c) | 523 | void Workspace::gotFocusIn(const AbstractClient* c) | ||
524 | { | 524 | { | ||
525 | if (should_get_focus.contains(const_cast< AbstractClient* >(c))) { | 525 | if (should_get_focus.contains(const_cast< AbstractClient* >(c))) { | ||
526 | // remove also all sooner elements that should have got FocusIn, | 526 | // remove also all sooner elements that should have got FocusIn, | ||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Line(s) | 583 | if (level == FSP::Extreme || protection == FSP::Extreme) | |||
584 | return false; | 584 | return false; | ||
585 | 585 | | |||
586 | // Desktop switching is only allowed in the "no protection" case | 586 | // Desktop switching is only allowed in the "no protection" case | ||
587 | if (!ignore_desktop && !c->isOnCurrentDesktop()) | 587 | if (!ignore_desktop && !c->isOnCurrentDesktop()) | ||
588 | return false; // allow only with level == 0 | 588 | return false; // allow only with level == 0 | ||
589 | 589 | | |||
590 | // No active client, it's ok to pass focus | 590 | // No active client, it's ok to pass focus | ||
591 | // NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows | 591 | // NOTICE that extreme protection needs to be handled before to allow protection on unmanged windows | ||
592 | if (ac == NULL || ac->isDesktop()) { | 592 | if (ac == nullptr || ac->isDesktop()) { | ||
593 | qCDebug(KWIN_CORE) << "Activation: No client active, allowing"; | 593 | qCDebug(KWIN_CORE) << "Activation: No client active, allowing"; | ||
594 | return true; // no active client -> always allow | 594 | return true; // no active client -> always allow | ||
595 | } | 595 | } | ||
596 | 596 | | |||
597 | // TODO window urgency -> return true? | 597 | // TODO window urgency -> return true? | ||
598 | 598 | | |||
599 | // Unconditionally allow intra-client passing around for lower stealing protections | 599 | // Unconditionally allow intra-client passing around for lower stealing protections | ||
600 | // unless the active client has High interest | 600 | // unless the active client has High interest | ||
Show All 37 Lines | 636 | { | |||
638 | if (session_saving && level <= 2) { // <= normal | 638 | if (session_saving && level <= 2) { // <= normal | ||
639 | return true; | 639 | return true; | ||
640 | } | 640 | } | ||
641 | AbstractClient* ac = mostRecentlyActivatedClient(); | 641 | AbstractClient* ac = mostRecentlyActivatedClient(); | ||
642 | if (level == 0) // none | 642 | if (level == 0) // none | ||
643 | return true; | 643 | return true; | ||
644 | if (level == 4) // extreme | 644 | if (level == 4) // extreme | ||
645 | return false; | 645 | return false; | ||
646 | if (ac == NULL || ac->isDesktop()) { | 646 | if (ac == nullptr || ac->isDesktop()) { | ||
647 | qCDebug(KWIN_CORE) << "Raising: No client active, allowing"; | 647 | qCDebug(KWIN_CORE) << "Raising: No client active, allowing"; | ||
648 | return true; // no active client -> always allow | 648 | return true; // no active client -> always allow | ||
649 | } | 649 | } | ||
650 | // TODO window urgency -> return true? | 650 | // TODO window urgency -> return true? | ||
651 | if (AbstractClient::belongToSameApplication(c, ac, AbstractClient::SameApplicationCheck::RelaxedForActive)) { | 651 | if (AbstractClient::belongToSameApplication(c, ac, AbstractClient::SameApplicationCheck::RelaxedForActive)) { | ||
652 | qCDebug(KWIN_CORE) << "Raising: Belongs to active application"; | 652 | qCDebug(KWIN_CORE) << "Raising: Belongs to active application"; | ||
653 | return true; | 653 | return true; | ||
654 | } | 654 | } | ||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | 699 | { | |||
701 | if (time == XCB_TIME_CURRENT_TIME) { | 701 | if (time == XCB_TIME_CURRENT_TIME) { | ||
702 | updateXTime(); | 702 | updateXTime(); | ||
703 | time = xTime(); | 703 | time = xTime(); | ||
704 | } | 704 | } | ||
705 | if (time != -1U | 705 | if (time != -1U | ||
706 | && (m_userTime == XCB_TIME_CURRENT_TIME | 706 | && (m_userTime == XCB_TIME_CURRENT_TIME | ||
707 | || NET::timestampCompare(time, m_userTime) > 0)) { // time > user_time | 707 | || NET::timestampCompare(time, m_userTime) > 0)) { // time > user_time | ||
708 | m_userTime = time; | 708 | m_userTime = time; | ||
709 | shade_below = NULL; // do not hover re-shade a window after it got interaction | 709 | shade_below = nullptr; // do not hover re-shade a window after it got interaction | ||
710 | } | 710 | } | ||
711 | group()->updateUserTime(m_userTime); | 711 | group()->updateUserTime(m_userTime); | ||
712 | } | 712 | } | ||
713 | 713 | | |||
714 | xcb_timestamp_t Client::readUserCreationTime() const | 714 | xcb_timestamp_t Client::readUserCreationTime() const | ||
715 | { | 715 | { | ||
716 | Xcb::Property prop(false, window(), atoms->kde_net_wm_user_creation_time, XCB_ATOM_CARDINAL, 0, 1); | 716 | Xcb::Property prop(false, window(), atoms->kde_net_wm_user_creation_time, XCB_ATOM_CARDINAL, 0, 1); | ||
717 | return prop.value<xcb_timestamp_t>(-1); | 717 | return prop.value<xcb_timestamp_t>(-1); | ||
718 | } | 718 | } | ||
719 | 719 | | |||
720 | xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data, | 720 | xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data, | ||
721 | bool session) const | 721 | bool session) const | ||
722 | { | 722 | { | ||
723 | xcb_timestamp_t time = info->userTime(); | 723 | xcb_timestamp_t time = info->userTime(); | ||
724 | //qDebug() << "User timestamp, initial:" << time; | 724 | //qDebug() << "User timestamp, initial:" << time; | ||
725 | //^^ this deadlocks kwin --replace sometimes. | 725 | //^^ this deadlocks kwin --replace sometimes. | ||
726 | 726 | | |||
727 | // newer ASN timestamp always replaces user timestamp, unless user timestamp is 0 | 727 | // newer ASN timestamp always replaces user timestamp, unless user timestamp is 0 | ||
728 | // helps e.g. with konqy reusing | 728 | // helps e.g. with konqy reusing | ||
729 | if (asn_data != NULL && time != 0) { | 729 | if (asn_data != nullptr && time != 0) { | ||
730 | if (asn_id->timestamp() != 0 | 730 | if (asn_id->timestamp() != 0 | ||
731 | && (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) { | 731 | && (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) { | ||
732 | time = asn_id->timestamp(); | 732 | time = asn_id->timestamp(); | ||
733 | } | 733 | } | ||
734 | } | 734 | } | ||
735 | qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time; | 735 | qCDebug(KWIN_CORE) << "User timestamp, ASN:" << time; | ||
736 | if (time == -1U) { | 736 | if (time == -1U) { | ||
737 | // The window doesn't have any timestamp. | 737 | // The window doesn't have any timestamp. | ||
738 | // If it's the first window for its application | 738 | // If it's the first window for its application | ||
739 | // (i.e. there's no other window from the same app), | 739 | // (i.e. there's no other window from the same app), | ||
740 | // use the _KDE_NET_WM_USER_CREATION_TIME trick. | 740 | // use the _KDE_NET_WM_USER_CREATION_TIME trick. | ||
741 | // Otherwise, refuse activation of a window | 741 | // Otherwise, refuse activation of a window | ||
742 | // from already running application if this application | 742 | // from already running application if this application | ||
743 | // is not the active one (unless focus stealing prevention is turned off). | 743 | // is not the active one (unless focus stealing prevention is turned off). | ||
744 | Client* act = dynamic_cast<Client*>(workspace()->mostRecentlyActivatedClient()); | 744 | Client* act = dynamic_cast<Client*>(workspace()->mostRecentlyActivatedClient()); | ||
745 | if (act != NULL && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) { | 745 | if (act != nullptr && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) { | ||
746 | bool first_window = true; | 746 | bool first_window = true; | ||
747 | auto sameApplicationActiveHackPredicate = [this](const Client *cl) { | 747 | auto sameApplicationActiveHackPredicate = [this](const Client *cl) { | ||
748 | // ignore already existing splashes, toolbars, utilities and menus, | 748 | // ignore already existing splashes, toolbars, utilities and menus, | ||
749 | // as the app may show those before the main window | 749 | // as the app may show those before the main window | ||
750 | return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu() | 750 | return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu() | ||
751 | && cl != this && Client::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive); | 751 | && cl != this && Client::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive); | ||
752 | }; | 752 | }; | ||
753 | if (isTransient()) { | 753 | if (isTransient()) { | ||
754 | auto clientMainClients = [this] () -> ClientList { | 754 | auto clientMainClients = [this] () -> ClientList { | ||
755 | ClientList ret; | 755 | ClientList ret; | ||
756 | const auto mcs = mainClients(); | 756 | const auto mcs = mainClients(); | ||
757 | for (auto mc: mcs) { | 757 | for (auto mc: mcs) { | ||
758 | if (Client *c = dynamic_cast<Client*>(mc)) { | 758 | if (Client *c = dynamic_cast<Client*>(mc)) { | ||
759 | ret << c; | 759 | ret << c; | ||
760 | } | 760 | } | ||
761 | } | 761 | } | ||
762 | return ret; | 762 | return ret; | ||
763 | }; | 763 | }; | ||
764 | if (act->hasTransient(this, true)) | 764 | if (act->hasTransient(this, true)) | ||
765 | ; // is transient for currently active window, even though it's not | 765 | ; // is transient for currently active window, even though it's not | ||
766 | // the same app (e.g. kcookiejar dialog) -> allow activation | 766 | // the same app (e.g. kcookiejar dialog) -> allow activation | ||
767 | else if (groupTransient() && | 767 | else if (groupTransient() && | ||
768 | findInList<Client, Client>(clientMainClients(), sameApplicationActiveHackPredicate) == NULL) | 768 | findInList<Client, Client>(clientMainClients(), sameApplicationActiveHackPredicate) == nullptr) | ||
769 | ; // standalone transient | 769 | ; // standalone transient | ||
770 | else | 770 | else | ||
771 | first_window = false; | 771 | first_window = false; | ||
772 | } else { | 772 | } else { | ||
773 | if (workspace()->findClient(sameApplicationActiveHackPredicate)) | 773 | if (workspace()->findClient(sameApplicationActiveHackPredicate)) | ||
774 | first_window = false; | 774 | first_window = false; | ||
775 | } | 775 | } | ||
776 | // don't refuse if focus stealing prevention is turned off | 776 | // don't refuse if focus stealing prevention is turned off | ||
Show All 19 Lines | |||||
796 | return time; | 796 | return time; | ||
797 | } | 797 | } | ||
798 | 798 | | |||
799 | xcb_timestamp_t Client::userTime() const | 799 | xcb_timestamp_t Client::userTime() const | ||
800 | { | 800 | { | ||
801 | xcb_timestamp_t time = m_userTime; | 801 | xcb_timestamp_t time = m_userTime; | ||
802 | if (time == 0) // doesn't want focus after showing | 802 | if (time == 0) // doesn't want focus after showing | ||
803 | return 0; | 803 | return 0; | ||
804 | Q_ASSERT(group() != NULL); | 804 | Q_ASSERT(group() != nullptr); | ||
805 | if (time == -1U | 805 | if (time == -1U | ||
806 | || (group()->userTime() != -1U | 806 | || (group()->userTime() != -1U | ||
807 | && NET::timestampCompare(group()->userTime(), time) > 0)) | 807 | && NET::timestampCompare(group()->userTime(), time) > 0)) | ||
808 | time = group()->userTime(); | 808 | time = group()->userTime(); | ||
809 | return time; | 809 | return time; | ||
810 | } | 810 | } | ||
811 | 811 | | |||
812 | void Client::doSetActive() | 812 | void Client::doSetActive() | ||
▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines |