all: use BINDABLE only with trivial setters

Fixes various bugs caused by the QML engine bypassing setters
when BINDABLE is specified (even if the bindable is const).
Also restructures all properties using BINDABLE to have
a default READ and WRITE to ensure this doesn't happen again.
This commit is contained in:
outfoxxed 2025-05-29 16:05:30 -07:00
parent 2e3c15f7a1
commit b67f92bc13
Signed by untrusted user: outfoxxed
GPG key ID: 4C88A185FB89301E
10 changed files with 167 additions and 180 deletions

View file

@ -282,15 +282,6 @@ bool setSimpleObjectHandle(auto* parent, auto* value) {
return SimpleObjectHandleOps<member, destroyedSlot, changedSignal>::setObject(parent, value); return SimpleObjectHandleOps<member, destroyedSlot, changedSignal>::setObject(parent, value);
} }
// NOLINTBEGIN
#define QS_TRIVIAL_GETTER(Type, member, getter) \
[[nodiscard]] Type getter() { return this->member; }
#define QS_BINDABLE_GETTER(Type, member, getter, bindable) \
[[nodiscard]] Type getter() { return this->member.value(); } \
[[nodiscard]] QBindable<Type> bindable() { return &this->member; }
// NOLINTEND
template <auto methodPtr> template <auto methodPtr>
class MethodFunctor { class MethodFunctor {
using PtrMeta = MemberPointerTraits<decltype(methodPtr)>; using PtrMeta = MemberPointerTraits<decltype(methodPtr)>;

View file

@ -148,7 +148,7 @@ MprisPlayer::MprisPlayer(const QString& address, QObject* parent): QObject(paren
} }
void MprisPlayer::raise() { void MprisPlayer::raise() {
if (!this->canRaise()) { if (!this->bCanRaise) {
qWarning() << "Cannot call raise() on" << this << "because canRaise is false."; qWarning() << "Cannot call raise() on" << this << "because canRaise is false.";
return; return;
} }
@ -157,7 +157,7 @@ void MprisPlayer::raise() {
} }
void MprisPlayer::quit() { void MprisPlayer::quit() {
if (!this->canQuit()) { if (!this->bCanQuit) {
qWarning() << "Cannot call quit() on" << this << "because canQuit is false."; qWarning() << "Cannot call quit() on" << this << "because canQuit is false.";
return; return;
} }
@ -168,7 +168,7 @@ void MprisPlayer::quit() {
void MprisPlayer::openUri(const QString& uri) { this->player->OpenUri(uri); } void MprisPlayer::openUri(const QString& uri) { this->player->OpenUri(uri); }
void MprisPlayer::next() { void MprisPlayer::next() {
if (!this->canGoNext()) { if (!this->bCanGoNext) {
qWarning() << "Cannot call next() on" << this << "because canGoNext is false."; qWarning() << "Cannot call next() on" << this << "because canGoNext is false.";
return; return;
} }
@ -177,7 +177,7 @@ void MprisPlayer::next() {
} }
void MprisPlayer::previous() { void MprisPlayer::previous() {
if (!this->canGoPrevious()) { if (!this->bCanGoPrevious) {
qWarning() << "Cannot call previous() on" << this << "because canGoPrevious is false."; qWarning() << "Cannot call previous() on" << this << "because canGoPrevious is false.";
return; return;
} }
@ -186,7 +186,7 @@ void MprisPlayer::previous() {
} }
void MprisPlayer::seek(qreal offset) { void MprisPlayer::seek(qreal offset) {
if (!this->canSeek()) { if (!this->bCanSeek) {
qWarning() << "Cannot call seek() on" << this << "because canSeek is false."; qWarning() << "Cannot call seek() on" << this << "because canSeek is false.";
return; return;
} }
@ -226,7 +226,7 @@ void MprisPlayer::setPosition(qreal position) {
return; return;
} }
if (!this->canSeek()) { if (!this->bCanSeek) {
qWarning() << "Cannot set position of" << this << "because canSeek is false."; qWarning() << "Cannot set position of" << this << "because canSeek is false.";
return; return;
} }
@ -275,7 +275,7 @@ bool MprisPlayer::lengthSupported() const { return this->bInternalLength != -1;
bool MprisPlayer::volumeSupported() const { return this->pVolume.exists(); } bool MprisPlayer::volumeSupported() const { return this->pVolume.exists(); }
void MprisPlayer::setVolume(qreal volume) { void MprisPlayer::setVolume(qreal volume) {
if (!this->canControl()) { if (!this->bCanControl) {
qWarning() << "Cannot set volume of" << this << "because canControl is false."; qWarning() << "Cannot set volume of" << this << "because canControl is false.";
return; return;
} }
@ -353,7 +353,7 @@ void MprisPlayer::setPlaybackState(MprisPlaybackState::Enum playbackState) {
switch (playbackState) { switch (playbackState) {
case MprisPlaybackState::Stopped: case MprisPlaybackState::Stopped:
if (!this->canControl()) { if (!this->bCanControl) {
qWarning() << "Cannot set playbackState of" << this qWarning() << "Cannot set playbackState of" << this
<< "to Stopped because canControl is false."; << "to Stopped because canControl is false.";
return; return;
@ -362,7 +362,7 @@ void MprisPlayer::setPlaybackState(MprisPlaybackState::Enum playbackState) {
this->player->Stop(); this->player->Stop();
break; break;
case MprisPlaybackState::Playing: case MprisPlaybackState::Playing:
if (!this->canPlay()) { if (!this->bCanPlay) {
qWarning() << "Cannot set playbackState of" << this << "to Playing because canPlay is false."; qWarning() << "Cannot set playbackState of" << this << "to Playing because canPlay is false.";
return; return;
} }
@ -370,7 +370,7 @@ void MprisPlayer::setPlaybackState(MprisPlaybackState::Enum playbackState) {
this->player->Play(); this->player->Play();
break; break;
case MprisPlaybackState::Paused: case MprisPlaybackState::Paused:
if (!this->canPause()) { if (!this->bCanPause) {
qWarning() << "Cannot set playbackState of" << this << "to Paused because canPause is false."; qWarning() << "Cannot set playbackState of" << this << "to Paused because canPause is false.";
return; return;
} }
@ -420,7 +420,7 @@ void MprisPlayer::onPlaybackStatusUpdated() {
bool MprisPlayer::loopSupported() const { return this->pLoopStatus.exists(); } bool MprisPlayer::loopSupported() const { return this->pLoopStatus.exists(); }
void MprisPlayer::setLoopState(MprisLoopState::Enum loopState) { void MprisPlayer::setLoopState(MprisLoopState::Enum loopState) {
if (!this->canControl()) { if (!this->bCanControl) {
qWarning() << "Cannot set loopState of" << this << "because canControl is false."; qWarning() << "Cannot set loopState of" << this << "because canControl is false.";
return; return;
} }
@ -468,7 +468,7 @@ void MprisPlayer::setShuffle(bool shuffle) {
return; return;
} }
if (!this->canControl()) { if (!this->bCanControl) {
qWarning() << "Cannot set shuffle state of" << this << "because canControl is false."; qWarning() << "Cannot set shuffle state of" << this << "because canControl is false.";
return; return;
} }
@ -478,7 +478,7 @@ void MprisPlayer::setShuffle(bool shuffle) {
} }
void MprisPlayer::setFullscreen(bool fullscreen) { void MprisPlayer::setFullscreen(bool fullscreen) {
if (!this->canSetFullscreen()) { if (!this->bCanSetFullscreen) {
qWarning() << "Cannot set fullscreen for" << this << "because canSetFullscreen is false."; qWarning() << "Cannot set fullscreen for" << this << "because canSetFullscreen is false.";
return; return;
} }

View file

@ -63,20 +63,20 @@ public:
class MprisPlayer: public QObject { class MprisPlayer: public QObject {
Q_OBJECT; Q_OBJECT;
// clang-format off // clang-format off
Q_PROPERTY(bool canControl READ canControl NOTIFY canControlChanged BINDABLE bindableCanControl); Q_PROPERTY(bool canControl READ default NOTIFY canControlChanged BINDABLE bindableCanControl);
Q_PROPERTY(bool canPlay READ canPlay NOTIFY canPlayChanged BINDABLE bindableCanPlay); Q_PROPERTY(bool canPlay READ default NOTIFY canPlayChanged BINDABLE bindableCanPlay);
Q_PROPERTY(bool canPause READ canPause NOTIFY canPauseChanged BINDABLE bindableCanPause); Q_PROPERTY(bool canPause READ default NOTIFY canPauseChanged BINDABLE bindableCanPause);
Q_PROPERTY(bool canTogglePlaying READ canTogglePlaying NOTIFY canTogglePlayingChanged BINDABLE bindableCanTogglePlaying); Q_PROPERTY(bool canTogglePlaying READ default NOTIFY canTogglePlayingChanged BINDABLE bindableCanTogglePlaying);
Q_PROPERTY(bool canSeek READ canSeek NOTIFY canSeekChanged BINDABLE bindableCanSeek); Q_PROPERTY(bool canSeek READ default NOTIFY canSeekChanged BINDABLE bindableCanSeek);
Q_PROPERTY(bool canGoNext READ canGoNext NOTIFY canGoNextChanged BINDABLE bindableCanGoNext); Q_PROPERTY(bool canGoNext READ default NOTIFY canGoNextChanged BINDABLE bindableCanGoNext);
Q_PROPERTY(bool canGoPrevious READ canGoPrevious NOTIFY canGoPreviousChanged BINDABLE bindableCanGoPrevious); Q_PROPERTY(bool canGoPrevious READ default NOTIFY canGoPreviousChanged BINDABLE bindableCanGoPrevious);
Q_PROPERTY(bool canQuit READ canQuit NOTIFY canQuitChanged BINDABLE bindableCanQuit); Q_PROPERTY(bool canQuit READ default NOTIFY canQuitChanged BINDABLE bindableCanQuit);
Q_PROPERTY(bool canRaise READ canRaise NOTIFY canRaiseChanged BINDABLE bindableCanRaise); Q_PROPERTY(bool canRaise READ default NOTIFY canRaiseChanged BINDABLE bindableCanRaise);
Q_PROPERTY(bool canSetFullscreen READ canSetFullscreen NOTIFY canSetFullscreenChanged BINDABLE bindableCanSetFullscreen); Q_PROPERTY(bool canSetFullscreen READ default NOTIFY canSetFullscreenChanged BINDABLE bindableCanSetFullscreen);
/// The human readable name of the media player. /// The human readable name of the media player.
Q_PROPERTY(QString identity READ identity NOTIFY identityChanged BINDABLE bindableIdentity); Q_PROPERTY(QString identity READ default NOTIFY identityChanged BINDABLE bindableIdentity);
/// The name of the desktop entry for the media player, or an empty string if not provided. /// The name of the desktop entry for the media player, or an empty string if not provided.
Q_PROPERTY(QString desktopEntry READ desktopEntry NOTIFY desktopEntryChanged BINDABLE bindableDesktopEntry); Q_PROPERTY(QString desktopEntry READ default NOTIFY desktopEntryChanged BINDABLE bindableDesktopEntry);
/// The DBus service name of the player. /// The DBus service name of the player.
Q_PROPERTY(QString dbusName READ address CONSTANT); Q_PROPERTY(QString dbusName READ address CONSTANT);
/// The current position in the playing track, as seconds, with millisecond precision, /// The current position in the playing track, as seconds, with millisecond precision,
@ -121,7 +121,7 @@ class MprisPlayer: public QObject {
/// The volume of the playing track from 0.0 to 1.0, or 1.0 if @@volumeSupported is false. /// The volume of the playing track from 0.0 to 1.0, or 1.0 if @@volumeSupported is false.
/// ///
/// May only be written to if @@canControl and @@volumeSupported are true. /// May only be written to if @@canControl and @@volumeSupported are true.
Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged BINDABLE bindableVolume); Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged);
Q_PROPERTY(bool volumeSupported READ volumeSupported NOTIFY volumeSupportedChanged); Q_PROPERTY(bool volumeSupported READ volumeSupported NOTIFY volumeSupportedChanged);
/// Metadata of the current track. /// Metadata of the current track.
/// ///
@ -131,52 +131,52 @@ class MprisPlayer: public QObject {
/// Note that the @@trackTitle, @@trackAlbum, @@trackAlbumArtist, @@trackArtist and @@trackArtUrl /// Note that the @@trackTitle, @@trackAlbum, @@trackAlbumArtist, @@trackArtist and @@trackArtUrl
/// properties have extra logic to guard against bad players sending weird metadata, and should /// properties have extra logic to guard against bad players sending weird metadata, and should
/// be used over grabbing the properties directly from the metadata. /// be used over grabbing the properties directly from the metadata.
Q_PROPERTY(QVariantMap metadata READ metadata NOTIFY metadataChanged BINDABLE bindableMetadata); Q_PROPERTY(QVariantMap metadata READ default NOTIFY metadataChanged BINDABLE bindableMetadata);
/// An opaque identifier for the current track unique within the current player. /// An opaque identifier for the current track unique within the current player.
/// ///
/// > [!WARNING] This is NOT `mpris:trackid` as that is sometimes missing or nonunique /// > [!WARNING] This is NOT `mpris:trackid` as that is sometimes missing or nonunique
/// > in some players. /// > in some players.
Q_PROPERTY(quint32 uniqueId READ uniqueId NOTIFY uniqueIdChanged BINDABLE bindableUniqueId); Q_PROPERTY(quint32 uniqueId READ default NOTIFY uniqueIdChanged BINDABLE bindableUniqueId);
/// The title of the current track, or `""` if none was provided. /// The title of the current track, or `""` if none was provided.
/// ///
/// > [!TIP] Use `player.trackTitle || "Unknown Title"` to provide a message /// > [!TIP] Use `player.trackTitle || "Unknown Title"` to provide a message
/// > when no title is available. /// > when no title is available.
Q_PROPERTY(QString trackTitle READ trackTitle NOTIFY trackTitleChanged BINDABLE bindableTrackTitle); Q_PROPERTY(QString trackTitle READ default NOTIFY trackTitleChanged BINDABLE bindableTrackTitle);
/// The current track's artist, or an `""` if none was provided. /// The current track's artist, or an `""` if none was provided.
/// ///
/// > [!TIP] Use `player.trackArtist || "Unknown Artist"` to provide a message /// > [!TIP] Use `player.trackArtist || "Unknown Artist"` to provide a message
/// > when no artist is available. /// > when no artist is available.
Q_PROPERTY(QString trackArtist READ trackArtist NOTIFY trackArtistChanged BINDABLE bindableTrackArtist); Q_PROPERTY(QString trackArtist READ default NOTIFY trackArtistChanged BINDABLE bindableTrackArtist);
/// > [!ERROR] deprecated in favor of @@trackArtist. /// > [!ERROR] deprecated in favor of @@trackArtist.
Q_PROPERTY(QString trackArtists READ trackArtist NOTIFY trackArtistChanged BINDABLE bindableTrackArtist); Q_PROPERTY(QString trackArtists READ default NOTIFY trackArtistChanged BINDABLE bindableTrackArtist);
/// The current track's album, or `""` if none was provided. /// The current track's album, or `""` if none was provided.
/// ///
/// > [!TIP] Use `player.trackAlbum || "Unknown Album"` to provide a message /// > [!TIP] Use `player.trackAlbum || "Unknown Album"` to provide a message
/// > when no album is available. /// > when no album is available.
Q_PROPERTY(QString trackAlbum READ trackAlbum NOTIFY trackAlbumChanged BINDABLE bindableTrackAlbum); Q_PROPERTY(QString trackAlbum READ default NOTIFY trackAlbumChanged BINDABLE bindableTrackAlbum);
/// The current track's album artist, or `""` if none was provided. /// The current track's album artist, or `""` if none was provided.
/// ///
/// > [!TIP] Use `player.trackAlbumArtist || "Unknown Album"` to provide a message /// > [!TIP] Use `player.trackAlbumArtist || "Unknown Album"` to provide a message
/// > when no album artist is available. /// > when no album artist is available.
Q_PROPERTY(QString trackAlbumArtist READ trackAlbumArtist NOTIFY trackAlbumArtistChanged BINDABLE bindableTrackAlbumArtist); Q_PROPERTY(QString trackAlbumArtist READ default NOTIFY trackAlbumArtistChanged BINDABLE bindableTrackAlbumArtist);
/// The current track's art url, or `""` if none was provided. /// The current track's art url, or `""` if none was provided.
Q_PROPERTY(QString trackArtUrl READ trackArtUrl NOTIFY trackArtUrlChanged BINDABLE bindableTrackArtUrl); Q_PROPERTY(QString trackArtUrl READ default NOTIFY trackArtUrlChanged BINDABLE bindableTrackArtUrl);
/// The playback state of the media player. /// The playback state of the media player.
/// ///
/// - If @@canPlay is false, you cannot assign the `Playing` state. /// - If @@canPlay is false, you cannot assign the `Playing` state.
/// - If @@canPause is false, you cannot assign the `Paused` state. /// - If @@canPause is false, you cannot assign the `Paused` state.
/// - If @@canControl is false, you cannot assign the `Stopped` state. /// - If @@canControl is false, you cannot assign the `Stopped` state.
/// (or any of the others, though their repsective properties will also be false) /// (or any of the others, though their repsective properties will also be false)
Q_PROPERTY(qs::service::mpris::MprisPlaybackState::Enum playbackState READ playbackState WRITE setPlaybackState NOTIFY playbackStateChanged BINDABLE bindablePlaybackState); Q_PROPERTY(qs::service::mpris::MprisPlaybackState::Enum playbackState READ playbackState WRITE setPlaybackState NOTIFY playbackStateChanged );
/// True if @@playbackState == `MprisPlaybackState.Playing`. /// True if @@playbackState == `MprisPlaybackState.Playing`.
/// ///
/// Setting this property is equivalent to calling @@play() or @@pause(). /// Setting this property is equivalent to calling @@play() or @@pause().
/// You cannot set this property if @@canTogglePlaying is false. /// You cannot set this property if @@canTogglePlaying is false.
Q_PROPERTY(bool isPlaying READ isPlaying WRITE setPlaying NOTIFY isPlayingChanged BINDABLE bindableIsPlaying); Q_PROPERTY(bool isPlaying READ isPlaying WRITE setPlaying NOTIFY isPlayingChanged);
/// The loop state of the media player, or `None` if @@loopSupported is false. /// The loop state of the media player, or `None` if @@loopSupported is false.
/// ///
/// May only be written to if @@canControl and @@loopSupported are true. /// May only be written to if @@canControl and @@loopSupported are true.
Q_PROPERTY(qs::service::mpris::MprisLoopState::Enum loopState READ loopState WRITE setLoopState NOTIFY loopStateChanged BINDABLE bindableLoopState); Q_PROPERTY(qs::service::mpris::MprisLoopState::Enum loopState READ loopState WRITE setLoopState NOTIFY loopStateChanged);
Q_PROPERTY(bool loopSupported READ loopSupported NOTIFY loopSupportedChanged); Q_PROPERTY(bool loopSupported READ loopSupported NOTIFY loopSupportedChanged);
/// The speed the song is playing at, as a multiplier. /// The speed the song is playing at, as a multiplier.
/// ///
@ -184,22 +184,22 @@ class MprisPlayer: public QObject {
/// Additionally, It is recommended that you only write common values such as `0.25`, `0.5`, `1.0`, `2.0` /// Additionally, It is recommended that you only write common values such as `0.25`, `0.5`, `1.0`, `2.0`
/// to the property, as media players are free to ignore the value, and are more likely to /// to the property, as media players are free to ignore the value, and are more likely to
/// accept common ones. /// accept common ones.
Q_PROPERTY(qreal rate READ rate WRITE setRate NOTIFY rateChanged BINDABLE bindableRate); Q_PROPERTY(qreal rate READ rate WRITE setRate NOTIFY rateChanged);
Q_PROPERTY(qreal minRate READ minRate NOTIFY minRateChanged BINDABLE bindableMinRate); Q_PROPERTY(qreal minRate READ default NOTIFY minRateChanged BINDABLE bindableMinRate);
Q_PROPERTY(qreal maxRate READ maxRate NOTIFY maxRateChanged BINDABLE bindableMaxRate); Q_PROPERTY(qreal maxRate READ default NOTIFY maxRateChanged BINDABLE bindableMaxRate);
/// If the play queue is currently being shuffled, or false if @@shuffleSupported is false. /// If the play queue is currently being shuffled, or false if @@shuffleSupported is false.
/// ///
/// May only be written if @@canControl and @@shuffleSupported are true. /// May only be written if @@canControl and @@shuffleSupported are true.
Q_PROPERTY(bool shuffle READ shuffle WRITE setShuffle NOTIFY shuffleChanged BINDABLE bindableShuffle); Q_PROPERTY(bool shuffle READ shuffle WRITE setShuffle NOTIFY shuffleChanged);
Q_PROPERTY(bool shuffleSupported READ shuffleSupported NOTIFY shuffleSupportedChanged); Q_PROPERTY(bool shuffleSupported READ shuffleSupported NOTIFY shuffleSupportedChanged);
/// If the player is currently shown in fullscreen. /// If the player is currently shown in fullscreen.
/// ///
/// May only be written to if @@canSetFullscreen is true. /// May only be written to if @@canSetFullscreen is true.
Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged BINDABLE bindableFullscreen); Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged);
/// Uri schemes supported by @@openUri(). /// Uri schemes supported by @@openUri().
Q_PROPERTY(QList<QString> supportedUriSchemes READ supportedUriSchemes NOTIFY supportedUriSchemesChanged BINDABLE bindableSupportedUriSchemes); Q_PROPERTY(QList<QString> supportedUriSchemes READ default NOTIFY supportedUriSchemesChanged BINDABLE bindableSupportedUriSchemes);
/// Mime types supported by @@openUri(). /// Mime types supported by @@openUri().
Q_PROPERTY(QList<QString> supportedMimeTypes READ supportedMimeTypes NOTIFY supportedMimeTypesChanged BINDABLE bindableSupportedMimeTypes); Q_PROPERTY(QList<QString> supportedMimeTypes READ default NOTIFY supportedMimeTypesChanged BINDABLE bindableSupportedMimeTypes);
// clang-format on // clang-format on
QML_ELEMENT; QML_ELEMENT;
QML_UNCREATABLE("MprisPlayers can only be acquired from Mpris"); QML_UNCREATABLE("MprisPlayers can only be acquired from Mpris");
@ -250,19 +250,23 @@ public:
[[nodiscard]] bool isValid() const; [[nodiscard]] bool isValid() const;
[[nodiscard]] QString address() const; [[nodiscard]] QString address() const;
QS_BINDABLE_GETTER(bool, bCanControl, canControl, bindableCanControl); [[nodiscard]] QBindable<bool> bindableCanControl() const { return &this->bCanControl; };
QS_BINDABLE_GETTER(bool, bCanSeek, canSeek, bindableCanSeek); [[nodiscard]] QBindable<bool> bindableCanSeek() const { return &this->bCanSeek; };
QS_BINDABLE_GETTER(bool, bCanGoNext, canGoNext, bindableCanGoNext); [[nodiscard]] QBindable<bool> bindableCanGoNext() const { return &this->bCanGoNext; };
QS_BINDABLE_GETTER(bool, bCanGoPrevious, canGoPrevious, bindableCanGoPrevious); [[nodiscard]] QBindable<bool> bindableCanGoPrevious() const { return &this->bCanGoPrevious; };
QS_BINDABLE_GETTER(bool, bCanPlay, canPlay, bindableCanPlay); [[nodiscard]] QBindable<bool> bindableCanPlay() const { return &this->bCanPlay; };
QS_BINDABLE_GETTER(bool, bCanPause, canPause, bindableCanPause); [[nodiscard]] QBindable<bool> bindableCanPause() const { return &this->bCanPause; };
QS_BINDABLE_GETTER(bool, bCanTogglePlaying, canTogglePlaying, bindableCanTogglePlaying); [[nodiscard]] QBindable<bool> bindableCanTogglePlaying() const {
QS_BINDABLE_GETTER(bool, bCanQuit, canQuit, bindableCanQuit); return &this->bCanTogglePlaying;
QS_BINDABLE_GETTER(bool, bCanRaise, canRaise, bindableCanRaise); };
QS_BINDABLE_GETTER(bool, bCanSetFullscreen, canSetFullscreen, bindableCanSetFullscreen); [[nodiscard]] QBindable<bool> bindableCanQuit() const { return &this->bCanQuit; };
[[nodiscard]] QBindable<bool> bindableCanRaise() const { return &this->bCanRaise; };
[[nodiscard]] QBindable<bool> bindableCanSetFullscreen() const {
return &this->bCanSetFullscreen;
};
QS_BINDABLE_GETTER(QString, bIdentity, identity, bindableIdentity); [[nodiscard]] QBindable<QString> bindableIdentity() const { return &this->bIdentity; };
QS_BINDABLE_GETTER(QString, bDesktopEntry, desktopEntry, bindableDesktopEntry); [[nodiscard]] QBindable<QString> bindableDesktopEntry() const { return &this->bDesktopEntry; };
[[nodiscard]] qlonglong positionMs() const; [[nodiscard]] qlonglong positionMs() const;
[[nodiscard]] qreal position() const; [[nodiscard]] qreal position() const;
@ -272,59 +276,49 @@ public:
[[nodiscard]] qreal length() const; [[nodiscard]] qreal length() const;
[[nodiscard]] bool lengthSupported() const; [[nodiscard]] bool lengthSupported() const;
QS_BINDABLE_GETTER(qreal, bVolume, volume, bindableVolume); [[nodiscard]] qreal volume() const { return this->bVolume; };
[[nodiscard]] bool volumeSupported() const; [[nodiscard]] bool volumeSupported() const;
void setVolume(qreal volume); void setVolume(qreal volume);
QS_BINDABLE_GETTER(quint32, bUniqueId, uniqueId, bindableUniqueId); [[nodiscard]] QBindable<quint32> bindableUniqueId() const { return &this->bUniqueId; };
QS_BINDABLE_GETTER(QVariantMap, bMetadata, metadata, bindableMetadata); [[nodiscard]] QBindable<QVariantMap> bindableMetadata() const { return &this->bMetadata; };
QS_BINDABLE_GETTER(QString, bTrackTitle, trackTitle, bindableTrackTitle); [[nodiscard]] QBindable<QString> bindableTrackTitle() const { return &this->bTrackTitle; };
QS_BINDABLE_GETTER(QString, bTrackAlbum, trackAlbum, bindableTrackAlbum); [[nodiscard]] QBindable<QString> bindableTrackAlbum() const { return &this->bTrackAlbum; };
QS_BINDABLE_GETTER(QString, bTrackAlbumArtist, trackAlbumArtist, bindableTrackAlbumArtist); [[nodiscard]] QBindable<QString> bindableTrackAlbumArtist() const {
QS_BINDABLE_GETTER(QString, bTrackArtist, trackArtist, bindableTrackArtist); return &this->bTrackAlbumArtist;
QS_BINDABLE_GETTER(QString, bTrackArtUrl, trackArtUrl, bindableTrackArtUrl); };
[[nodiscard]] QBindable<QString> bindableTrackArtist() const { return &this->bTrackArtist; };
QS_BINDABLE_GETTER( [[nodiscard]] QBindable<QString> bindableTrackArtUrl() const { return &this->bTrackArtUrl; };
MprisPlaybackState::Enum,
bPlaybackState,
playbackState,
bindablePlaybackState
);
[[nodiscard]] MprisPlaybackState::Enum playbackState() const { return this->bPlaybackState; };
void setPlaybackState(MprisPlaybackState::Enum playbackState); void setPlaybackState(MprisPlaybackState::Enum playbackState);
QS_BINDABLE_GETTER(bool, bIsPlaying, isPlaying, bindableIsPlaying); [[nodiscard]] bool isPlaying() const { return this->bIsPlaying; };
void setPlaying(bool playing); void setPlaying(bool playing);
QS_BINDABLE_GETTER(MprisLoopState::Enum, bLoopState, loopState, bindableLoopState); [[nodiscard]] MprisLoopState::Enum loopState() const { return this->bLoopState; };
[[nodiscard]] bool loopSupported() const; [[nodiscard]] bool loopSupported() const;
void setLoopState(MprisLoopState::Enum loopState); void setLoopState(MprisLoopState::Enum loopState);
QS_BINDABLE_GETTER(qreal, bRate, rate, bindableRate); [[nodiscard]] qreal rate() const { return this->bRate; };
QS_BINDABLE_GETTER(qreal, bRate, minRate, bindableMinRate); [[nodiscard]] QBindable<qreal> bindableMinRate() const { return &this->bRate; };
QS_BINDABLE_GETTER(qreal, bRate, maxRate, bindableMaxRate); [[nodiscard]] QBindable<qreal> bindableMaxRate() const { return &this->bRate; };
void setRate(qreal rate); void setRate(qreal rate);
QS_BINDABLE_GETTER(bool, bShuffle, shuffle, bindableShuffle); [[nodiscard]] bool shuffle() const { return this->bShuffle; };
[[nodiscard]] bool shuffleSupported() const; [[nodiscard]] bool shuffleSupported() const;
void setShuffle(bool shuffle); void setShuffle(bool shuffle);
QS_BINDABLE_GETTER(bool, bFullscreen, fullscreen, bindableFullscreen); [[nodiscard]] bool fullscreen() const { return this->bFullscreen; };
void setFullscreen(bool fullscreen); void setFullscreen(bool fullscreen);
QS_BINDABLE_GETTER( [[nodiscard]] QBindable<QList<QString>> bindableSupportedUriSchemes() const {
QList<QString>, return &this->bSupportedUriSchemes;
bSupportedUriSchemes, };
supportedUriSchemes,
bindableSupportedUriSchemes
);
QS_BINDABLE_GETTER( [[nodiscard]] QBindable<QList<QString>> bindableSupportedMimeTypes() const {
QList<QString>, return &this->bSupportedMimeTypes;
bSupportedMimeTypes, };
supportedMimeTypes,
bindableSupportedMimeTypes
);
signals: signals:
/// The track has changed. /// The track has changed.

View file

@ -49,7 +49,7 @@ void NotificationAction::invoke() {
NotificationServer::instance()->ActionInvoked(this->notification->id(), this->mIdentifier); NotificationServer::instance()->ActionInvoked(this->notification->id(), this->mIdentifier);
if (!this->notification->resident()) { if (!this->notification->bindableResident().value()) {
this->notification->close(NotificationCloseReason::Dismissed); this->notification->close(NotificationCloseReason::Dismissed);
} }
} }

View file

@ -81,35 +81,35 @@ class Notification
/// if @@NotificationServer.keepOnReload is true. /// if @@NotificationServer.keepOnReload is true.
Q_PROPERTY(bool lastGeneration READ isLastGeneration CONSTANT); Q_PROPERTY(bool lastGeneration READ isLastGeneration CONSTANT);
/// Time in seconds the notification should be valid for /// Time in seconds the notification should be valid for
Q_PROPERTY(qreal expireTimeout READ expireTimeout NOTIFY expireTimeoutChanged BINDABLE bindableExpireTimeout); Q_PROPERTY(qreal expireTimeout READ default NOTIFY expireTimeoutChanged BINDABLE bindableExpireTimeout);
/// The sending application's name. /// The sending application's name.
Q_PROPERTY(QString appName READ appName NOTIFY appNameChanged BINDABLE bindableAppName); Q_PROPERTY(QString appName READ default NOTIFY appNameChanged BINDABLE bindableAppName);
/// The sending application's icon. If none was provided, then the icon from an associated /// The sending application's icon. If none was provided, then the icon from an associated
/// desktop entry will be retrieved. If none was found then "". /// desktop entry will be retrieved. If none was found then "".
Q_PROPERTY(QString appIcon READ appIcon NOTIFY appIconChanged BINDABLE bindableAppIcon); Q_PROPERTY(QString appIcon READ default NOTIFY appIconChanged BINDABLE bindableAppIcon);
/// The image associated with this notification, or "" if none. /// The image associated with this notification, or "" if none.
Q_PROPERTY(QString summary READ summary NOTIFY summaryChanged BINDABLE bindableSummary); Q_PROPERTY(QString summary READ default NOTIFY summaryChanged BINDABLE bindableSummary);
Q_PROPERTY(QString body READ body NOTIFY bodyChanged BINDABLE bindableBody); Q_PROPERTY(QString body READ default NOTIFY bodyChanged BINDABLE bindableBody);
Q_PROPERTY(qs::service::notifications::NotificationUrgency::Enum urgency READ urgency NOTIFY urgencyChanged BINDABLE bindableUrgency); Q_PROPERTY(qs::service::notifications::NotificationUrgency::Enum urgency READ default NOTIFY urgencyChanged BINDABLE bindableUrgency);
/// Actions that can be taken for this notification. /// Actions that can be taken for this notification.
Q_PROPERTY(QList<qs::service::notifications::NotificationAction*> actions READ actions NOTIFY actionsChanged); Q_PROPERTY(QList<qs::service::notifications::NotificationAction*> actions READ actions NOTIFY actionsChanged);
/// If actions associated with this notification have icons available. /// If actions associated with this notification have icons available.
/// ///
/// See @@NotificationAction.identifier for details. /// See @@NotificationAction.identifier for details.
Q_PROPERTY(bool hasActionIcons READ hasActionIcons NOTIFY hasActionIconsChanged); Q_PROPERTY(bool hasActionIcons READ default NOTIFY hasActionIconsChanged BINDABLE bindableHasActionIcons);
/// If true, the notification will not be destroyed after an action is invoked. /// If true, the notification will not be destroyed after an action is invoked.
Q_PROPERTY(bool resident READ resident NOTIFY residentChanged); Q_PROPERTY(bool resident READ default NOTIFY residentChanged BINDABLE bindableResident);
/// If true, the notification should skip any kind of persistence function like a notification area. /// If true, the notification should skip any kind of persistence function like a notification area.
Q_PROPERTY(bool transient READ transient NOTIFY transientChanged); Q_PROPERTY(bool transient READ default NOTIFY transientChanged BINDABLE bindableTransient);
/// The name of the sender's desktop entry or "" if none was supplied. /// The name of the sender's desktop entry or "" if none was supplied.
Q_PROPERTY(QString desktopEntry READ desktopEntry NOTIFY desktopEntryChanged); Q_PROPERTY(QString desktopEntry READ default NOTIFY desktopEntryChanged BINDABLE bindableDesktopEntry);
/// An image associated with the notification. /// An image associated with the notification.
/// ///
/// This image is often something like a profile picture in instant messaging applications. /// This image is often something like a profile picture in instant messaging applications.
Q_PROPERTY(QString image READ image NOTIFY imageChanged); Q_PROPERTY(QString image READ default NOTIFY imageChanged BINDABLE bindableImage);
/// All hints sent by the client application as a javascript object. /// All hints sent by the client application as a javascript object.
/// Many common hints are exposed via other properties. /// Many common hints are exposed via other properties.
Q_PROPERTY(QVariantMap hints READ hints NOTIFY hintsChanged); Q_PROPERTY(QVariantMap hints READ default NOTIFY hintsChanged BINDABLE bindableHints);
// clang-format on // clang-format on
QML_ELEMENT; QML_ELEMENT;
QML_UNCREATABLE("Notifications must be acquired from a NotificationServer"); QML_UNCREATABLE("Notifications must be acquired from a NotificationServer");
@ -142,21 +142,23 @@ public:
[[nodiscard]] bool isLastGeneration() const; [[nodiscard]] bool isLastGeneration() const;
void setLastGeneration(); void setLastGeneration();
QS_BINDABLE_GETTER(qreal, bExpireTimeout, expireTimeout, bindableExpireTimeout); [[nodiscard]] QBindable<qreal> bindableExpireTimeout() const { return &this->bExpireTimeout; };
QS_BINDABLE_GETTER(QString, bAppName, appName, bindableAppName); [[nodiscard]] QBindable<QString> bindableAppName() const { return &this->bAppName; };
QS_BINDABLE_GETTER(QString, bAppIcon, appIcon, bindableAppIcon); [[nodiscard]] QBindable<QString> bindableAppIcon() const { return &this->bAppIcon; };
QS_BINDABLE_GETTER(QString, bSummary, summary, bindableSummary); [[nodiscard]] QBindable<QString> bindableSummary() const { return &this->bSummary; };
QS_BINDABLE_GETTER(QString, bBody, body, bindableBody); [[nodiscard]] QBindable<QString> bindableBody() const { return &this->bBody; };
QS_BINDABLE_GETTER(NotificationUrgency::Enum, bUrgency, urgency, bindableUrgency); [[nodiscard]] QBindable<NotificationUrgency ::Enum> bindableUrgency() const {
return &this->bUrgency;
};
[[nodiscard]] QList<NotificationAction*> actions() const; [[nodiscard]] QList<NotificationAction*> actions() const;
QS_BINDABLE_GETTER(bool, bHasActionIcons, hasActionIcons, bindableHasActionIcons); [[nodiscard]] QBindable<bool> bindableHasActionIcons() const { return &this->bHasActionIcons; };
QS_BINDABLE_GETTER(bool, bResident, resident, bindableResident); [[nodiscard]] QBindable<bool> bindableResident() const { return &this->bResident; };
QS_BINDABLE_GETTER(bool, bTransient, transient, bindableTransient); [[nodiscard]] QBindable<bool> bindableTransient() const { return &this->bTransient; };
QS_BINDABLE_GETTER(QString, bDesktopEntry, desktopEntry, bindableDesktopEntry); [[nodiscard]] QBindable<QString> bindableDesktopEntry() const { return &this->bDesktopEntry; };
QS_BINDABLE_GETTER(QString, bImage, image, bindableImage); [[nodiscard]] QBindable<QString> bindableImage() const { return &this->bImage; };
QS_BINDABLE_GETTER(QVariantMap, bHints, hints, bindableHints); [[nodiscard]] QBindable<QVariantMap> bindableHints() const { return &this->bHints; };
[[nodiscard]] NotificationCloseReason::Enum closeReason() const; [[nodiscard]] NotificationCloseReason::Enum closeReason() const;
void setTracked(bool tracked); void setTracked(bool tracked);

View file

@ -101,23 +101,23 @@ class StatusNotifierItem: public QObject {
// clang-format off // clang-format off
/// A name unique to the application, such as its name. /// A name unique to the application, such as its name.
Q_PROPERTY(QString id READ id NOTIFY idChanged BINDABLE bindableId); Q_PROPERTY(QString id READ default NOTIFY idChanged BINDABLE bindableId);
/// Text that describes the application. /// Text that describes the application.
Q_PROPERTY(QString title READ title NOTIFY titleChanged BINDABLE bindableTitle); Q_PROPERTY(QString title READ default NOTIFY titleChanged BINDABLE bindableTitle);
Q_PROPERTY(qs::service::sni::Status::Enum status READ status NOTIFY statusChanged BINDABLE bindableStatus); Q_PROPERTY(qs::service::sni::Status::Enum status READ default NOTIFY statusChanged BINDABLE bindableStatus);
Q_PROPERTY(qs::service::sni::Category::Enum category READ category NOTIFY categoryChanged BINDABLE bindableCategory); Q_PROPERTY(qs::service::sni::Category::Enum category READ default NOTIFY categoryChanged BINDABLE bindableCategory);
/// Icon source string, usable as an Image source. /// Icon source string, usable as an Image source.
Q_PROPERTY(QString icon READ icon NOTIFY iconChanged BINDABLE bindableIcon); Q_PROPERTY(QString icon READ default NOTIFY iconChanged BINDABLE bindableIcon);
Q_PROPERTY(QString tooltipTitle READ tooltipTitle NOTIFY tooltipTitleChanged); Q_PROPERTY(QString tooltipTitle READ tooltipTitle NOTIFY tooltipTitleChanged);
Q_PROPERTY(QString tooltipDescription READ tooltipDescription NOTIFY tooltipDescriptionChanged); Q_PROPERTY(QString tooltipDescription READ tooltipDescription NOTIFY tooltipDescriptionChanged);
/// If this tray item has an associated menu accessible via @@display() or @@menu. /// If this tray item has an associated menu accessible via @@display() or @@menu.
Q_PROPERTY(bool hasMenu READ hasMenu NOTIFY hasMenuChanged BINDABLE bindableHasMenu); Q_PROPERTY(bool hasMenu READ default NOTIFY hasMenuChanged BINDABLE bindableHasMenu);
/// A handle to the menu associated with this tray item, if any. /// A handle to the menu associated with this tray item, if any.
/// ///
/// Can be displayed with @@Quickshell.QsMenuAnchor or @@Quickshell.QsMenuOpener. /// Can be displayed with @@Quickshell.QsMenuAnchor or @@Quickshell.QsMenuOpener.
Q_PROPERTY(qs::dbus::dbusmenu::DBusMenuHandle* menu READ menuHandle NOTIFY hasMenuChanged); Q_PROPERTY(qs::dbus::dbusmenu::DBusMenuHandle* menu READ menuHandle NOTIFY hasMenuChanged);
/// If this tray item only offers a menu and activation will do nothing. /// If this tray item only offers a menu and activation will do nothing.
Q_PROPERTY(bool onlyMenu READ onlyMenu NOTIFY onlyMenuChanged BINDABLE bindableOnlyMenu); Q_PROPERTY(bool onlyMenu READ default NOTIFY onlyMenuChanged BINDABLE bindableOnlyMenu);
// clang-format on // clang-format on
QML_NAMED_ELEMENT(SystemTrayItem); QML_NAMED_ELEMENT(SystemTrayItem);
QML_UNCREATABLE("SystemTrayItems can only be acquired from SystemTray"); QML_UNCREATABLE("SystemTrayItems can only be acquired from SystemTray");
@ -127,7 +127,7 @@ public:
[[nodiscard]] bool isValid() const; [[nodiscard]] bool isValid() const;
[[nodiscard]] bool isReady() const; [[nodiscard]] bool isReady() const;
QS_BINDABLE_GETTER(QString, bIcon, icon, bindableIcon); [[nodiscard]] QBindable<QString> bindableIcon() const { return &this->bIcon; };
[[nodiscard]] QPixmap createPixmap(const QSize& size) const; [[nodiscard]] QPixmap createPixmap(const QSize& size) const;
[[nodiscard]] dbus::dbusmenu::DBusMenuHandle* menuHandle(); [[nodiscard]] dbus::dbusmenu::DBusMenuHandle* menuHandle();
@ -141,14 +141,14 @@ public:
/// Display a platform menu at the given location relative to the parent window. /// Display a platform menu at the given location relative to the parent window.
Q_INVOKABLE void display(QObject* parentWindow, qint32 relativeX, qint32 relativeY); Q_INVOKABLE void display(QObject* parentWindow, qint32 relativeX, qint32 relativeY);
QS_BINDABLE_GETTER(QString, bId, id, bindableId); [[nodiscard]] QBindable<QString> bindableId() const { return &this->bId; };
QS_BINDABLE_GETTER(QString, bTitle, title, bindableTitle); [[nodiscard]] QBindable<QString> bindableTitle() const { return &this->bTitle; };
QS_BINDABLE_GETTER(Status::Enum, bStatus, status, bindableStatus); [[nodiscard]] QBindable<Status::Enum> bindableStatus() const { return &this->bStatus; };
QS_BINDABLE_GETTER(Category::Enum, bCategory, category, bindableCategory); [[nodiscard]] QBindable<Category::Enum> bindableCategory() const { return &this->bCategory; };
[[nodiscard]] QString tooltipTitle() const { return this->bTooltip.value().title; }; [[nodiscard]] QString tooltipTitle() const { return this->bTooltip.value().title; };
[[nodiscard]] QString tooltipDescription() const { return this->bTooltip.value().description; }; [[nodiscard]] QString tooltipDescription() const { return this->bTooltip.value().description; };
QS_BINDABLE_GETTER(bool, bHasMenu, hasMenu, bindableHasMenu); [[nodiscard]] QBindable<bool> bindableHasMenu() const { return &this->bHasMenu; };
QS_BINDABLE_GETTER(bool, bIsMenu, onlyMenu, bindableOnlyMenu); [[nodiscard]] QBindable<bool> bindableOnlyMenu() const { return &this->bIsMenu; };
signals: signals:
void ready(); void ready();

View file

@ -30,5 +30,6 @@ void SystemTray::onItemUnregistered(StatusNotifierItem* item) { this->mItems.rem
ObjectModel<StatusNotifierItem>* SystemTray::items() { return &this->mItems; } ObjectModel<StatusNotifierItem>* SystemTray::items() { return &this->mItems; }
bool SystemTray::compareItems(StatusNotifierItem* a, StatusNotifierItem* b) { bool SystemTray::compareItems(StatusNotifierItem* a, StatusNotifierItem* b) {
return a->category() < b->category() || a->id().compare(b->id(), Qt::CaseInsensitive) >= 0; return a->bindableCategory().value() < b->bindableCategory().value()
|| a->bindableId().value().compare(b->bindableId().value(), Qt::CaseInsensitive) >= 0;
} }

View file

@ -22,7 +22,7 @@ class UPower: public QObject {
public: public:
[[nodiscard]] UPowerDevice* displayDevice(); [[nodiscard]] UPowerDevice* displayDevice();
[[nodiscard]] ObjectModel<UPowerDevice>* devices(); [[nodiscard]] ObjectModel<UPowerDevice>* devices();
QS_BINDABLE_GETTER(bool, bOnBattery, onBattery, bindableOnBattery); [[nodiscard]] QBindable<bool> bindableOnBattery() const { return &this->bOnBattery; };
static UPower* instance(); static UPower* instance();
@ -77,7 +77,7 @@ class UPowerQml: public QObject {
QSDOC_TYPE_OVERRIDE(ObjectModel<qs::service::upower::UPowerDevice>*); QSDOC_TYPE_OVERRIDE(ObjectModel<qs::service::upower::UPowerDevice>*);
Q_PROPERTY(UntypedObjectModel* devices READ devices CONSTANT); Q_PROPERTY(UntypedObjectModel* devices READ devices CONSTANT);
/// If the system is currently running on battery power, or discharging. /// If the system is currently running on battery power, or discharging.
Q_PROPERTY(bool onBattery READ onBattery NOTIFY onBatteryChanged BINDABLE bindableOnBattery); Q_PROPERTY(bool onBattery READ default NOTIFY onBatteryChanged BINDABLE bindableOnBattery);
// clang-format on // clang-format on
public: public:
@ -85,7 +85,6 @@ public:
[[nodiscard]] UPowerDevice* displayDevice(); [[nodiscard]] UPowerDevice* displayDevice();
[[nodiscard]] ObjectModel<UPowerDevice>* devices(); [[nodiscard]] ObjectModel<UPowerDevice>* devices();
[[nodiscard]] static bool onBattery() { return UPower::instance()->onBattery(); }
[[nodiscard]] static QBindable<bool> bindableOnBattery() { [[nodiscard]] static QBindable<bool> bindableOnBattery() {
return UPower::instance()->bindableOnBattery(); return UPower::instance()->bindableOnBattery();

View file

@ -116,50 +116,50 @@ class UPowerDevice: public QObject {
Q_OBJECT; Q_OBJECT;
// clang-format off // clang-format off
/// The type of device. /// The type of device.
Q_PROPERTY(qs::service::upower::UPowerDeviceType::Enum type READ type NOTIFY typeChanged BINDABLE bindableType); Q_PROPERTY(qs::service::upower::UPowerDeviceType::Enum type READ default NOTIFY typeChanged BINDABLE bindableType);
/// If the device is a power supply for your computer and can provide charge. /// If the device is a power supply for your computer and can provide charge.
Q_PROPERTY(bool powerSupply READ powerSupply NOTIFY powerSupplyChanged BINDABLE bindablePowerSupply); Q_PROPERTY(bool powerSupply READ default NOTIFY powerSupplyChanged BINDABLE bindablePowerSupply);
/// Current energy level of the device in watt-hours. /// Current energy level of the device in watt-hours.
Q_PROPERTY(qreal energy READ energy NOTIFY energyChanged BINDABLE bindableEnergy); Q_PROPERTY(qreal energy READ default NOTIFY energyChanged BINDABLE bindableEnergy);
/// Maximum energy capacity of the device in watt-hours /// Maximum energy capacity of the device in watt-hours
Q_PROPERTY(qreal energyCapacity READ energyCapacity NOTIFY energyCapacityChanged BINDABLE bindableEnergyCapacity); Q_PROPERTY(qreal energyCapacity READ default NOTIFY energyCapacityChanged BINDABLE bindableEnergyCapacity);
/// Rate of energy change in watts (positive when charging, negative when discharging). /// Rate of energy change in watts (positive when charging, negative when discharging).
Q_PROPERTY(qreal changeRate READ changeRate NOTIFY changeRateChanged BINDABLE bindableChangeRate); Q_PROPERTY(qreal changeRate READ default NOTIFY changeRateChanged BINDABLE bindableChangeRate);
/// Estimated time until the device is fully discharged, in seconds. /// Estimated time until the device is fully discharged, in seconds.
/// ///
/// Will be set to `0` if charging. /// Will be set to `0` if charging.
Q_PROPERTY(qreal timeToEmpty READ timeToEmpty NOTIFY timeToEmptyChanged BINDABLE bindableTimeToEmpty); Q_PROPERTY(qreal timeToEmpty READ default NOTIFY timeToEmptyChanged BINDABLE bindableTimeToEmpty);
/// Estimated time until the device is fully charged, in seconds. /// Estimated time until the device is fully charged, in seconds.
/// ///
/// Will be set to `0` if discharging. /// Will be set to `0` if discharging.
Q_PROPERTY(qreal timeToFull READ timeToFull NOTIFY timeToFullChanged BINDABLE bindableTimeToFull); Q_PROPERTY(qreal timeToFull READ default NOTIFY timeToFullChanged BINDABLE bindableTimeToFull);
/// Current charge level as a percentage. /// Current charge level as a percentage.
/// ///
/// This would be equivalent to @@energy / @@energyCapacity. /// This would be equivalent to @@energy / @@energyCapacity.
Q_PROPERTY(qreal percentage READ percentage NOTIFY percentageChanged BINDABLE bindablePercentage); Q_PROPERTY(qreal percentage READ default NOTIFY percentageChanged BINDABLE bindablePercentage);
/// If the power source is present in the bay or slot, useful for hot-removable batteries. /// If the power source is present in the bay or slot, useful for hot-removable batteries.
/// ///
/// If the device `type` is not `Battery`, then the property will be invalid. /// If the device `type` is not `Battery`, then the property will be invalid.
Q_PROPERTY(bool isPresent READ isPresent NOTIFY isPresentChanged BINDABLE bindableIsPresent); Q_PROPERTY(bool isPresent READ default NOTIFY isPresentChanged BINDABLE bindableIsPresent);
/// Current state of the device. /// Current state of the device.
Q_PROPERTY(qs::service::upower::UPowerDeviceState::Enum state READ state NOTIFY stateChanged BINDABLE bindableState); Q_PROPERTY(qs::service::upower::UPowerDeviceState::Enum state READ default NOTIFY stateChanged BINDABLE bindableState);
/// Health of the device as a percentage of its original health. /// Health of the device as a percentage of its original health.
Q_PROPERTY(qreal healthPercentage READ healthPercentage NOTIFY healthPercentageChanged BINDABLE bindableHealthPercentage); Q_PROPERTY(qreal healthPercentage READ default NOTIFY healthPercentageChanged BINDABLE bindableHealthPercentage);
Q_PROPERTY(bool healthSupported READ healthSupported NOTIFY healthSupportedChanged BINDABLE bindableHealthSupported); Q_PROPERTY(bool healthSupported READ default NOTIFY healthSupportedChanged BINDABLE bindableHealthSupported);
/// Name of the icon representing the current state of the device, or an empty string if not provided. /// Name of the icon representing the current state of the device, or an empty string if not provided.
Q_PROPERTY(QString iconName READ iconName NOTIFY iconNameChanged BINDABLE bindableIconName); Q_PROPERTY(QString iconName READ default NOTIFY iconNameChanged BINDABLE bindableIconName);
/// If the device is a laptop battery or not. Use this to check if your device is a valid battery. /// If the device is a laptop battery or not. Use this to check if your device is a valid battery.
/// ///
/// This will be equivalent to @@type == Battery && @@powerSupply == true. /// This will be equivalent to @@type == Battery && @@powerSupply == true.
Q_PROPERTY(bool isLaptopBattery READ isLaptopBattery NOTIFY isLaptopBatteryChanged BINDABLE bindableIsLaptopBattery); Q_PROPERTY(bool isLaptopBattery READ default NOTIFY isLaptopBatteryChanged BINDABLE bindableIsLaptopBattery);
/// Native path of the device specific to your OS. /// Native path of the device specific to your OS.
Q_PROPERTY(QString nativePath READ nativePath NOTIFY nativePathChanged BINDABLE bindableNativePath); Q_PROPERTY(QString nativePath READ default NOTIFY nativePathChanged BINDABLE bindableNativePath);
/// Model name of the device. Unlikely to be useful for internal devices. /// Model name of the device. Unlikely to be useful for internal devices.
Q_PROPERTY(QString model READ model NOTIFY modelChanged BINDABLE bindableModel); Q_PROPERTY(QString model READ default NOTIFY modelChanged BINDABLE bindableModel);
/// If device statistics have been queried for this device yet. /// If device statistics have been queried for this device yet.
/// This will be true for all devices returned from @@UPower.devices, but not the default /// This will be true for all devices returned from @@UPower.devices, but not the default
/// device, which may be returned before it is ready to avoid returning null. /// device, which may be returned before it is ready to avoid returning null.
Q_PROPERTY(bool ready READ ready NOTIFY readyChanged BINDABLE bindableReady); Q_PROPERTY(bool ready READ default NOTIFY readyChanged BINDABLE bindableReady);
// clang-format on // clang-format on
QML_ELEMENT; QML_ELEMENT;
QML_UNCREATABLE("UPowerDevices can only be acquired from UPower"); QML_UNCREATABLE("UPowerDevices can only be acquired from UPower");
@ -173,23 +173,25 @@ public:
[[nodiscard]] QString address() const; [[nodiscard]] QString address() const;
[[nodiscard]] QString path() const; [[nodiscard]] QString path() const;
QS_BINDABLE_GETTER(UPowerDeviceType::Enum, bType, type, bindableType); [[nodiscard]] QBindable<UPowerDeviceType::Enum> bindableType() const { return &this->bType; };
QS_BINDABLE_GETTER(bool, bPowerSupply, powerSupply, bindablePowerSupply); [[nodiscard]] QBindable<bool> bindablePowerSupply() const { return &this->bPowerSupply; };
QS_BINDABLE_GETTER(qreal, bEnergy, energy, bindableEnergy); [[nodiscard]] QBindable<qreal> bindableEnergy() const { return &this->bEnergy; };
QS_BINDABLE_GETTER(qreal, bEnergyCapacity, energyCapacity, bindableEnergyCapacity); [[nodiscard]] QBindable<qreal> bindableEnergyCapacity() const { return &this->bEnergyCapacity; };
QS_BINDABLE_GETTER(qreal, bChangeRate, changeRate, bindableChangeRate); [[nodiscard]] QBindable<qreal> bindableChangeRate() const { return &this->bChangeRate; };
QS_BINDABLE_GETTER(qlonglong, bTimeToEmpty, timeToEmpty, bindableTimeToEmpty); [[nodiscard]] QBindable<qlonglong> bindableTimeToEmpty() const { return &this->bTimeToEmpty; };
QS_BINDABLE_GETTER(qlonglong, bTimeToFull, timeToFull, bindableTimeToFull); [[nodiscard]] QBindable<qlonglong> bindableTimeToFull() const { return &this->bTimeToFull; };
QS_BINDABLE_GETTER(qreal, bPercentage, percentage, bindablePercentage); [[nodiscard]] QBindable<qreal> bindablePercentage() const { return &this->bPercentage; };
QS_BINDABLE_GETTER(bool, bIsPresent, isPresent, bindableIsPresent); [[nodiscard]] QBindable<bool> bindableIsPresent() const { return &this->bIsPresent; };
QS_BINDABLE_GETTER(UPowerDeviceState::Enum, bState, state, bindableState); [[nodiscard]] QBindable<UPowerDeviceState::Enum> bindableState() const { return &this->bState; };
QS_BINDABLE_GETTER(qreal, bHealthPercentage, healthPercentage, bindableHealthPercentage); [[nodiscard]] QBindable<qreal> bindableHealthPercentage() const {
QS_BINDABLE_GETTER(bool, bHealthSupported, healthSupported, bindableHealthSupported); return &this->bHealthPercentage;
QS_BINDABLE_GETTER(QString, bIconName, iconName, bindableIconName); };
QS_BINDABLE_GETTER(bool, bIsLaptopBattery, isLaptopBattery, bindableIsLaptopBattery); [[nodiscard]] QBindable<bool> bindableHealthSupported() const { return &this->bHealthSupported; };
QS_BINDABLE_GETTER(QString, bNativePath, nativePath, bindableNativePath); [[nodiscard]] QBindable<QString> bindableIconName() const { return &this->bIconName; };
QS_BINDABLE_GETTER(QString, bModel, model, bindableModel); [[nodiscard]] QBindable<bool> bindableIsLaptopBattery() const { return &this->bIsLaptopBattery; };
QS_BINDABLE_GETTER(bool, bReady, ready, bindableReady); [[nodiscard]] QBindable<QString> bindableNativePath() const { return &this->bNativePath; };
[[nodiscard]] QBindable<QString> bindableModel() const { return &this->bModel; };
[[nodiscard]] QBindable<bool> bindableReady() const { return &this->bReady; };
signals: signals:
QSDOC_HIDE void readyChanged(); QSDOC_HIDE void readyChanged();

View file

@ -43,8 +43,8 @@ class ProxyWindowBase: public Reloadable {
Q_PROPERTY(QQuickWindow* _backingWindow READ backingWindow); Q_PROPERTY(QQuickWindow* _backingWindow READ backingWindow);
Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT); Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT);
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged); Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged);
Q_PROPERTY(qint32 implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged BINDABLE bindableImplicitWidth); Q_PROPERTY(qint32 implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged);
Q_PROPERTY(qint32 implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged BINDABLE bindableImplicitHeight); Q_PROPERTY(qint32 implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged);
Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged); Q_PROPERTY(qint32 width READ width WRITE setWidth NOTIFY widthChanged);
Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged); Q_PROPERTY(qint32 height READ height WRITE setHeight NOTIFY heightChanged);
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged); Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged);
@ -97,11 +97,9 @@ public:
[[nodiscard]] qint32 implicitWidth() const { return this->bImplicitWidth; } [[nodiscard]] qint32 implicitWidth() const { return this->bImplicitWidth; }
void setImplicitWidth(qint32 implicitWidth); void setImplicitWidth(qint32 implicitWidth);
QBindable<qint32> bindableImplicitWidth() { return &this->bImplicitWidth; }
[[nodiscard]] qint32 implicitHeight() const { return this->bImplicitHeight; } [[nodiscard]] qint32 implicitHeight() const { return this->bImplicitHeight; }
void setImplicitHeight(qint32 implicitHeight); void setImplicitHeight(qint32 implicitHeight);
QBindable<qint32> bindableImplicitHeight() { return &this->bImplicitHeight; }
[[nodiscard]] virtual qint32 width() const; [[nodiscard]] virtual qint32 width() const;
void setWidth(qint32 width); void setWidth(qint32 width);