Changeset View
Changeset View
Standalone View
Standalone View
client.cpp
Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Line(s) | |||||
81 | // | 81 | // | ||
82 | // Destroying a client: | 82 | // Destroying a client: | ||
83 | // - destroyClient() - only when the window itself has been destroyed | 83 | // - destroyClient() - only when the window itself has been destroyed | ||
84 | // - releaseWindow() - the window is kept, only the client itself is destroyed | 84 | // - releaseWindow() - the window is kept, only the client itself is destroyed | ||
85 | 85 | | |||
86 | /** | 86 | /** | ||
87 | * \class Client client.h | 87 | * \class Client client.h | ||
88 | * \brief The Client class encapsulates a window decoration frame. | 88 | * \brief The Client class encapsulates a window decoration frame. | ||
89 | */ | 89 | **/ | ||
90 | 90 | | |||
91 | /** | 91 | /** | ||
92 | * This ctor is "dumb" - it only initializes data. All the real initialization | 92 | * This ctor is "dumb" - it only initializes data. All the real initialization | ||
93 | * is done in manage(). | 93 | * is done in manage(). | ||
94 | */ | 94 | **/ | ||
95 | Client::Client() | 95 | Client::Client() | ||
96 | : AbstractClient() | 96 | : AbstractClient() | ||
97 | , m_client() | 97 | , m_client() | ||
98 | , m_wrapper() | 98 | , m_wrapper() | ||
99 | , m_frame() | 99 | , m_frame() | ||
100 | , m_activityUpdatesBlocked(false) | 100 | , m_activityUpdatesBlocked(false) | ||
101 | , m_blockedActivityUpdatesRequireTransients(false) | 101 | , m_blockedActivityUpdatesRequireTransients(false) | ||
102 | , m_moveResizeGrabWindow() | 102 | , m_moveResizeGrabWindow() | ||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Line(s) | 178 | else | |||
179 | m_client.deleteProperty(atoms->kde_net_wm_tab_group); | 179 | m_client.deleteProperty(atoms->kde_net_wm_tab_group); | ||
180 | }); | 180 | }); | ||
181 | 181 | | |||
182 | // SELI TODO: Initialize xsizehints?? | 182 | // SELI TODO: Initialize xsizehints?? | ||
183 | } | 183 | } | ||
184 | 184 | | |||
185 | /** | 185 | /** | ||
186 | * "Dumb" destructor. | 186 | * "Dumb" destructor. | ||
187 | */ | 187 | **/ | ||
188 | Client::~Client() | 188 | Client::~Client() | ||
189 | { | 189 | { | ||
190 | if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive | 190 | if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive | ||
191 | ::kill(m_killHelperPID, SIGTERM); | 191 | ::kill(m_killHelperPID, SIGTERM); | ||
192 | m_killHelperPID = 0; | 192 | m_killHelperPID = 0; | ||
193 | } | 193 | } | ||
194 | //SWrapper::Client::clientRelease(this); | 194 | //SWrapper::Client::clientRelease(this); | ||
195 | if (syncRequest.alarm != XCB_NONE) | 195 | if (syncRequest.alarm != XCB_NONE) | ||
Show All 11 Lines | |||||
207 | // Use destroyClient() or releaseWindow(), Client instances cannot be deleted directly | 207 | // Use destroyClient() or releaseWindow(), Client instances cannot be deleted directly | ||
208 | void Client::deleteClient(Client* c) | 208 | void Client::deleteClient(Client* c) | ||
209 | { | 209 | { | ||
210 | delete c; | 210 | delete c; | ||
211 | } | 211 | } | ||
212 | 212 | | |||
213 | /** | 213 | /** | ||
214 | * Releases the window. The client has done its job and the window is still existing. | 214 | * Releases the window. The client has done its job and the window is still existing. | ||
215 | */ | 215 | **/ | ||
216 | void Client::releaseWindow(bool on_shutdown) | 216 | void Client::releaseWindow(bool on_shutdown) | ||
217 | { | 217 | { | ||
218 | assert(!deleting); | 218 | assert(!deleting); | ||
219 | deleting = true; | 219 | deleting = true; | ||
220 | destroyWindowManagementInterface(); | 220 | destroyWindowManagementInterface(); | ||
221 | Deleted* del = NULL; | 221 | Deleted* del = NULL; | ||
222 | if (!on_shutdown) { | 222 | if (!on_shutdown) { | ||
223 | del = Deleted::create(this); | 223 | del = Deleted::create(this); | ||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Line(s) | |||||
277 | } | 277 | } | ||
278 | deleteClient(this); | 278 | deleteClient(this); | ||
279 | ungrabXServer(); | 279 | ungrabXServer(); | ||
280 | } | 280 | } | ||
281 | 281 | | |||
282 | /** | 282 | /** | ||
283 | * Like releaseWindow(), but this one is called when the window has been already destroyed | 283 | * Like releaseWindow(), but this one is called when the window has been already destroyed | ||
284 | * (E.g. The application closed it) | 284 | * (E.g. The application closed it) | ||
285 | */ | 285 | **/ | ||
286 | void Client::destroyClient() | 286 | void Client::destroyClient() | ||
287 | { | 287 | { | ||
288 | assert(!deleting); | 288 | assert(!deleting); | ||
289 | deleting = true; | 289 | deleting = true; | ||
290 | destroyWindowManagementInterface(); | 290 | destroyWindowManagementInterface(); | ||
291 | Deleted* del = Deleted::create(this); | 291 | Deleted* del = Deleted::create(this); | ||
292 | if (isMoveResize()) | 292 | if (isMoveResize()) | ||
293 | emit clientFinishUserMovedResized(this); | 293 | emit clientFinishUserMovedResized(this); | ||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Line(s) | |||||
562 | } | 562 | } | ||
563 | 563 | | |||
564 | /** | 564 | /** | ||
565 | * Resizes the decoration, and makes sure the decoration widget gets resize event | 565 | * Resizes the decoration, and makes sure the decoration widget gets resize event | ||
566 | * even if the size hasn't changed. This is needed to make sure the decoration | 566 | * even if the size hasn't changed. This is needed to make sure the decoration | ||
567 | * re-layouts (e.g. when maximization state changes, | 567 | * re-layouts (e.g. when maximization state changes, | ||
568 | * the decoration may alter some borders, but the actual size | 568 | * the decoration may alter some borders, but the actual size | ||
569 | * of the decoration stays the same). | 569 | * of the decoration stays the same). | ||
570 | */ | 570 | **/ | ||
571 | void Client::resizeDecoration() | 571 | void Client::resizeDecoration() | ||
572 | { | 572 | { | ||
573 | triggerDecorationRepaint(); | 573 | triggerDecorationRepaint(); | ||
574 | updateInputWindow(); | 574 | updateInputWindow(); | ||
575 | } | 575 | } | ||
576 | 576 | | |||
577 | bool Client::userNoBorder() const | 577 | bool Client::userNoBorder() const | ||
578 | { | 578 | { | ||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Line(s) | 684 | { | |||
685 | if (hidden == hide) | 685 | if (hidden == hide) | ||
686 | return; | 686 | return; | ||
687 | hidden = hide; | 687 | hidden = hide; | ||
688 | updateVisibility(); | 688 | updateVisibility(); | ||
689 | } | 689 | } | ||
690 | 690 | | |||
691 | /** | 691 | /** | ||
692 | * Returns whether the window is minimizable or not | 692 | * Returns whether the window is minimizable or not | ||
693 | */ | 693 | **/ | ||
694 | bool Client::isMinimizable() const | 694 | bool Client::isMinimizable() const | ||
695 | { | 695 | { | ||
696 | if (isSpecialWindow() && !isTransient()) | 696 | if (isSpecialWindow() && !isTransient()) | ||
697 | return false; | 697 | return false; | ||
698 | if (!rules()->checkMinimize(true)) | 698 | if (!rules()->checkMinimize(true)) | ||
699 | return false; | 699 | return false; | ||
700 | 700 | | |||
701 | if (isTransient()) { | 701 | if (isTransient()) { | ||
▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Line(s) | 889 | { | |||
925 | } | 925 | } | ||
926 | internalShow(); | 926 | internalShow(); | ||
927 | } | 927 | } | ||
928 | 928 | | |||
929 | 929 | | |||
930 | /** | 930 | /** | ||
931 | * Sets the client window's mapping state. Possible values are | 931 | * Sets the client window's mapping state. Possible values are | ||
932 | * WithdrawnState, IconicState, NormalState. | 932 | * WithdrawnState, IconicState, NormalState. | ||
933 | */ | 933 | **/ | ||
934 | void Client::exportMappingState(int s) | 934 | void Client::exportMappingState(int s) | ||
935 | { | 935 | { | ||
936 | assert(m_client != XCB_WINDOW_NONE); | 936 | assert(m_client != XCB_WINDOW_NONE); | ||
937 | assert(!deleting || s == WithdrawnState); | 937 | assert(!deleting || s == WithdrawnState); | ||
938 | if (s == WithdrawnState) { | 938 | if (s == WithdrawnState) { | ||
939 | m_client.deleteProperty(atoms->wm_state); | 939 | m_client.deleteProperty(atoms->wm_state); | ||
940 | return; | 940 | return; | ||
941 | } | 941 | } | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 981 | { | |||
993 | addWorkspaceRepaint(visibleRect()); | 993 | addWorkspaceRepaint(visibleRect()); | ||
994 | workspace()->clientHidden(this); | 994 | workspace()->clientHidden(this); | ||
995 | } | 995 | } | ||
996 | 996 | | |||
997 | /** | 997 | /** | ||
998 | * Maps (shows) the client. Note that it is mapping state of the frame, | 998 | * Maps (shows) the client. Note that it is mapping state of the frame, | ||
999 | * not necessarily the client window itself (i.e. a shaded window is here | 999 | * not necessarily the client window itself (i.e. a shaded window is here | ||
1000 | * considered mapped, even though it is in IconicState). | 1000 | * considered mapped, even though it is in IconicState). | ||
1001 | */ | 1001 | **/ | ||
1002 | void Client::map() | 1002 | void Client::map() | ||
1003 | { | 1003 | { | ||
1004 | // XComposite invalidates backing pixmaps on unmap (minimize, different | 1004 | // XComposite invalidates backing pixmaps on unmap (minimize, different | ||
1005 | // virtual desktop, etc.). We kept the last known good pixmap around | 1005 | // virtual desktop, etc.). We kept the last known good pixmap around | ||
1006 | // for use in effects, but now we want to have access to the new pixmap | 1006 | // for use in effects, but now we want to have access to the new pixmap | ||
1007 | if (compositing()) | 1007 | if (compositing()) | ||
1008 | discardWindowPixmap(); | 1008 | discardWindowPixmap(); | ||
1009 | m_frame.map(); | 1009 | m_frame.map(); | ||
1010 | if (!isShade()) { | 1010 | if (!isShade()) { | ||
1011 | m_wrapper.map(); | 1011 | m_wrapper.map(); | ||
1012 | m_client.map(); | 1012 | m_client.map(); | ||
1013 | m_decoInputExtent.map(); | 1013 | m_decoInputExtent.map(); | ||
1014 | exportMappingState(NormalState); | 1014 | exportMappingState(NormalState); | ||
1015 | } else | 1015 | } else | ||
1016 | exportMappingState(IconicState); | 1016 | exportMappingState(IconicState); | ||
1017 | addLayerRepaint(visibleRect()); | 1017 | addLayerRepaint(visibleRect()); | ||
1018 | } | 1018 | } | ||
1019 | 1019 | | |||
1020 | /** | 1020 | /** | ||
1021 | * Unmaps the client. Again, this is about the frame. | 1021 | * Unmaps the client. Again, this is about the frame. | ||
1022 | */ | 1022 | **/ | ||
1023 | void Client::unmap() | 1023 | void Client::unmap() | ||
1024 | { | 1024 | { | ||
1025 | // Here it may look like a race condition, as some other client might try to unmap | 1025 | // Here it may look like a race condition, as some other client might try to unmap | ||
1026 | // the window between these two XSelectInput() calls. However, they're supposed to | 1026 | // the window between these two XSelectInput() calls. However, they're supposed to | ||
1027 | // use XWithdrawWindow(), which also sends a synthetic event to the root window, | 1027 | // use XWithdrawWindow(), which also sends a synthetic event to the root window, | ||
1028 | // which won't be missed, so this shouldn't be a problem. The chance the real UnmapNotify | 1028 | // which won't be missed, so this shouldn't be a problem. The chance the real UnmapNotify | ||
1029 | // will be missed is also very minimal, so I don't think it's needed to grab the server | 1029 | // will be missed is also very minimal, so I don't think it's needed to grab the server | ||
1030 | // here. | 1030 | // here. | ||
Show All 11 Lines | |||||
1042 | * there wouldn't be any previews of windows that are minimized or on another | 1042 | * there wouldn't be any previews of windows that are minimized or on another | ||
1043 | * virtual desktop. Therefore rawHide() actually keeps such windows mapped. | 1043 | * virtual desktop. Therefore rawHide() actually keeps such windows mapped. | ||
1044 | * However special care needs to be taken so that such windows don't interfere. | 1044 | * However special care needs to be taken so that such windows don't interfere. | ||
1045 | * Therefore they're put very low in the stacking order and they have input shape | 1045 | * Therefore they're put very low in the stacking order and they have input shape | ||
1046 | * set to none, which hopefully is enough. If there's no input shape available, | 1046 | * set to none, which hopefully is enough. If there's no input shape available, | ||
1047 | * then it's hoped that there will be some other desktop above it *shrug*. | 1047 | * then it's hoped that there will be some other desktop above it *shrug*. | ||
1048 | * Using normal shape would be better, but that'd affect other things, e.g. painting | 1048 | * Using normal shape would be better, but that'd affect other things, e.g. painting | ||
1049 | * of the actual preview. | 1049 | * of the actual preview. | ||
1050 | */ | 1050 | **/ | ||
1051 | void Client::updateHiddenPreview() | 1051 | void Client::updateHiddenPreview() | ||
1052 | { | 1052 | { | ||
1053 | if (hiddenPreview()) { | 1053 | if (hiddenPreview()) { | ||
1054 | workspace()->forceRestacking(); | 1054 | workspace()->forceRestacking(); | ||
1055 | if (Xcb::Extensions::self()->isShapeInputAvailable()) { | 1055 | if (Xcb::Extensions::self()->isShapeInputAvailable()) { | ||
1056 | xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, | 1056 | xcb_shape_rectangles(connection(), XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, | ||
1057 | XCB_CLIP_ORDERING_UNSORTED, frameId(), 0, 0, 0, NULL); | 1057 | XCB_CLIP_ORDERING_UNSORTED, frameId(), 0, 0, 0, NULL); | ||
1058 | } | 1058 | } | ||
Show All 21 Lines | 1079 | if (w == rootWindow()) { | |||
1080 | eventMask = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; // Magic! | 1080 | eventMask = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT; // Magic! | ||
1081 | } | 1081 | } | ||
1082 | xcb_send_event(connection(), false, w, eventMask, reinterpret_cast<const char*>(&ev)); | 1082 | xcb_send_event(connection(), false, w, eventMask, reinterpret_cast<const char*>(&ev)); | ||
1083 | xcb_flush(connection()); | 1083 | xcb_flush(connection()); | ||
1084 | } | 1084 | } | ||
1085 | 1085 | | |||
1086 | /** | 1086 | /** | ||
1087 | * Returns whether the window may be closed (have a close button) | 1087 | * Returns whether the window may be closed (have a close button) | ||
1088 | */ | 1088 | **/ | ||
1089 | bool Client::isCloseable() const | 1089 | bool Client::isCloseable() const | ||
1090 | { | 1090 | { | ||
1091 | return rules()->checkCloseable(m_motif.close() && !isSpecialWindow()); | 1091 | return rules()->checkCloseable(m_motif.close() && !isSpecialWindow()); | ||
1092 | } | 1092 | } | ||
1093 | 1093 | | |||
1094 | /** | 1094 | /** | ||
1095 | * Closes the window by either sending a delete_window message or using XKill. | 1095 | * Closes the window by either sending a delete_window message or using XKill. | ||
1096 | */ | 1096 | **/ | ||
1097 | void Client::closeWindow() | 1097 | void Client::closeWindow() | ||
1098 | { | 1098 | { | ||
1099 | if (!isCloseable()) | 1099 | if (!isCloseable()) | ||
1100 | return; | 1100 | return; | ||
1101 | 1101 | | |||
1102 | // Update user time, because the window may create a confirming dialog. | 1102 | // Update user time, because the window may create a confirming dialog. | ||
1103 | updateUserTime(); | 1103 | updateUserTime(); | ||
1104 | 1104 | | |||
1105 | if (info->supportsProtocol(NET::DeleteWindowProtocol)) { | 1105 | if (info->supportsProtocol(NET::DeleteWindowProtocol)) { | ||
1106 | sendClientMessage(window(), atoms->wm_protocols, atoms->wm_delete_window); | 1106 | sendClientMessage(window(), atoms->wm_protocols, atoms->wm_delete_window); | ||
1107 | pingWindow(); | 1107 | pingWindow(); | ||
1108 | } else // Client will not react on wm_delete_window. We have not choice | 1108 | } else // Client will not react on wm_delete_window. We have not choice | ||
1109 | // but destroy his connection to the XServer. | 1109 | // but destroy his connection to the XServer. | ||
1110 | killWindow(); | 1110 | killWindow(); | ||
1111 | } | 1111 | } | ||
1112 | 1112 | | |||
1113 | 1113 | | |||
1114 | /** | 1114 | /** | ||
1115 | * Kills the window via XKill | 1115 | * Kills the window via XKill | ||
1116 | */ | 1116 | **/ | ||
1117 | void Client::killWindow() | 1117 | void Client::killWindow() | ||
1118 | { | 1118 | { | ||
1119 | qCDebug(KWIN_CORE) << "Client::killWindow():" << caption(); | 1119 | qCDebug(KWIN_CORE) << "Client::killWindow():" << caption(); | ||
1120 | killProcess(false); | 1120 | killProcess(false); | ||
1121 | m_client.kill(); // Always kill this client at the server | 1121 | m_client.kill(); // Always kill this client at the server | ||
1122 | destroyClient(); | 1122 | destroyClient(); | ||
1123 | } | 1123 | } | ||
1124 | 1124 | | |||
1125 | /** | 1125 | /** | ||
1126 | * Send a ping to the window using _NET_WM_PING if possible if it | 1126 | * Send a ping to the window using _NET_WM_PING if possible if it | ||
1127 | * doesn't respond within a reasonable time, it will be killed. | 1127 | * doesn't respond within a reasonable time, it will be killed. | ||
1128 | */ | 1128 | **/ | ||
1129 | void Client::pingWindow() | 1129 | void Client::pingWindow() | ||
1130 | { | 1130 | { | ||
1131 | if (!info->supportsProtocol(NET::PingProtocol)) | 1131 | if (!info->supportsProtocol(NET::PingProtocol)) | ||
1132 | return; // Can't ping :( | 1132 | return; // Can't ping :( | ||
1133 | if (options->killPingTimeout() == 0) | 1133 | if (options->killPingTimeout() == 0) | ||
1134 | return; // Turned off | 1134 | return; // Turned off | ||
1135 | if (ping_timer != NULL) | 1135 | if (ping_timer != NULL) | ||
1136 | return; // Pinging already | 1136 | return; // Pinging already | ||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Line(s) | |||||
1232 | } | 1232 | } | ||
1233 | 1233 | | |||
1234 | /** | 1234 | /** | ||
1235 | * Sets whether the client is on @p activity. | 1235 | * Sets whether the client is on @p activity. | ||
1236 | * If you remove it from its last activity, then it's on all activities. | 1236 | * If you remove it from its last activity, then it's on all activities. | ||
1237 | * | 1237 | * | ||
1238 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | 1238 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | ||
1239 | * I don't think that's an important enough use case to handle here. | 1239 | * I don't think that's an important enough use case to handle here. | ||
1240 | */ | 1240 | **/ | ||
1241 | void Client::setOnActivity(const QString &activity, bool enable) | 1241 | void Client::setOnActivity(const QString &activity, bool enable) | ||
1242 | { | 1242 | { | ||
1243 | #ifdef KWIN_BUILD_ACTIVITIES | 1243 | #ifdef KWIN_BUILD_ACTIVITIES | ||
1244 | if (! Activities::self()) { | 1244 | if (! Activities::self()) { | ||
1245 | return; | 1245 | return; | ||
1246 | } | 1246 | } | ||
1247 | QStringList newActivitiesList = activities(); | 1247 | QStringList newActivitiesList = activities(); | ||
1248 | if (newActivitiesList.contains(activity) == enable) //nothing to do | 1248 | if (newActivitiesList.contains(activity) == enable) //nothing to do | ||
Show All 9 Lines | |||||
1258 | #else | 1258 | #else | ||
1259 | Q_UNUSED(activity) | 1259 | Q_UNUSED(activity) | ||
1260 | Q_UNUSED(enable) | 1260 | Q_UNUSED(enable) | ||
1261 | #endif | 1261 | #endif | ||
1262 | } | 1262 | } | ||
1263 | 1263 | | |||
1264 | /** | 1264 | /** | ||
1265 | * set exactly which activities this client is on | 1265 | * set exactly which activities this client is on | ||
1266 | */ | 1266 | **/ | ||
1267 | void Client::setOnActivities(QStringList newActivitiesList) | 1267 | void Client::setOnActivities(QStringList newActivitiesList) | ||
1268 | { | 1268 | { | ||
1269 | #ifdef KWIN_BUILD_ACTIVITIES | 1269 | #ifdef KWIN_BUILD_ACTIVITIES | ||
1270 | if (!Activities::self()) { | 1270 | if (!Activities::self()) { | ||
1271 | return; | 1271 | return; | ||
1272 | } | 1272 | } | ||
1273 | QString joinedActivitiesList = newActivitiesList.join(QStringLiteral(",")); | 1273 | QString joinedActivitiesList = newActivitiesList.join(QStringLiteral(",")); | ||
1274 | joinedActivitiesList = rules()->checkActivity(joinedActivitiesList, false); | 1274 | joinedActivitiesList = rules()->checkActivity(joinedActivitiesList, false); | ||
Show All 40 Lines | 1313 | } else { | |||
1315 | --m_activityUpdatesBlocked; | 1315 | --m_activityUpdatesBlocked; | ||
1316 | if (!m_activityUpdatesBlocked) | 1316 | if (!m_activityUpdatesBlocked) | ||
1317 | updateActivities(m_blockedActivityUpdatesRequireTransients); | 1317 | updateActivities(m_blockedActivityUpdatesRequireTransients); | ||
1318 | } | 1318 | } | ||
1319 | } | 1319 | } | ||
1320 | 1320 | | |||
1321 | /** | 1321 | /** | ||
1322 | * update after activities changed | 1322 | * update after activities changed | ||
1323 | */ | 1323 | **/ | ||
1324 | void Client::updateActivities(bool includeTransients) | 1324 | void Client::updateActivities(bool includeTransients) | ||
1325 | { | 1325 | { | ||
1326 | if (m_activityUpdatesBlocked) { | 1326 | if (m_activityUpdatesBlocked) { | ||
1327 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | 1327 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | ||
1328 | return; | 1328 | return; | ||
1329 | } | 1329 | } | ||
1330 | emit activitiesChanged(this); | 1330 | emit activitiesChanged(this); | ||
1331 | m_blockedActivityUpdatesRequireTransients = false; // reset | 1331 | m_blockedActivityUpdatesRequireTransients = false; // reset | ||
1332 | FocusChain::self()->update(this, FocusChain::MakeFirst); | 1332 | FocusChain::self()->update(this, FocusChain::MakeFirst); | ||
1333 | updateVisibility(); | 1333 | updateVisibility(); | ||
1334 | updateWindowRules(Rules::Activity); | 1334 | updateWindowRules(Rules::Activity); | ||
1335 | 1335 | | |||
1336 | // Update states of all other windows in this group | 1336 | // Update states of all other windows in this group | ||
1337 | if (tabGroup()) | 1337 | if (tabGroup()) | ||
1338 | tabGroup()->updateStates(this, TabGroup::Activity); | 1338 | tabGroup()->updateStates(this, TabGroup::Activity); | ||
1339 | } | 1339 | } | ||
1340 | 1340 | | |||
1341 | /** | 1341 | /** | ||
1342 | * Returns the list of activities the client window is on. | 1342 | * Returns the list of activities the client window is on. | ||
1343 | * if it's on all activities, the list will be empty. | 1343 | * if it's on all activities, the list will be empty. | ||
1344 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | 1344 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | ||
1345 | */ | 1345 | **/ | ||
1346 | QStringList Client::activities() const | 1346 | QStringList Client::activities() const | ||
1347 | { | 1347 | { | ||
1348 | if (sessionActivityOverride) { | 1348 | if (sessionActivityOverride) { | ||
1349 | return QStringList(); | 1349 | return QStringList(); | ||
1350 | } | 1350 | } | ||
1351 | return activityList; | 1351 | return activityList; | ||
1352 | } | 1352 | } | ||
1353 | 1353 | | |||
1354 | /** | 1354 | /** | ||
1355 | * if @p on is true, sets on all activities. | 1355 | * if @p on is true, sets on all activities. | ||
1356 | * if it's false, sets it to only be on the current activity | 1356 | * if it's false, sets it to only be on the current activity | ||
1357 | */ | 1357 | **/ | ||
1358 | void Client::setOnAllActivities(bool on) | 1358 | void Client::setOnAllActivities(bool on) | ||
1359 | { | 1359 | { | ||
1360 | #ifdef KWIN_BUILD_ACTIVITIES | 1360 | #ifdef KWIN_BUILD_ACTIVITIES | ||
1361 | if (on == isOnAllActivities()) | 1361 | if (on == isOnAllActivities()) | ||
1362 | return; | 1362 | return; | ||
1363 | if (on) { | 1363 | if (on) { | ||
1364 | setOnActivities(QStringList()); | 1364 | setOnActivities(QStringList()); | ||
1365 | 1365 | | |||
1366 | } else { | 1366 | } else { | ||
1367 | setOnActivity(Activities::self()->current(), true); | 1367 | setOnActivity(Activities::self()->current(), true); | ||
1368 | } | 1368 | } | ||
1369 | #else | 1369 | #else | ||
1370 | Q_UNUSED(on) | 1370 | Q_UNUSED(on) | ||
1371 | #endif | 1371 | #endif | ||
1372 | } | 1372 | } | ||
1373 | 1373 | | |||
1374 | /** | 1374 | /** | ||
1375 | * Performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS | 1375 | * Performs the actual focusing of the window using XSetInputFocus and WM_TAKE_FOCUS | ||
1376 | */ | 1376 | **/ | ||
1377 | void Client::takeFocus() | 1377 | void Client::takeFocus() | ||
1378 | { | 1378 | { | ||
1379 | if (rules()->checkAcceptFocus(info->input())) | 1379 | if (rules()->checkAcceptFocus(info->input())) | ||
1380 | m_client.focus(); | 1380 | m_client.focus(); | ||
1381 | else | 1381 | else | ||
1382 | demandAttention(false); // window cannot take input, at least withdraw urgency | 1382 | demandAttention(false); // window cannot take input, at least withdraw urgency | ||
1383 | if (info->supportsProtocol(NET::TakeFocusProtocol)) { | 1383 | if (info->supportsProtocol(NET::TakeFocusProtocol)) { | ||
1384 | sendClientMessage(window(), atoms->wm_protocols, atoms->wm_take_focus, 0, 0, 0, XCB_CURRENT_TIME); | 1384 | sendClientMessage(window(), atoms->wm_protocols, atoms->wm_take_focus, 0, 0, 0, XCB_CURRENT_TIME); | ||
Show All 14 Lines | |||||
1399 | } | 1399 | } | ||
1400 | 1400 | | |||
1401 | /** | 1401 | /** | ||
1402 | * Returns whether the window provides context help or not. If it does, | 1402 | * Returns whether the window provides context help or not. If it does, | ||
1403 | * you should show a help menu item or a help button like '?' and call | 1403 | * you should show a help menu item or a help button like '?' and call | ||
1404 | * contextHelp() if this is invoked. | 1404 | * contextHelp() if this is invoked. | ||
1405 | * | 1405 | * | ||
1406 | * \sa contextHelp() | 1406 | * \sa contextHelp() | ||
1407 | */ | 1407 | **/ | ||
1408 | bool Client::providesContextHelp() const | 1408 | bool Client::providesContextHelp() const | ||
1409 | { | 1409 | { | ||
1410 | return info->supportsProtocol(NET::ContextHelpProtocol); | 1410 | return info->supportsProtocol(NET::ContextHelpProtocol); | ||
1411 | } | 1411 | } | ||
1412 | 1412 | | |||
1413 | /** | 1413 | /** | ||
1414 | * Invokes context help on the window. Only works if the window | 1414 | * Invokes context help on the window. Only works if the window | ||
1415 | * actually provides context help. | 1415 | * actually provides context help. | ||
1416 | * | 1416 | * | ||
1417 | * \sa providesContextHelp() | 1417 | * \sa providesContextHelp() | ||
1418 | */ | 1418 | **/ | ||
1419 | void Client::showContextHelp() | 1419 | void Client::showContextHelp() | ||
1420 | { | 1420 | { | ||
1421 | if (info->supportsProtocol(NET::ContextHelpProtocol)) { | 1421 | if (info->supportsProtocol(NET::ContextHelpProtocol)) { | ||
1422 | sendClientMessage(window(), atoms->wm_protocols, atoms->net_wm_context_help); | 1422 | sendClientMessage(window(), atoms->wm_protocols, atoms->net_wm_context_help); | ||
1423 | } | 1423 | } | ||
1424 | } | 1424 | } | ||
1425 | 1425 | | |||
1426 | /** | 1426 | /** | ||
1427 | * Fetches the window's caption (WM_NAME property). It will be | 1427 | * Fetches the window's caption (WM_NAME property). It will be | ||
1428 | * stored in the client's caption(). | 1428 | * stored in the client's caption(). | ||
1429 | */ | 1429 | **/ | ||
1430 | void Client::fetchName() | 1430 | void Client::fetchName() | ||
1431 | { | 1431 | { | ||
1432 | setCaption(readName()); | 1432 | setCaption(readName()); | ||
1433 | } | 1433 | } | ||
1434 | 1434 | | |||
1435 | static inline QString readNameProperty(xcb_window_t w, xcb_atom_t atom) | 1435 | static inline QString readNameProperty(xcb_window_t w, xcb_atom_t atom) | ||
1436 | { | 1436 | { | ||
1437 | const auto cookie = xcb_icccm_get_text_property_unchecked(connection(), w, atom); | 1437 | const auto cookie = xcb_icccm_get_text_property_unchecked(connection(), w, atom); | ||
▲ Show 20 Lines • Show All 226 Lines • ▼ Show 20 Line(s) | 1657 | } else { | |||
1664 | xcb_sync_change_alarm_aux(c, syncRequest.alarm, XCB_SYNC_CA_DELTA | XCB_SYNC_CA_VALUE, &value); | 1664 | xcb_sync_change_alarm_aux(c, syncRequest.alarm, XCB_SYNC_CA_DELTA | XCB_SYNC_CA_VALUE, &value); | ||
1665 | } | 1665 | } | ||
1666 | } | 1666 | } | ||
1667 | } | 1667 | } | ||
1668 | } | 1668 | } | ||
1669 | 1669 | | |||
1670 | /** | 1670 | /** | ||
1671 | * Send the client a _NET_SYNC_REQUEST | 1671 | * Send the client a _NET_SYNC_REQUEST | ||
1672 | */ | 1672 | **/ | ||
1673 | void Client::sendSyncRequest() | 1673 | void Client::sendSyncRequest() | ||
1674 | { | 1674 | { | ||
1675 | if (syncRequest.counter == XCB_NONE || syncRequest.isPending) | 1675 | if (syncRequest.counter == XCB_NONE || syncRequest.isPending) | ||
1676 | return; // do NOT, NEVER send a sync request when there's one on the stack. the clients will just stop respoding. FOREVER! ... | 1676 | return; // do NOT, NEVER send a sync request when there's one on the stack. the clients will just stop respoding. FOREVER! ... | ||
1677 | 1677 | | |||
1678 | if (!syncRequest.failsafeTimeout) { | 1678 | if (!syncRequest.failsafeTimeout) { | ||
1679 | syncRequest.failsafeTimeout = new QTimer(this); | 1679 | syncRequest.failsafeTimeout = new QTimer(this); | ||
1680 | connect(syncRequest.failsafeTimeout, &QTimer::timeout, this, | 1680 | connect(syncRequest.failsafeTimeout, &QTimer::timeout, this, | ||
▲ Show 20 Lines • Show All 430 Lines • Show Last 20 Lines |