23#if KWIN_BUILD_ACTIVITIES
28#include <KLocalizedString>
29#include <kstartupinfo.h>
30#include <kstringhandler.h>
218 if (m_activeWindow == window) {
222 if (active_popup && m_activePopupWindow != window && m_setActiveWindowRecursion == 0) {
225 if (m_userActionsMenu->
hasWindow() && !m_userActionsMenu->
isMenuWindow(window) && m_setActiveWindowRecursion == 0) {
226 m_userActionsMenu->
close();
229 ++m_setActiveWindowRecursion;
231 if (m_activeWindow !=
nullptr) {
235 m_activeWindow = window;
236 Q_ASSERT(window ==
nullptr || window->
isActive());
238 if (m_activeWindow) {
239 m_lastActiveWindow = m_activeWindow;
245 for (
auto it = m_windows.begin(); it != m_windows.end(); ++it) {
246 if (*it != m_activeWindow && (*it)->
layer() ==
ActiveLayer && (*it)->output() == m_activeWindow->
output()) {
247 (*it)->updateLayer();
253 updateToolWindows(
false);
267 --m_setActiveWindowRecursion;
284 if (window ==
nullptr) {
302 VirtualDesktopManager::self()->setCurrent(window->
desktops().constLast());
305 window->
enterDesktop(VirtualDesktopManager::self()->currentDesktop());
312#if KWIN_BUILD_ACTIVITIES
317 m_activities->setCurrent(window->
activities().constFirst());
342 x11Window->updateUserTime();
345 m_quickTileCombineTimer->stop();
364 flags &= ~ActivityFocus;
374 if (modal !=
nullptr && modal != window) {
396 flags &= ~ActivityFocus;
405 flags &= ~ActivityFocus;
408 qCWarning(KWIN_CORE) <<
"takeActivity: not shown";
445 auto window = *(--it);
446 if (!window->isClient()) {
452 if (!(window->isShown() && window->isOnCurrentDesktop() && window->isOnCurrentActivity() && window->isOnOutput(output) && !window->isShade())) {
467 if (!(window == m_activeWindow || (should_get_focus.count() > 0 && window == should_get_focus.last()))) {
473 if (window !=
nullptr) {
474 if (window == m_activeWindow) {
477 should_get_focus.removeAll(window);
491 Window *focusCandidate =
nullptr;
493 VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
501 if (focusCandidate && (focusCandidate == window || focusCandidate->
isDesktop())) {
503 focusCandidate =
nullptr;
507 if (!focusCandidate) {
511 if (leaders.count() == 1 && m_focusChain->isUsableFocusCandidate(leaders.at(0), window)) {
512 focusCandidate = leaders.at(0);
516 if (!focusCandidate) {
518 focusCandidate = m_focusChain->nextForDesktop(window, desktop);
522 if (focusCandidate ==
nullptr) {
526 if (focusCandidate !=
nullptr) {
541 VirtualDesktop *desktop = VirtualDesktopManager::self()->currentDesktop();
542 Window *get_focus = m_focusChain->getForActivation(desktop, output);
543 if (get_focus ==
nullptr) {
554 if (should_get_focus.contains(window)) {
557 while (should_get_focus.first() != window) {
558 should_get_focus.pop_front();
560 should_get_focus.pop_front();
566 should_get_focus.append(window);
574bool Workspace::allowFullClientRaising(
const KWin::Window *window, xcb_timestamp_t time)
587 if (ac ==
nullptr || ac->isDesktop()) {
588 qCDebug(KWIN_CORE) <<
"Raising: No window active, allowing";
593 qCDebug(KWIN_CORE) <<
"Raising: Belongs to active application";
599 xcb_timestamp_t user_time = ac->userTime();
600 qCDebug(KWIN_CORE) <<
"Raising, compared:" << time <<
":" << user_time
601 <<
":" << (NET::timestampCompare(time, user_time) >= 0);
602 return NET::timestampCompare(time, user_time) >= 0;
617 kwinApp()->updateXTime();
618 if (should_get_focus.count() > 0) {
620 }
else if (m_lastActiveWindow) {
629 attention_chain.removeAll(window);
630 attention_chain.prepend(window);
632 attention_chain.removeAll(window);
649 if (time == XCB_TIME_CURRENT_TIME) {
650 kwinApp()->updateXTime();
654 && (m_userTime == XCB_TIME_CURRENT_TIME
655 || NET::timestampCompare(time, m_userTime) > 0)) {
657 shade_below =
nullptr;
662xcb_timestamp_t X11Window::readUserCreationTime()
const
665 return prop.value<xcb_timestamp_t>(-1);
668xcb_timestamp_t X11Window::readUserTimeMapTimestamp(
const KStartupInfoId *asn_id,
const KStartupInfoData *asn_data,
671 xcb_timestamp_t time = info->userTime();
677 if (asn_data !=
nullptr && time != 0) {
678 if (asn_id->timestamp() != 0
679 && (time == -1U || NET::timestampCompare(asn_id->timestamp(), time) > 0)) {
680 time = asn_id->timestamp();
683 qCDebug(KWIN_CORE) <<
"User timestamp, ASN:" << time;
694 bool first_window =
true;
695 auto sameApplicationActiveHackPredicate = [
this](
const X11Window *cl) {
698 return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
702 auto clientMainClients = [
this]() {
703 QList<X11Window *> ret;
705 for (
auto mc : mcs) {
712 if (act->hasTransient(
this,
true)) {
715 }
else if (
groupTransient() && findInList<X11Window, X11Window>(clientMainClients(), sameApplicationActiveHackPredicate) ==
nullptr) {
718 first_window =
false;
721 if (
workspace()->findClient(sameApplicationActiveHackPredicate)) {
722 first_window =
false;
727 qCDebug(KWIN_CORE) <<
"User timestamp, already exists:" << 0;
743 time = readUserCreationTime();
745 qCDebug(KWIN_CORE) <<
"User timestamp, final:" <<
this <<
":" << time;
751 xcb_timestamp_t time = m_userTime;
755 Q_ASSERT(
group() !=
nullptr);
767 info->setState(
isActive() ? NET::Focused : NET::States(), NET::Focused);
770void X11Window::startupIdChanged()
772 KStartupInfoId asn_id;
773 KStartupInfoData asn_data;
783 if (asn_data.desktop() == -1) {
786 if (VirtualDesktop *desktop = VirtualDesktopManager::self()->desktopForX11Id(asn_data.desktop())) {
792 if (asn_data.xinerama() != -1) {
798 const xcb_timestamp_t timestamp = asn_id.timestamp();
799 if (timestamp != 0) {
809void X11Window::updateUrgency()
811 if (info->urgency()) {
840 time =
window->userTime();
856 if (!
window->rules()->checkAcceptFocus(
false)) {
875 qCDebug(KWIN_CORE) <<
"Activation: No window active, allowing";
884 qCDebug(KWIN_CORE) <<
"Activation: Belongs to active application";
894 qCDebug(KWIN_CORE) <<
"Activation: No timestamp at all";
906 const xcb_timestamp_t user_time = ac->
userTime();
907 qCDebug(KWIN_CORE) <<
"Activation, compared:" <<
window <<
":" << time <<
":" << user_time
908 <<
":" << (NET::timestampCompare(time, user_time) >= 0);
909 return NET::timestampCompare(time, user_time) >= 0;
916void Group::startupIdChanged()
918 KStartupInfoId asn_id;
919 KStartupInfoData asn_data;
924 if (asn_id.timestamp() != 0 && user_time != -1U
925 && NET::timestampCompare(asn_id.timestamp(), user_time) > 0) {
926 user_time = asn_id.timestamp();
933 if (time == XCB_CURRENT_TIME) {
934 kwinApp()->updateXTime();
938 && (user_time == XCB_CURRENT_TIME
939 || NET::timestampCompare(time, user_time) > 0)) {
Xcb::Atom kde_net_wm_user_creation_time
xcb_timestamp_t userTime() const
void updateUserTime(xcb_timestamp_t time)
int focusStealingPreventionLevel
ActivationDesktopPolicy activationDesktopPolicy
bool focusPolicyIsReasonable
bool isNextFocusPrefersMouse() const
void setActiveClient(Window *client)
SessionState state() const
void setMinimized(bool set)
virtual QList< Window * > mainWindows() const
virtual bool isTransient() const
bool isOnCurrentActivity() const
static bool belongToSameApplication(const Window *c1, const Window *c2, SameApplicationChecks checks=SameApplicationChecks())
void demandAttention(bool set=true)
bool isHiddenByShowDesktop() const
bool isOnAllDesktops() const
virtual bool takeFocus()=0
bool isOnCurrentDesktop() const
void setDesktops(QList< VirtualDesktop * > desktops)
void setHidden(bool hidden)
QList< KWin::VirtualDesktop * > desktops
void enterDesktop(VirtualDesktop *desktop)
virtual bool dockWantsInput() const
const WindowRules * rules() const
virtual xcb_timestamp_t userTime() const
bool isOnActiveOutput() const
virtual Window * findModal(bool allow_itself=false)=0
bool checkDisableGlobalShortcuts(bool disable) const
int checkFSP(int fsp) const
int checkFPP(int fpp) const
void windowAttentionChanged(Window *, bool set)
Window * mostRecentlyActivatedWindow() const
void windowHidden(Window *)
void activateWindow(Window *window, bool force=false)
const QList< Window * > & stackingOrder() const
void sendWindowToOutput(Window *window, Output *output)
Window * windowUnderMouse(Output *output) const
Window * findDesktop(bool topmost, VirtualDesktop *desktop) const
Output * activeOutput() const
friend Workspace * workspace()
void gotFocusIn(const Window *window)
void switchToOutput(Output *output)
void updateStackingOrder(bool propagate_new_windows=false)
void raiseWindow(Window *window, bool nogroup=false)
void windowActivated(KWin::Window *)
Window * lastActiveWindow() const
bool checkStartupNotification(xcb_window_t w, KStartupInfoId &id, KStartupInfoData &data)
void updateFocusMousePosition(const QPointF &pos)
bool showingDesktop() const
QList< Output * > outputs() const
void setActiveWindow(Window *window)
void sendWindowToDesktops(Window *window, const QList< VirtualDesktop * > &desktops, bool dont_activate)
bool activateNextWindow(Window *window)
bool requestFocus(Window *window, bool force=false)
void setActiveOutput(Output *output)
bool takeActivity(Window *window, ActivityFlags flags)
void setShowingDesktop(bool showing, bool animated=true)
SessionManager * sessionManager() const
void disableGlobalShortcutsForClient(bool disable)
Output * xineramaIndexToOutput(int index) const
bool focusChangeEnabled()
void setShouldGetFocus(Window *window)
QList< Window * > mainWindows() const override
bool isTransient() const override
void doSetActive() override
void updateUserTime(xcb_timestamp_t time=XCB_TIME_CURRENT_TIME)
xcb_window_t window() const
bool allowWindowActivation(xcb_timestamp_t time=-1U, bool focus_in=false)
const Group * group() const override
static bool belongToSameApplication(const X11Window *c1, const X11Window *c2, SameApplicationChecks checks=SameApplicationChecks())
xcb_timestamp_t userTime() const override
bool groupTransient() const override
KWIN_EXPORT xcb_timestamp_t xTime()
KWIN_EXPORT Atoms * atoms