File indexing completed on 2025-03-16 05:05:00
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org> 0006 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #pragma once 0012 0013 // kwin 0014 #include "scene/decorationitem.h" 0015 #include "utils/xcbutils.h" 0016 #include "window.h" 0017 // Qt 0018 #include <QElapsedTimer> 0019 #include <QFlags> 0020 #include <QPixmap> 0021 #include <QPointer> 0022 #include <QWindow> 0023 // X 0024 #include <xcb/sync.h> 0025 0026 // TODO: Cleanup the order of things in this .h file 0027 0028 class QTimer; 0029 class KStartupInfoData; 0030 class KStartupInfoId; 0031 0032 namespace KWin 0033 { 0034 0035 class KillPrompt; 0036 0037 /** 0038 * @brief Defines Predicates on how to search for a Client. 0039 * 0040 * Used by Workspace::findClient. 0041 */ 0042 enum class Predicate { 0043 WindowMatch, 0044 WrapperIdMatch, 0045 FrameIdMatch, 0046 InputIdMatch, 0047 }; 0048 0049 /** 0050 * @todo Remove when the X11 platform support is dropped. This decoration renderer 0051 * will be used if compositing is off. 0052 */ 0053 class X11DecorationRenderer : public DecorationRenderer 0054 { 0055 Q_OBJECT 0056 0057 public: 0058 explicit X11DecorationRenderer(Decoration::DecoratedClientImpl *client); 0059 ~X11DecorationRenderer() override; 0060 0061 protected: 0062 void render(const QRegion ®ion) override; 0063 0064 private: 0065 void update(); 0066 0067 QTimer *m_scheduleTimer; 0068 xcb_gcontext_t m_gc; 0069 }; 0070 0071 class KWIN_EXPORT X11Window : public Window 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 explicit X11Window(); 0077 ~X11Window() override; ///< Use destroyWindow() or releaseWindow() 0078 0079 xcb_window_t frameId() const; 0080 xcb_window_t window() const; 0081 xcb_window_t wrapperId() const; 0082 xcb_window_t inputId() const 0083 { 0084 return m_decoInputExtent; 0085 } 0086 0087 int desktopId() const; 0088 QByteArray sessionId() const; 0089 xcb_window_t wmClientLeader() const; 0090 QString wmCommand(); 0091 0092 QPointF framePosToClientPos(const QPointF &point) const override; 0093 QPointF clientPosToFramePos(const QPointF &point) const override; 0094 QSizeF frameSizeToClientSize(const QSizeF &size) const override; 0095 QSizeF clientSizeToFrameSize(const QSizeF &size) const override; 0096 QRectF frameRectToBufferRect(const QRectF &rect) const; 0097 QPointF wrapperPos() const; 0098 QSizeF implicitSize() const; 0099 0100 xcb_visualid_t visual() const; 0101 int depth() const; 0102 bool hasAlpha() const; 0103 QRegion opaqueRegion() const; 0104 QList<QRectF> shapeRegion() const; 0105 0106 pid_t pid() const override; 0107 QString windowRole() const override; 0108 0109 bool isTransient() const override; 0110 bool groupTransient() const override; 0111 QList<Window *> mainWindows() const override; // Call once before loop , is not indirect 0112 bool hasTransient(const Window *c, bool indirect) const override; 0113 void checkTransient(xcb_window_t w); 0114 Window *findModal(bool allow_itself = false) override; 0115 const Group *group() const override; 0116 Group *group() override; 0117 void checkGroup(Group *gr = nullptr, bool force = false); 0118 void changeClientLeaderGroup(Group *gr); 0119 bool supportsWindowRules() const override; 0120 void updateWindowRules(Rules::Types selection) override; 0121 void applyWindowRules() override; 0122 void updateFullscreenMonitors(NETFullscreenMonitors topology); 0123 0124 bool hasNETSupport() const; 0125 0126 QSizeF minSize() const override; 0127 QSizeF maxSize() const override; 0128 QSizeF basicUnit() const; 0129 QPointF inputPos() const 0130 { 0131 return input_offset; 0132 } // Inside of geometry() 0133 0134 bool windowEvent(xcb_generic_event_t *e); 0135 NET::WindowType windowType() const override; 0136 0137 bool track(xcb_window_t w); 0138 bool manage(xcb_window_t w, bool isMapped); 0139 0140 void releaseWindow(bool on_shutdown = false); 0141 bool hasScheduledRelease() const; 0142 0143 void destroyWindow() override; 0144 0145 QStringList activities() const override; 0146 void doSetOnActivities(const QStringList &newActivitiesList) override; 0147 void updateActivities(bool includeTransients) override; 0148 0149 bool isShadeable() const override; 0150 bool isMaximizable() const override; 0151 MaximizeMode maximizeMode() const override; 0152 void maximize(MaximizeMode mode) override; 0153 0154 bool isMinimizable() const override; 0155 QRectF iconGeometry() const override; 0156 0157 bool isFullScreenable() const override; 0158 void setFullScreen(bool set) override; 0159 bool isFullScreen() const override; 0160 int fullScreenMode() const 0161 { 0162 return m_fullscreenMode; // only for session saving 0163 } 0164 0165 bool userNoBorder() const; 0166 bool noBorder() const override; 0167 void setNoBorder(bool set) override; 0168 bool userCanSetNoBorder() const override; 0169 void checkNoBorder() override; 0170 void checkActivities() override; 0171 0172 int sessionStackingOrder() const; 0173 0174 // Auxiliary functions, depend on the windowType 0175 bool wantsInput() const override; 0176 0177 bool isResizable() const override; 0178 bool isMovable() const override; 0179 bool isMovableAcrossScreens() const override; 0180 bool isCloseable() const override; ///< May be closed by the user (May have a close button) 0181 0182 bool takeFocus() override; 0183 0184 void invalidateDecoration() override; 0185 0186 void detectShape(); 0187 void updateShape(); 0188 0189 /// resizeWithChecks() resizes according to gravity, and checks workarea position 0190 QRectF resizeWithChecks(const QRectF &geometry, const QSizeF &size) override; 0191 QRectF resizeWithChecks(const QRectF &geometry, qreal w, qreal h, xcb_gravity_t gravity); 0192 QRectF resizeWithChecks(const QRectF &geometry, const QSizeF &s, xcb_gravity_t gravity); 0193 QSizeF constrainClientSize(const QSizeF &size, SizeMode mode = SizeModeAny) const override; 0194 0195 bool providesContextHelp() const override; 0196 0197 /// Updates visibility depending on being shaded, virtual desktop, etc. 0198 void updateVisibility(); 0199 bool hiddenPreview() const; ///< Window is mapped in order to get a window pixmap 0200 0201 bool setupCompositing() override; 0202 void finishCompositing() override; 0203 void setBlockingCompositing(bool block); 0204 void blockCompositing(); 0205 void unblockCompositing(); 0206 0207 QString captionNormal() const override 0208 { 0209 return cap_normal; 0210 } 0211 QString captionSuffix() const override 0212 { 0213 return cap_suffix; 0214 } 0215 0216 using Window::keyPressEvent; 0217 void keyPressEvent(uint key_code, xcb_timestamp_t time); // FRAME ?? 0218 void updateMouseGrab() override; 0219 xcb_window_t moveResizeGrabWindow() const; 0220 0221 QPointF gravityAdjustment(xcb_gravity_t gravity) const; 0222 const QPointF calculateGravitation(bool invert) const; 0223 0224 void NETMoveResize(qreal x_root, qreal y_root, NET::Direction direction); 0225 void NETMoveResizeWindow(int flags, qreal x, qreal y, qreal width, qreal height); 0226 void GTKShowWindowMenu(qreal x_root, qreal y_root); 0227 void restackWindow(xcb_window_t above, int detail, NET::RequestSource source, xcb_timestamp_t timestamp, 0228 bool send_event = false); 0229 0230 void gotPing(xcb_timestamp_t timestamp); 0231 0232 void updateUserTime(xcb_timestamp_t time = XCB_TIME_CURRENT_TIME); 0233 xcb_timestamp_t userTime() const override; 0234 bool hasUserTimeSupport() const; 0235 0236 /// Does 'delete c;' 0237 static void deleteClient(X11Window *c); 0238 0239 static bool belongToSameApplication(const X11Window *c1, const X11Window *c2, SameApplicationChecks checks = SameApplicationChecks()); 0240 static bool sameAppWindowRoleMatch(const X11Window *c1, const X11Window *c2, bool active_hack); 0241 0242 void killWindow() override; 0243 void showContextHelp() override; 0244 void checkActiveModal(); 0245 0246 StrutRect strutRect(StrutArea area) const override; 0247 bool hasStrut() const override; 0248 0249 bool isClientSideDecorated() const; 0250 0251 Xcb::StringProperty fetchPreferredColorScheme() const; 0252 QString readPreferredColorScheme(Xcb::StringProperty &property) const; 0253 QString preferredColorScheme() const override; 0254 0255 // sets whether the client should be faked as being on all activities (and be shown during session save) 0256 void setSessionActivityOverride(bool needed); 0257 bool isClient() const override; 0258 bool isOutline() const override; 0259 bool isUnmanaged() const override; 0260 0261 void cancelFocusOutTimer(); 0262 0263 /** 0264 * Restores the Client after it had been hidden due to show on screen edge functionality. 0265 * In addition the property gets deleted so that the Client knows that it is visible again. 0266 */ 0267 void showOnScreenEdge() override; 0268 0269 Xcb::StringProperty fetchApplicationMenuServiceName() const; 0270 void readApplicationMenuServiceName(Xcb::StringProperty &property); 0271 void checkApplicationMenuServiceName(); 0272 0273 Xcb::StringProperty fetchApplicationMenuObjectPath() const; 0274 void readApplicationMenuObjectPath(Xcb::StringProperty &property); 0275 void checkApplicationMenuObjectPath(); 0276 0277 struct SyncRequest 0278 { 0279 xcb_sync_counter_t counter; 0280 xcb_sync_int64_t value; 0281 xcb_sync_alarm_t alarm; 0282 xcb_timestamp_t lastTimestamp; 0283 QTimer *timeout, *failsafeTimeout; 0284 bool isPending; 0285 bool interactiveResize; 0286 }; 0287 const SyncRequest &syncRequest() const 0288 { 0289 return m_syncRequest; 0290 } 0291 bool wantsSyncCounter() const; 0292 void handleSync(); 0293 void handleSyncTimeout(); 0294 0295 bool allowWindowActivation(xcb_timestamp_t time = -1U, bool focus_in = false); 0296 0297 static void cleanupX11(); 0298 0299 quint64 surfaceSerial() const; 0300 quint32 pendingSurfaceId() const; 0301 0302 public Q_SLOTS: 0303 void closeWindow() override; 0304 void updateCaption() override; 0305 0306 private: 0307 // Handlers for X11 events 0308 bool mapRequestEvent(xcb_map_request_event_t *e); 0309 void unmapNotifyEvent(xcb_unmap_notify_event_t *e); 0310 void destroyNotifyEvent(xcb_destroy_notify_event_t *e); 0311 void configureNotifyEvent(xcb_configure_notify_event_t *e); 0312 void configureRequestEvent(xcb_configure_request_event_t *e); 0313 void propertyNotifyEvent(xcb_property_notify_event_t *e); 0314 void clientMessageEvent(xcb_client_message_event_t *e); 0315 void enterNotifyEvent(xcb_enter_notify_event_t *e); 0316 void leaveNotifyEvent(xcb_leave_notify_event_t *e); 0317 void focusInEvent(xcb_focus_in_event_t *e); 0318 void focusOutEvent(xcb_focus_out_event_t *e); 0319 void damageNotifyEvent(); 0320 0321 bool buttonPressEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root, xcb_timestamp_t time = XCB_CURRENT_TIME); 0322 bool buttonReleaseEvent(xcb_window_t w, int button, int state, int x, int y, int x_root, int y_root); 0323 bool motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_root, int y_root); 0324 0325 protected: 0326 bool belongsToSameApplication(const Window *other, SameApplicationChecks checks) const override; 0327 void doSetActive() override; 0328 void doSetKeepAbove() override; 0329 void doSetKeepBelow() override; 0330 void doSetShade(ShadeMode previousShadeMode) override; 0331 void doSetDesktop() override; 0332 void doMinimize() override; 0333 void doSetSkipPager() override; 0334 void doSetSkipTaskbar() override; 0335 void doSetSkipSwitcher() override; 0336 void doSetDemandsAttention() override; 0337 void doSetHidden() override; 0338 void doSetHiddenByShowDesktop() override; 0339 bool belongsToDesktop() const override; 0340 bool doStartInteractiveMoveResize() override; 0341 bool isWaitingForInteractiveMoveResizeSync() const override; 0342 void doInteractiveResizeSync(const QRectF &rect) override; 0343 QSizeF resizeIncrements() const override; 0344 bool acceptsFocus() const override; 0345 void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override; 0346 std::unique_ptr<WindowItem> createItem(Scene *scene) override; 0347 0348 Q_SIGNALS: 0349 void shapeChanged(); 0350 0351 private: 0352 void exportMappingState(int s); // ICCCM 4.1.3.1, 4.1.4, NETWM 2.5.1 0353 bool isManaged() const; ///< Returns false if this client is not yet managed 0354 void updateAllowedActions(bool force = false); 0355 QRect fullscreenMonitorsArea(NETFullscreenMonitors topology) const; 0356 void getResourceClass(); 0357 void getWmNormalHints(); 0358 void getWmClientMachine(); 0359 void getMotifHints(); 0360 void getIcons(); 0361 void getWmOpaqueRegion(); 0362 void discardShapeRegion(); 0363 void fetchName(); 0364 void fetchIconicName(); 0365 QString readName() const; 0366 void setCaption(const QString &s, bool force = false); 0367 bool hasTransientInternal(const X11Window *c, bool indirect, QList<const X11Window *> &set) const; 0368 void setShortcutInternal() override; 0369 Xcb::Property fetchWmClientLeader() const; 0370 void readWmClientLeader(Xcb::Property &p); 0371 void getWmClientLeader(); 0372 Xcb::Property fetchSkipCloseAnimation() const; 0373 void readSkipCloseAnimation(Xcb::Property &prop); 0374 void getSkipCloseAnimation(); 0375 0376 void configureRequest(int value_mask, qreal rx, qreal ry, qreal rw, qreal rh, int gravity, bool from_tool); 0377 NETExtendedStrut strut() const; 0378 int checkShadeGeometry(int w, int h); 0379 void getSyncCounter(); 0380 void sendSyncRequest(); 0381 void leaveInteractiveMoveResize() override; 0382 void performInteractiveResize(); 0383 void establishCommandWindowGrab(uint8_t button); 0384 void establishCommandAllGrab(uint8_t button); 0385 void resizeDecoration(); 0386 0387 void pingWindow(); 0388 void killProcess(bool ask, xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME); 0389 void updateUrgency(); 0390 static void sendClientMessage(xcb_window_t w, xcb_atom_t a, xcb_atom_t protocol, 0391 uint32_t data1 = 0, uint32_t data2 = 0, uint32_t data3 = 0); 0392 0393 void embedClient(xcb_window_t w, xcb_visualid_t visualid, xcb_colormap_t colormap, uint8_t depth); 0394 void detectNoBorder(); 0395 void updateFrameExtents(); 0396 void setClientFrameExtents(const NETStrut &strut); 0397 0398 void internalShow(); 0399 void internalHide(); 0400 void internalKeep(); 0401 void map(); 0402 void unmap(); 0403 void updateHiddenPreview(); 0404 0405 void updateInputShape(); 0406 void updateServerGeometry(); 0407 void discardWindowPixmap(); 0408 void updateWindowPixmap(); 0409 0410 xcb_timestamp_t readUserTimeMapTimestamp(const KStartupInfoId *asn_id, const KStartupInfoData *asn_data, 0411 bool session) const; 0412 xcb_timestamp_t readUserCreationTime() const; 0413 void startupIdChanged(); 0414 0415 void updateInputWindow(); 0416 0417 Xcb::Property fetchShowOnScreenEdge() const; 0418 void readShowOnScreenEdge(Xcb::Property &property); 0419 /** 0420 * Reads the property and creates/destroys the screen edge if required 0421 * and shows/hides the client. 0422 */ 0423 void updateShowOnScreenEdge(); 0424 0425 void maybeCreateX11DecorationRenderer(); 0426 void maybeDestroyX11DecorationRenderer(); 0427 void updateDecoration(bool check_workspace_pos, bool force = false); 0428 void createDecoration(); 0429 void destroyDecoration(); 0430 0431 QWindow *findInternalWindow() const; 0432 void checkOutput(); 0433 void associate(); 0434 void handleXwaylandScaleChanged(); 0435 0436 Xcb::Window m_client; 0437 Xcb::Window m_wrapper; 0438 Xcb::Window m_frame; 0439 xcb_window_t m_wmClientLeader = XCB_WINDOW_NONE; 0440 int m_activityUpdatesBlocked; 0441 bool m_blockedActivityUpdatesRequireTransients; 0442 Xcb::Window m_moveResizeGrabWindow; 0443 bool move_resize_has_keyboard_grab; 0444 bool m_managed; 0445 0446 Xcb::GeometryHints m_geometryHints; 0447 void sendSyntheticConfigureNotify(); 0448 enum MappingState { 0449 Withdrawn, ///< Not handled, as per ICCCM WithdrawnState 0450 Mapped, ///< The frame is mapped 0451 Unmapped, ///< The frame is not mapped 0452 Kept ///< The frame should be unmapped, but is kept (For compositing) 0453 }; 0454 MappingState mapping_state; 0455 0456 Xcb::TransientFor fetchTransient() const; 0457 void readTransientProperty(Xcb::TransientFor &transientFor); 0458 void readTransient(); 0459 xcb_window_t verifyTransientFor(xcb_window_t transient_for, bool set); 0460 void addTransient(Window *cl) override; 0461 void removeFromMainClients(); 0462 void cleanGrouping(); 0463 void checkGroupTransients(); 0464 void setTransient(xcb_window_t new_transient_for_id); 0465 0466 NETWinInfo *info = nullptr; 0467 xcb_window_t m_transientForId; 0468 xcb_window_t m_originalTransientForId; 0469 X11Window *shade_below; 0470 Xcb::MotifHints m_motif; 0471 uint noborder : 1; 0472 uint app_noborder : 1; ///< App requested no border via window type, shape extension, etc. 0473 uint ignore_focus_stealing : 1; ///< Don't apply focus stealing prevention to this client 0474 bool blocks_compositing; 0475 bool is_shape = false; 0476 0477 enum FullScreenMode { 0478 FullScreenNone, 0479 FullScreenNormal 0480 } m_fullscreenMode; 0481 0482 MaximizeMode max_mode; 0483 QString cap_normal, cap_iconic, cap_suffix; 0484 Group *in_group; 0485 QTimer *ping_timer; 0486 std::unique_ptr<KillPrompt> m_killPrompt; 0487 xcb_timestamp_t m_pingTimestamp; 0488 xcb_timestamp_t m_userTime; 0489 NET::Actions allowed_actions; 0490 bool shade_geometry_change; 0491 SyncRequest m_syncRequest; 0492 static bool check_active_modal; ///< \see X11Window::checkActiveModal() 0493 int sm_stacking_order; 0494 xcb_visualid_t m_visual = XCB_NONE; 0495 int bit_depth = 24; 0496 QRegion opaque_region; 0497 mutable QList<QRectF> m_shapeRegion; 0498 mutable bool m_shapeRegionIsValid = false; 0499 friend struct ResetupRulesProcedure; 0500 0501 friend bool performTransiencyCheck(); 0502 0503 Xcb::StringProperty fetchActivities() const; 0504 void readActivities(Xcb::StringProperty &property); 0505 bool activitiesDefined; // whether the x property was actually set 0506 0507 bool sessionActivityOverride; 0508 0509 Xcb::Window m_decoInputExtent; 0510 QPointF input_offset; 0511 0512 QTimer *m_focusOutTimer; 0513 QTimer m_releaseTimer; 0514 0515 QMetaObject::Connection m_edgeGeometryTrackingConnection; 0516 0517 QMarginsF m_clientFrameExtents; 0518 Output *m_lastOutput = nullptr; 0519 QRectF m_lastBufferGeometry; 0520 QRectF m_lastFrameGeometry; 0521 QRectF m_lastClientGeometry; 0522 std::unique_ptr<X11DecorationRenderer> m_decorationRenderer; 0523 0524 bool m_unmanaged = false; 0525 bool m_outline = false; 0526 quint32 m_pendingSurfaceId = 0; 0527 quint64 m_surfaceSerial = 0; 0528 }; 0529 0530 inline xcb_visualid_t X11Window::visual() const 0531 { 0532 return m_visual; 0533 } 0534 0535 inline int X11Window::depth() const 0536 { 0537 return bit_depth; 0538 } 0539 0540 inline bool X11Window::hasAlpha() const 0541 { 0542 return depth() == 32; 0543 } 0544 0545 inline QRegion X11Window::opaqueRegion() const 0546 { 0547 return opaque_region; 0548 } 0549 0550 inline bool X11Window::isClientSideDecorated() const 0551 { 0552 return !m_clientFrameExtents.isNull(); 0553 } 0554 0555 inline bool X11Window::groupTransient() const 0556 { 0557 return m_transientForId == kwinApp()->x11RootWindow(); 0558 } 0559 0560 inline bool X11Window::isTransient() const 0561 { 0562 return m_transientForId != XCB_WINDOW_NONE; 0563 } 0564 0565 inline const Group *X11Window::group() const 0566 { 0567 return in_group; 0568 } 0569 0570 inline Group *X11Window::group() 0571 { 0572 return in_group; 0573 } 0574 0575 inline MaximizeMode X11Window::maximizeMode() const 0576 { 0577 return max_mode; 0578 } 0579 0580 inline bool X11Window::isFullScreen() const 0581 { 0582 return m_fullscreenMode != FullScreenNone; 0583 } 0584 0585 inline bool X11Window::hasNETSupport() const 0586 { 0587 return info->hasNETSupport(); 0588 } 0589 0590 inline int X11Window::sessionStackingOrder() const 0591 { 0592 return sm_stacking_order; 0593 } 0594 0595 inline bool X11Window::isManaged() const 0596 { 0597 return m_managed; 0598 } 0599 0600 inline QRectF X11Window::resizeWithChecks(const QRectF &geometry, const QSizeF &s) 0601 { 0602 return resizeWithChecks(geometry, s.width(), s.height(), XCB_GRAVITY_BIT_FORGET); 0603 } 0604 0605 inline QRectF X11Window::resizeWithChecks(const QRectF &geometry, const QSizeF &s, xcb_gravity_t gravity) 0606 { 0607 return resizeWithChecks(geometry, s.width(), s.height(), gravity); 0608 } 0609 0610 inline bool X11Window::hasUserTimeSupport() const 0611 { 0612 return info->userTime() != -1U; 0613 } 0614 0615 inline xcb_window_t X11Window::moveResizeGrabWindow() const 0616 { 0617 return m_moveResizeGrabWindow; 0618 } 0619 0620 inline bool X11Window::hiddenPreview() const 0621 { 0622 return mapping_state == Kept; 0623 } 0624 0625 inline quint64 X11Window::surfaceSerial() const 0626 { 0627 return m_surfaceSerial; 0628 } 0629 0630 inline quint32 X11Window::pendingSurfaceId() const 0631 { 0632 return m_pendingSurfaceId; 0633 } 0634 0635 } // namespace 0636 Q_DECLARE_METATYPE(KWin::X11Window *) 0637 Q_DECLARE_METATYPE(QList<KWin::X11Window *>)