Changeset View
Changeset View
Standalone View
Standalone View
client.cpp
Show First 20 Lines • Show All 164 Lines • ▼ Show 20 Line(s) | 164 | if (m_decoInputExtent.isValid()) | |||
---|---|---|---|---|---|
165 | m_decoInputExtent.defineCursor(nativeCursor); | 165 | m_decoInputExtent.defineCursor(nativeCursor); | ||
166 | if (isMoveResize()) { | 166 | if (isMoveResize()) { | ||
167 | // changing window attributes doesn't change cursor if there's pointer grab active | 167 | // changing window attributes doesn't change cursor if there's pointer grab active | ||
168 | xcb_change_active_pointer_grab(connection(), nativeCursor, xTime(), | 168 | xcb_change_active_pointer_grab(connection(), nativeCursor, xTime(), | ||
169 | 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); | 169 | 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); | ||
170 | } | 170 | } | ||
171 | }); | 171 | }); | ||
172 | 172 | | |||
173 | connect(this, &Client::tabGroupChanged, this, | | |||
174 | [this] { | | |||
175 | auto group = tabGroup(); | | |||
176 | if (group) { | | |||
177 | unsigned long data[] = {qHash(group)}; //->id(); | | |||
178 | m_client.changeProperty(atoms->kde_net_wm_tab_group, XCB_ATOM_CARDINAL, 32, 1, data); | | |||
179 | } | | |||
180 | else | | |||
181 | m_client.deleteProperty(atoms->kde_net_wm_tab_group); | | |||
182 | }); | | |||
183 | | ||||
184 | // SELI TODO: Initialize xsizehints?? | 173 | // SELI TODO: Initialize xsizehints?? | ||
185 | } | 174 | } | ||
186 | 175 | | |||
187 | /** | 176 | /** | ||
188 | * "Dumb" destructor. | 177 | * "Dumb" destructor. | ||
189 | */ | 178 | */ | ||
190 | Client::~Client() | 179 | Client::~Client() | ||
191 | { | 180 | { | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | 215 | #endif | |||
252 | m_frame.unmap(); // Destroying decoration would cause ugly visual effect | 241 | m_frame.unmap(); // Destroying decoration would cause ugly visual effect | ||
253 | destroyDecoration(); | 242 | destroyDecoration(); | ||
254 | cleanGrouping(); | 243 | cleanGrouping(); | ||
255 | if (!on_shutdown) { | 244 | if (!on_shutdown) { | ||
256 | workspace()->removeClient(this); | 245 | workspace()->removeClient(this); | ||
257 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | 246 | // Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7) | ||
258 | info->setDesktop(0); | 247 | info->setDesktop(0); | ||
259 | info->setState(0, info->state()); // Reset all state flags | 248 | info->setState(0, info->state()); // Reset all state flags | ||
260 | } else | 249 | } | ||
261 | untab(); | | |||
262 | xcb_connection_t *c = connection(); | 250 | xcb_connection_t *c = connection(); | ||
263 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | 251 | m_client.deleteProperty(atoms->kde_net_wm_user_creation_time); | ||
264 | m_client.deleteProperty(atoms->net_frame_extents); | 252 | m_client.deleteProperty(atoms->net_frame_extents); | ||
265 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | 253 | m_client.deleteProperty(atoms->kde_net_wm_frame_strut); | ||
266 | m_client.reparent(rootWindow(), x(), y()); | 254 | m_client.reparent(rootWindow(), x(), y()); | ||
267 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | 255 | xcb_change_save_set(c, XCB_SET_MODE_DELETE, m_client); | ||
268 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | 256 | m_client.selectInput(XCB_EVENT_MASK_NO_EVENT); | ||
269 | if (on_shutdown) | 257 | if (on_shutdown) | ||
▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Line(s) | |||||
609 | 597 | | |||
610 | bool Client::noBorder() const | 598 | bool Client::noBorder() const | ||
611 | { | 599 | { | ||
612 | return userNoBorder() || isFullScreen(); | 600 | return userNoBorder() || isFullScreen(); | ||
613 | } | 601 | } | ||
614 | 602 | | |||
615 | bool Client::userCanSetNoBorder() const | 603 | bool Client::userCanSetNoBorder() const | ||
616 | { | 604 | { | ||
617 | return !isFullScreen() && !isShade() && !tabGroup(); | 605 | return !isFullScreen() && !isShade(); | ||
618 | } | 606 | } | ||
619 | 607 | | |||
620 | void Client::setNoBorder(bool set) | 608 | void Client::setNoBorder(bool set) | ||
621 | { | 609 | { | ||
622 | if (!userCanSetNoBorder()) | 610 | if (!userCanSetNoBorder()) | ||
623 | return; | 611 | return; | ||
624 | set = rules()->checkNoBorder(set); | 612 | set = rules()->checkNoBorder(set); | ||
625 | if (noborder == set) | 613 | if (noborder == set) | ||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Line(s) | 754 | #endif | |||
769 | return true; | 757 | return true; | ||
770 | } | 758 | } | ||
771 | 759 | | |||
772 | void Client::doMinimize() | 760 | void Client::doMinimize() | ||
773 | { | 761 | { | ||
774 | updateVisibility(); | 762 | updateVisibility(); | ||
775 | updateAllowedActions(); | 763 | updateAllowedActions(); | ||
776 | workspace()->updateMinimizedOfTransients(this); | 764 | workspace()->updateMinimizedOfTransients(this); | ||
777 | // Update states of all other windows in this group | | |||
778 | if (tabGroup()) | | |||
779 | tabGroup()->updateStates(this, TabGroup::Minimized); | | |||
780 | } | 765 | } | ||
781 | 766 | | |||
782 | QRect Client::iconGeometry() const | 767 | QRect Client::iconGeometry() const | ||
783 | { | 768 | { | ||
784 | NETRect r = info->iconGeometry(); | 769 | NETRect r = info->iconGeometry(); | ||
785 | QRect geom(r.pos.x, r.pos.y, r.size.width, r.size.height); | 770 | QRect geom(r.pos.x, r.pos.y, r.size.width, r.size.height); | ||
786 | if (geom.isValid()) | 771 | if (geom.isValid()) | ||
787 | return geom; | 772 | return geom; | ||
Show All 33 Lines | 795 | { | |||
821 | 806 | | |||
822 | // Decorations may turn off some borders when shaded | 807 | // Decorations may turn off some borders when shaded | ||
823 | // this has to happen _before_ the tab alignment since it will restrict the minimum geometry | 808 | // this has to happen _before_ the tab alignment since it will restrict the minimum geometry | ||
824 | #if 0 | 809 | #if 0 | ||
825 | if (decoration) | 810 | if (decoration) | ||
826 | decoration->borders(border_left, border_right, border_top, border_bottom); | 811 | decoration->borders(border_left, border_right, border_top, border_bottom); | ||
827 | #endif | 812 | #endif | ||
828 | 813 | | |||
829 | // Update states of all other windows in this group | | |||
830 | if (tabGroup()) | | |||
831 | tabGroup()->updateStates(this, TabGroup::Shaded); | | |||
832 | | ||||
833 | if (was_shade == isShade()) { | 814 | if (was_shade == isShade()) { | ||
834 | // Decoration may want to update after e.g. hover-shade changes | 815 | // Decoration may want to update after e.g. hover-shade changes | ||
835 | emit shadeChanged(); | 816 | emit shadeChanged(); | ||
836 | return; // No real change in shaded state | 817 | return; // No real change in shaded state | ||
837 | } | 818 | } | ||
838 | 819 | | |||
839 | Q_ASSERT(isDecorated()); // noborder windows can't be shaded | 820 | Q_ASSERT(isDecorated()); // noborder windows can't be shaded | ||
840 | GeometryUpdatesBlocker blocker(this); | 821 | GeometryUpdatesBlocker blocker(this); | ||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | |||||
907 | void Client::shadeHover() | 888 | void Client::shadeHover() | ||
908 | { | 889 | { | ||
909 | setShade(ShadeHover); | 890 | setShade(ShadeHover); | ||
910 | cancelShadeHoverTimer(); | 891 | cancelShadeHoverTimer(); | ||
911 | } | 892 | } | ||
912 | 893 | | |||
913 | void Client::shadeUnhover() | 894 | void Client::shadeUnhover() | ||
914 | { | 895 | { | ||
915 | if (!tabGroup() || tabGroup()->current() == this || | | |||
916 | tabGroup()->current()->shadeMode() == ShadeNormal) | | |||
917 | setShade(ShadeNormal); | 896 | setShade(ShadeNormal); | ||
918 | cancelShadeHoverTimer(); | 897 | cancelShadeHoverTimer(); | ||
919 | } | 898 | } | ||
920 | 899 | | |||
921 | void Client::cancelShadeHoverTimer() | 900 | void Client::cancelShadeHoverTimer() | ||
922 | { | 901 | { | ||
923 | delete shadeHoverTimer; | 902 | delete shadeHoverTimer; | ||
924 | shadeHoverTimer = 0; | 903 | shadeHoverTimer = 0; | ||
925 | } | 904 | } | ||
926 | 905 | | |||
927 | void Client::toggleShade() | 906 | void Client::toggleShade() | ||
928 | { | 907 | { | ||
929 | // If the mode is ShadeHover or ShadeActive, cancel shade too | 908 | // If the mode is ShadeHover or ShadeActive, cancel shade too | ||
930 | setShade(shade_mode == ShadeNone ? ShadeNormal : ShadeNone); | 909 | setShade(shade_mode == ShadeNone ? ShadeNormal : ShadeNone); | ||
931 | } | 910 | } | ||
932 | 911 | | |||
933 | void Client::updateVisibility() | 912 | void Client::updateVisibility() | ||
934 | { | 913 | { | ||
935 | if (deleting) | 914 | if (deleting) | ||
936 | return; | 915 | return; | ||
937 | if (hidden && isCurrentTab()) { | 916 | if (hidden) { | ||
938 | info->setState(NET::Hidden, NET::Hidden); | 917 | info->setState(NET::Hidden, NET::Hidden); | ||
939 | setSkipTaskbar(true); // Also hide from taskbar | 918 | setSkipTaskbar(true); // Also hide from taskbar | ||
940 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | 919 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | ||
941 | internalKeep(); | 920 | internalKeep(); | ||
942 | else | 921 | else | ||
943 | internalHide(); | 922 | internalHide(); | ||
944 | return; | 923 | return; | ||
945 | } | 924 | } | ||
946 | if (isCurrentTab()) | | |||
947 | setSkipTaskbar(originalSkipTaskbar()); // Reset from 'hidden' | 925 | 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 :) | |||||
948 | if (isMinimized()) { | 926 | if (isMinimized()) { | ||
949 | info->setState(NET::Hidden, NET::Hidden); | 927 | info->setState(NET::Hidden, NET::Hidden); | ||
950 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | 928 | if (compositing() && options->hiddenPreviews() == HiddenPreviewsAlways) | ||
951 | internalKeep(); | 929 | internalKeep(); | ||
952 | else | 930 | else | ||
953 | internalHide(); | 931 | internalHide(); | ||
954 | return; | 932 | return; | ||
955 | } | 933 | } | ||
▲ Show 20 Lines • Show All 309 Lines • ▼ Show 20 Line(s) | 1242 | { | |||
1265 | info->setState(skipSwitcher() ? NET::SkipSwitcher : NET::States(0), NET::SkipSwitcher); | 1243 | info->setState(skipSwitcher() ? NET::SkipSwitcher : NET::States(0), NET::SkipSwitcher); | ||
1266 | } | 1244 | } | ||
1267 | 1245 | | |||
1268 | void Client::doSetDesktop(int desktop, int was_desk) | 1246 | void Client::doSetDesktop(int desktop, int was_desk) | ||
1269 | { | 1247 | { | ||
1270 | Q_UNUSED(desktop) | 1248 | Q_UNUSED(desktop) | ||
1271 | Q_UNUSED(was_desk) | 1249 | Q_UNUSED(was_desk) | ||
1272 | updateVisibility(); | 1250 | updateVisibility(); | ||
1273 | | ||||
1274 | // Update states of all other windows in this group | | |||
1275 | if (tabGroup()) | | |||
1276 | tabGroup()->updateStates(this, TabGroup::Desktop); | | |||
1277 | } | 1251 | } | ||
1278 | 1252 | | |||
1279 | /** | 1253 | /** | ||
1280 | * Sets whether the client is on @p activity. | 1254 | * Sets whether the client is on @p activity. | ||
1281 | * If you remove it from its last activity, then it's on all activities. | 1255 | * If you remove it from its last activity, then it's on all activities. | ||
1282 | * | 1256 | * | ||
1283 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | 1257 | * Note: If it was on all activities and you try to remove it from one, nothing will happen; | ||
1284 | * I don't think that's an important enough use case to handle here. | 1258 | * 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) | 1345 | if (m_activityUpdatesBlocked) { | |||
1372 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | 1346 | m_blockedActivityUpdatesRequireTransients |= includeTransients; | ||
1373 | return; | 1347 | return; | ||
1374 | } | 1348 | } | ||
1375 | emit activitiesChanged(this); | 1349 | emit activitiesChanged(this); | ||
1376 | m_blockedActivityUpdatesRequireTransients = false; // reset | 1350 | m_blockedActivityUpdatesRequireTransients = false; // reset | ||
1377 | FocusChain::self()->update(this, FocusChain::MakeFirst); | 1351 | FocusChain::self()->update(this, FocusChain::MakeFirst); | ||
1378 | updateVisibility(); | 1352 | updateVisibility(); | ||
1379 | updateWindowRules(Rules::Activity); | 1353 | updateWindowRules(Rules::Activity); | ||
1380 | | ||||
1381 | // Update states of all other windows in this group | | |||
1382 | if (tabGroup()) | | |||
1383 | tabGroup()->updateStates(this, TabGroup::Activity); | | |||
1384 | } | 1354 | } | ||
1385 | 1355 | | |||
1386 | /** | 1356 | /** | ||
1387 | * Returns the list of activities the client window is on. | 1357 | * Returns the list of activities the client window is on. | ||
1388 | * if it's on all activities, the list will be empty. | 1358 | * if it's on all activities, the list will be empty. | ||
1389 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | 1359 | * Don't use this, use isOnActivity() and friends (from class Toplevel) | ||
1390 | */ | 1360 | */ | ||
1391 | QStringList Client::activities() const | 1361 | QStringList Client::activities() const | ||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Line(s) | |||||
1591 | 1561 | | |||
1592 | void Client::setClientShown(bool shown) | 1562 | void Client::setClientShown(bool shown) | ||
1593 | { | 1563 | { | ||
1594 | if (deleting) | 1564 | if (deleting) | ||
1595 | return; // Don't change shown status if this client is being deleted | 1565 | return; // Don't change shown status if this client is being deleted | ||
1596 | if (shown != hidden) | 1566 | if (shown != hidden) | ||
1597 | return; // nothing to change | 1567 | return; // nothing to change | ||
1598 | hidden = !shown; | 1568 | hidden = !shown; | ||
1599 | if (options->isInactiveTabsSkipTaskbar()) | | |||
1600 | setSkipTaskbar(hidden); // TODO: Causes reshuffle of the taskbar | | |||
1601 | if (shown) { | 1569 | if (shown) { | ||
1602 | map(); | 1570 | map(); | ||
1603 | takeFocus(); | 1571 | takeFocus(); | ||
1604 | autoRaise(); | 1572 | autoRaise(); | ||
1605 | FocusChain::self()->update(this, FocusChain::MakeFirst); | 1573 | FocusChain::self()->update(this, FocusChain::MakeFirst); | ||
1606 | } else { | 1574 | } else { | ||
1607 | unmap(); | 1575 | unmap(); | ||
1608 | // Don't move tabs to the end of the list when another tab get's activated | 1576 | // Don't move tabs to the end of the list when another tab get's activated | ||
1609 | if (isCurrentTab()) | | |||
1610 | FocusChain::self()->update(this, FocusChain::MakeLast); | 1577 | 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! | |||||
1611 | addWorkspaceRepaint(visibleRect()); | 1578 | addWorkspaceRepaint(visibleRect()); | ||
1612 | } | 1579 | } | ||
1613 | } | 1580 | } | ||
1614 | 1581 | | |||
1615 | void Client::getMotifHints() | 1582 | void Client::getMotifHints() | ||
1616 | { | 1583 | { | ||
1617 | const bool wasClosable = m_motif.close(); | 1584 | const bool wasClosable = m_motif.close(); | ||
1618 | const bool wasNoBorder = m_motif.noBorder(); | 1585 | const bool wasNoBorder = m_motif.noBorder(); | ||
▲ Show 20 Lines • Show All 482 Lines • ▼ Show 20 Line(s) | |||||
2101 | { | 2068 | { | ||
2102 | const Client *c2 = dynamic_cast<const Client*>(other); | 2069 | const Client *c2 = dynamic_cast<const Client*>(other); | ||
2103 | if (!c2) { | 2070 | if (!c2) { | ||
2104 | return false; | 2071 | return false; | ||
2105 | } | 2072 | } | ||
2106 | return Client::belongToSameApplication(this, c2, checks); | 2073 | return Client::belongToSameApplication(this, c2, checks); | ||
2107 | } | 2074 | } | ||
2108 | 2075 | | |||
2109 | void Client::updateTabGroupStates(TabGroup::States states) | | |||
2110 | { | | |||
2111 | if (auto t = tabGroup()) { | | |||
2112 | t->updateStates(this, states); | | |||
2113 | } | | |||
2114 | } | | |||
2115 | | ||||
2116 | QSize Client::resizeIncrements() const | 2076 | QSize Client::resizeIncrements() const | ||
2117 | { | 2077 | { | ||
2118 | return m_geometryHints.resizeIncrements(); | 2078 | return m_geometryHints.resizeIncrements(); | ||
2119 | } | 2079 | } | ||
2120 | 2080 | | |||
2121 | Xcb::StringProperty Client::fetchApplicationMenuServiceName() const | 2081 | Xcb::StringProperty Client::fetchApplicationMenuServiceName() const | ||
2122 | { | 2082 | { | ||
2123 | return Xcb::StringProperty(m_client, atoms->kde_net_wm_appmenu_service_name); | 2083 | 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.