Changeset View
Changeset View
Standalone View
Standalone View
client.cpp
Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Line(s) | 166 | if (m_decoInputExtent.isValid()) | |||
---|---|---|---|---|---|
167 | m_decoInputExtent.defineCursor(nativeCursor); | 167 | m_decoInputExtent.defineCursor(nativeCursor); | ||
168 | if (isMoveResize()) { | 168 | if (isMoveResize()) { | ||
169 | // changing window attributes doesn't change cursor if there's pointer grab active | 169 | // changing window attributes doesn't change cursor if there's pointer grab active | ||
170 | xcb_change_active_pointer_grab(connection(), nativeCursor, xTime(), | 170 | xcb_change_active_pointer_grab(connection(), nativeCursor, xTime(), | ||
171 | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW); | 171 | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW); | ||
172 | } | 172 | } | ||
173 | }); | 173 | }); | ||
174 | 174 | | |||
175 | connect(this, &Client::tabGroupChanged, this, | | |||
176 | [this] { | | |||
177 | auto group = tabGroup(); | | |||
178 | if (group) { | | |||
179 | unsigned long data[] = {qHash(group)}; //->id(); | | |||
180 | m_client.changeProperty(atoms->kde_net_wm_tab_group, XCB_ATOM_CARDINAL, 32, 1, data); | | |||
181 | } | | |||
182 | else | | |||
183 | m_client.deleteProperty(atoms->kde_net_wm_tab_group); | | |||
184 | }); | | |||
185 | | ||||
186 | // SELI TODO: Initialize xsizehints?? | 175 | // SELI TODO: Initialize xsizehints?? | ||
187 | } | 176 | } | ||
188 | 177 | | |||
189 | /** | 178 | /** | ||
190 | * "Dumb" destructor. | 179 | * "Dumb" destructor. | ||
191 | */ | 180 | */ | ||
192 | Client::~Client() | 181 | Client::~Client() | ||
193 | { | 182 | { | ||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Line(s) | 218 | #endif | |||
255 | m_frame.unmap(); // Destroying decoration would cause ugly visual effect | 244 | m_frame.unmap(); // Destroying decoration would cause ugly visual effect | ||
256 | destroyDecoration(); | 245 | destroyDecoration(); | ||
257 | cleanGrouping(); | 246 | cleanGrouping(); | ||
258 | if (!on_shutdown) { | 247 | if (!on_shutdown) { | ||
259 | workspace()->removeClient(this); | 248 | workspace()->removeClient(this); | ||
260 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | 249 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | ||
261 | info->setDesktop(0); | 250 | info->setDesktop(0); | ||
262 | info->setState(0, info->state()); // Reset all state flags | 251 | info->setState(0, info->state()); // Reset all state flags | ||
263 | } else | 252 | } | ||
264 | untab(); | | |||
265 | xcb_connection_t *c = connection(); | 253 | xcb_connection_t *c = connection(); | ||
266 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | 254 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | ||
267 | m_client.deleteProperty(atoms->net_frame_extents); | 255 | m_client.deleteProperty(atoms->net_frame_extents); | ||
268 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | 256 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | ||
269 | m_client.reparent(rootWindow(), x(), y()); | 257 | m_client.reparent(rootWindow(), x(), y()); | ||
270 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | 258 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | ||
271 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | 259 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | ||
272 | if (on_shutdown) | 260 | if (on_shutdown) | ||
▲ Show 20 Lines • Show All 341 Lines • ▼ Show 20 Line(s) | |||||
614 | 602 | | |||
615 | bool Client::noBorder() const | 603 | bool Client::noBorder() const | ||
616 | { | 604 | { | ||
617 | return userNoBorder() || isFullScreen(); | 605 | return userNoBorder() || isFullScreen(); | ||
618 | } | 606 | } | ||
619 | 607 | | |||
620 | bool Client::userCanSetNoBorder() const | 608 | bool Client::userCanSetNoBorder() const | ||
621 | { | 609 | { | ||
622 | return !isFullScreen() && !isShade() && !tabGroup(); | 610 | return !isFullScreen() && !isShade(); | ||
623 | } | 611 | } | ||
624 | 612 | | |||
625 | void Client::setNoBorder(bool set) | 613 | void Client::setNoBorder(bool set) | ||
626 | { | 614 | { | ||
627 | if (!userCanSetNoBorder()) | 615 | if (!userCanSetNoBorder()) | ||
628 | return; | 616 | return; | ||
629 | set = rules()->checkNoBorder(set); | 617 | set = rules()->checkNoBorder(set); | ||
630 | if (noborder == set) | 618 | if (noborder == set) | ||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Line(s) | 759 | #endif | |||
774 | return true; | 762 | return true; | ||
775 | } | 763 | } | ||
776 | 764 | | |||
777 | void Client::doMinimize() | 765 | void Client::doMinimize() | ||
778 | { | 766 | { | ||
779 | updateVisibility(); | 767 | updateVisibility(); | ||
780 | updateAllowedActions(); | 768 | updateAllowedActions(); | ||
781 | workspace()->updateMinimizedOfTransients(this); | 769 | workspace()->updateMinimizedOfTransients(this); | ||
782 | // Update states of all other windows in this group | | |||
783 | if (tabGroup()) | | |||
784 | tabGroup()->updateStates(this, TabGroup::Minimized); | | |||
785 | } | 770 | } | ||
786 | 771 | | |||
787 | QRect Client::iconGeometry() const | 772 | QRect Client::iconGeometry() const | ||
788 | { | 773 | { | ||
789 | NETRect r = info->iconGeometry(); | 774 | NETRect r = info->iconGeometry(); | ||
790 | QRect geom(r.pos.x, r.pos.y, r.size.width, r.size.height); | 775 | QRect geom(r.pos.x, r.pos.y, r.size.width, r.size.height); | ||
791 | if (geom.isValid()) | 776 | if (geom.isValid()) | ||
792 | return geom; | 777 | return geom; | ||
Show All 33 Lines | 800 | { | |||
826 | 811 | | |||
827 | // Decorations may turn off some borders when shaded | 812 | // Decorations may turn off some borders when shaded | ||
828 | // this has to happen _before_ the tab alignment since it will restrict the minimum geometry | 813 | // this has to happen _before_ the tab alignment since it will restrict the minimum geometry | ||
829 | #if 0 | 814 | #if 0 | ||
830 | if (decoration) | 815 | if (decoration) | ||
831 | decoration->borders(border_left, border_right, border_top, border_bottom); | 816 | decoration->borders(border_left, border_right, border_top, border_bottom); | ||
832 | #endif | 817 | #endif | ||
833 | 818 | | |||
834 | // Update states of all other windows in this group | | |||
835 | if (tabGroup()) | | |||
836 | tabGroup()->updateStates(this, TabGroup::Shaded); | | |||
837 | | ||||
838 | if (was_shade == isShade()) { | 819 | if (was_shade == isShade()) { | ||
839 | // Decoration may want to update after e.g. hover-shade changes | 820 | // Decoration may want to update after e.g. hover-shade changes | ||
840 | emit shadeChanged(); | 821 | emit shadeChanged(); | ||
841 | return; // No real change in shaded state | 822 | return; // No real change in shaded state | ||
842 | } | 823 | } | ||
843 | 824 | | |||
844 | assert(isDecorated()); // noborder windows can't be shaded | 825 | assert(isDecorated()); // noborder windows can't be shaded | ||
845 | GeometryUpdatesBlocker blocker(this); | 826 | GeometryUpdatesBlocker blocker(this); | ||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | |||||
912 | void Client::shadeHover() | 893 | void Client::shadeHover() | ||
913 | { | 894 | { | ||
914 | setShade(ShadeHover); | 895 | setShade(ShadeHover); | ||
915 | cancelShadeHoverTimer(); | 896 | cancelShadeHoverTimer(); | ||
916 | } | 897 | } | ||
917 | 898 | | |||
918 | void Client::shadeUnhover() | 899 | void Client::shadeUnhover() | ||
919 | { | 900 | { | ||
920 | if (!tabGroup() || tabGroup()->current() == this || | | |||
921 | tabGroup()->current()->shadeMode() == ShadeNormal) | | |||
922 | setShade(ShadeNormal); | 901 | setShade(ShadeNormal); | ||
923 | cancelShadeHoverTimer(); | 902 | cancelShadeHoverTimer(); | ||
924 | } | 903 | } | ||
925 | 904 | | |||
926 | void Client::cancelShadeHoverTimer() | 905 | void Client::cancelShadeHoverTimer() | ||
927 | { | 906 | { | ||
928 | delete shadeHoverTimer; | 907 | delete shadeHoverTimer; | ||
929 | shadeHoverTimer = 0; | 908 | shadeHoverTimer = 0; | ||
930 | } | 909 | } | ||
931 | 910 | | |||
932 | void Client::toggleShade() | 911 | void Client::toggleShade() | ||
933 | { | 912 | { | ||
934 | // If the mode is ShadeHover or ShadeActive, cancel shade too | 913 | // If the mode is ShadeHover or ShadeActive, cancel shade too | ||
935 | setShade(shade_mode == ShadeNone ? ShadeNormal : ShadeNone); | 914 | setShade(shade_mode == ShadeNone ? ShadeNormal : ShadeNone); | ||
936 | } | 915 | } | ||
937 | 916 | | |||
938 | void Client::updateVisibility() | 917 | void Client::updateVisibility() | ||
939 | { | 918 | { | ||
940 | if (deleting) | 919 | if (deleting) | ||
941 | return; | 920 | return; | ||
942 | if (hidden && isCurrentTab()) { | 921 | if (hidden) { | ||
943 | info->setState(NET::Hidden, NET::Hidden); | 922 | info->setState(NET::Hidden, NET::Hidden); | ||
944 | setSkipTaskbar(true); // Also hide from taskbar | 923 | setSkipTaskbar(true); // Also hide from taskbar | ||
945 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | 924 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | ||
946 | internalKeep(); | 925 | internalKeep(); | ||
947 | else | 926 | else | ||
948 | internalHide(); | 927 | internalHide(); | ||
949 | return; | 928 | return; | ||
950 | } | 929 | } | ||
951 | if (isCurrentTab()) | | |||
952 | setSkipTaskbar(originalSkipTaskbar()); // Reset from 'hidden' | | |||
zzag: Keep this one too. We need to restore the skip-taskbar state. | |||||
Right, I'll grep for all isCurrentTab that I removed, makes a lot of sense :) gladhorn: Right, I'll grep for all isCurrentTab that I removed, makes a lot of sense :) | |||||
953 | if (isMinimized()) { | 930 | if (isMinimized()) { | ||
954 | info->setState(NET::Hidden, NET::Hidden); | 931 | info->setState(NET::Hidden, NET::Hidden); | ||
955 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | 932 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | ||
956 | internalKeep(); | 933 | internalKeep(); | ||
957 | else | 934 | else | ||
958 | internalHide(); | 935 | internalHide(); | ||
959 | return; | 936 | return; | ||
960 | } | 937 | } | ||
▲ Show 20 Lines • Show All 309 Lines • ▼ Show 20 Line(s) | 1246 | { | |||
1270 | info->setState(skipSwitcher() ? NET::SkipSwitcher : NET::States(0), NET::SkipSwitcher); | 1247 | info->setState(skipSwitcher() ? NET::SkipSwitcher : NET::States(0), NET::SkipSwitcher); | ||
1271 | } | 1248 | } | ||
1272 | 1249 | | |||
1273 | void Client::doSetDesktop(int desktop, int was_desk) | 1250 | void Client::doSetDesktop(int desktop, int was_desk) | ||
1274 | { | 1251 | { | ||
1275 | Q_UNUSED(desktop) | 1252 | Q_UNUSED(desktop) | ||
1276 | Q_UNUSED(was_desk) | 1253 | Q_UNUSED(was_desk) | ||
1277 | updateVisibility(); | 1254 | updateVisibility(); | ||
1278 | | ||||
1279 | // Update states of all other windows in this group | | |||
1280 | if (tabGroup()) | | |||
1281 | tabGroup()->updateStates(this, TabGroup::Desktop); | | |||
1282 | } | 1255 | } | ||
1283 | 1256 | | |||
1284 | /** | 1257 | /** | ||
1285 | * Sets whether the client is on @p activity. | 1258 | * Sets whether the client is on @p activity. | ||
1286 | * If you remove it from its last activity, then it's on all activities. | 1259 | * If you remove it from its last activity, then it's on all activities. | ||
1287 | * | 1260 | * | ||
1288 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | 1261 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | ||
1289 | * I don't think that's an important enough use case to handle here. | 1262 | * I don't think that's an important enough use case to handle here. | ||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Line(s) | 1349 | if (m_activityUpdatesBlocked) { | |||
1377 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | 1350 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | ||
1378 | return; | 1351 | return; | ||
1379 | } | 1352 | } | ||
1380 | emit activitiesChanged(this); | 1353 | emit activitiesChanged(this); | ||
1381 | m_blockedActivityUpdatesRequireTransients = false; // reset | 1354 | m_blockedActivityUpdatesRequireTransients = false; // reset | ||
1382 | FocusChain::self()->update(this, FocusChain::MakeFirst); | 1355 | FocusChain::self()->update(this, FocusChain::MakeFirst); | ||
1383 | updateVisibility(); | 1356 | updateVisibility(); | ||
1384 | updateWindowRules(Rules::Activity); | 1357 | updateWindowRules(Rules::Activity); | ||
1385 | | ||||
1386 | // Update states of all other windows in this group | | |||
1387 | if (tabGroup()) | | |||
1388 | tabGroup()->updateStates(this, TabGroup::Activity); | | |||
1389 | } | 1358 | } | ||
1390 | 1359 | | |||
1391 | /** | 1360 | /** | ||
1392 | * Returns the list of activities the client window is on. | 1361 | * Returns the list of activities the client window is on. | ||
1393 | * if it's on all activities, the list will be empty. | 1362 | * if it's on all activities, the list will be empty. | ||
1394 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | 1363 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | ||
1395 | */ | 1364 | */ | ||
1396 | QStringList Client::activities() const | 1365 | QStringList Client::activities() const | ||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Line(s) | 1573 | if (options->isInactiveTabsSkipTaskbar()) | |||
1605 | setSkipTaskbar(hidden); // TODO: Causes reshuffle of the taskbar | 1574 | setSkipTaskbar(hidden); // TODO: Causes reshuffle of the taskbar | ||
1606 | if (shown) { | 1575 | if (shown) { | ||
1607 | map(); | 1576 | map(); | ||
1608 | takeFocus(); | 1577 | takeFocus(); | ||
1609 | autoRaise(); | 1578 | autoRaise(); | ||
1610 | FocusChain::self()->update(this, FocusChain::MakeFirst); | 1579 | FocusChain::self()->update(this, FocusChain::MakeFirst); | ||
1611 | } else { | 1580 | } else { | ||
1612 | unmap(); | 1581 | unmap(); | ||
1613 | // Don't move tabs to the end of the list when another tab get's activated | | |||
1614 | if (isCurrentTab()) | | |||
1615 | FocusChain::self()->update(this, FocusChain::MakeLast); | | |||
isCurrentTab is without tabs always true, right? So then this should be kept. romangg: `isCurrentTab` is without tabs always true, right? So then this should be kept. | |||||
gladhorn: Of course, thanks! | |||||
1616 | addWorkspaceRepaint(visibleRect()); | 1582 | addWorkspaceRepaint(visibleRect()); | ||
1617 | } | 1583 | } | ||
1618 | } | 1584 | } | ||
1619 | 1585 | | |||
1620 | void Client::getMotifHints() | 1586 | void Client::getMotifHints() | ||
1621 | { | 1587 | { | ||
1622 | const bool wasClosable = m_motif.close(); | 1588 | const bool wasClosable = m_motif.close(); | ||
1623 | const bool wasNoBorder = m_motif.noBorder(); | 1589 | const bool wasNoBorder = m_motif.noBorder(); | ||
▲ Show 20 Lines • Show All 482 Lines • ▼ Show 20 Line(s) | |||||
2106 | { | 2072 | { | ||
2107 | const Client *c2 = dynamic_cast<const Client*>(other); | 2073 | const Client *c2 = dynamic_cast<const Client*>(other); | ||
2108 | if (!c2) { | 2074 | if (!c2) { | ||
2109 | return false; | 2075 | return false; | ||
2110 | } | 2076 | } | ||
2111 | return Client::belongToSameApplication(this, c2, checks); | 2077 | return Client::belongToSameApplication(this, c2, checks); | ||
2112 | } | 2078 | } | ||
2113 | 2079 | | |||
2114 | void Client::updateTabGroupStates(TabGroup::States states) | | |||
2115 | { | | |||
2116 | if (auto t = tabGroup()) { | | |||
2117 | t->updateStates(this, states); | | |||
2118 | } | | |||
2119 | } | | |||
2120 | | ||||
2121 | QSize Client::resizeIncrements() const | 2080 | QSize Client::resizeIncrements() const | ||
2122 | { | 2081 | { | ||
2123 | return m_geometryHints.resizeIncrements(); | 2082 | return m_geometryHints.resizeIncrements(); | ||
2124 | } | 2083 | } | ||
2125 | 2084 | | |||
2126 | Xcb::StringProperty Client::fetchApplicationMenuServiceName() const | 2085 | Xcb::StringProperty Client::fetchApplicationMenuServiceName() const | ||
2127 | { | 2086 | { | ||
2128 | return Xcb::StringProperty(m_client, atoms->kde_net_wm_appmenu_service_name); | 2087 | return Xcb::StringProperty(m_client, atoms->kde_net_wm_appmenu_service_name); | ||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |
Keep this one too. We need to restore the skip-taskbar state.