mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Compare commits
6 commits
701d60b2fe
...
611e3e8350
Author | SHA1 | Date | |
---|---|---|---|
611e3e8350 | |||
a4a476bd19 | |||
7d7f1b3bea | |||
5cd4c51f07 | |||
5f2e01b611 | |||
7604d7ea4a |
|
@ -26,7 +26,8 @@
|
|||
- Minor: Normalized the input padding between light & dark themes. (#5095)
|
||||
- Minor: Add `--activate <channel>` (or `-a`) command line option to activate or add a Twitch channel. (#5111)
|
||||
- Minor: Chatters from recent-messages are now added to autocompletion. (#5116)
|
||||
- Minor: Add _System_ theme that updates according to the system's color scheme (requires Qt 6.5). (#5118)
|
||||
- Minor: Added a _System_ theme that updates according to the system's color scheme (requires Qt 6.5). (#5118)
|
||||
- Minor: Added support for the `{input.text}` placeholder in the **Split** -> **Run a command** hotkey. (#5130)
|
||||
- Bugfix: Fixed an issue where certain emojis did not send to Twitch chat correctly. (#4840)
|
||||
- Bugfix: Fixed capitalized channel names in log inclusion list not being logged. (#4848)
|
||||
- Bugfix: Trimmed custom streamlink paths on all platforms making sure you don't accidentally add spaces at the beginning or end of its path. (#4834)
|
||||
|
@ -133,6 +134,8 @@
|
|||
- Dev: Fix `NotebookTab` emitting updates for every message. (#5068)
|
||||
- Dev: Added benchmark for parsing and building recent messages. (#5071)
|
||||
- Dev: Boost is depended on as a header-only library when using conan. (#5107)
|
||||
- Dev: Added signal to invalidate paint buffers of channel views without forcing a relayout. (#5123)
|
||||
- Dev: Specialize `Atomic<std::shared_ptr<T>>` if underlying standard library supports it. (#5133)
|
||||
|
||||
## 2.4.6
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7e99623f5f6862d226df9d5049edf1c8532be028
|
||||
Subproject commit 53be0788a000960dbbc34350315e20ad1e194970
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace chatterino {
|
||||
|
@ -9,9 +11,10 @@ class Atomic
|
|||
{
|
||||
public:
|
||||
Atomic() = default;
|
||||
~Atomic() = default;
|
||||
|
||||
Atomic(T &&val)
|
||||
: value_(val)
|
||||
: value_(std::move(val))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,4 +50,67 @@ private:
|
|||
T value_;
|
||||
};
|
||||
|
||||
#if defined(__cpp_lib_atomic_shared_ptr) && defined(__cpp_concepts)
|
||||
|
||||
template <typename T>
|
||||
class Atomic<std::shared_ptr<T>>
|
||||
{
|
||||
// Atomic<std::shared_ptr<T>> must be instantated with a const T
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
requires std::is_const_v<T>
|
||||
class Atomic<std::shared_ptr<T>>
|
||||
{
|
||||
public:
|
||||
Atomic() = default;
|
||||
~Atomic() = default;
|
||||
|
||||
Atomic(T &&val)
|
||||
: value_(std::make_shared<T>(std::move(val)))
|
||||
{
|
||||
}
|
||||
|
||||
Atomic(std::shared_ptr<T> &&val)
|
||||
: value_(std::move(val))
|
||||
{
|
||||
}
|
||||
|
||||
Atomic(const Atomic &) = delete;
|
||||
Atomic &operator=(const Atomic &) = delete;
|
||||
|
||||
Atomic(Atomic &&) = delete;
|
||||
Atomic &operator=(Atomic &&) = delete;
|
||||
|
||||
std::shared_ptr<T> get() const
|
||||
{
|
||||
return this->value_.load();
|
||||
}
|
||||
|
||||
void set(const T &val)
|
||||
{
|
||||
this->value_.store(std::make_shared<T>(val));
|
||||
}
|
||||
|
||||
void set(T &&val)
|
||||
{
|
||||
this->value_.store(std::make_shared<T>(std::move(val)));
|
||||
}
|
||||
|
||||
void set(const std::shared_ptr<T> &val)
|
||||
{
|
||||
this->value_.store(val);
|
||||
}
|
||||
|
||||
void set(std::shared_ptr<T> &&val)
|
||||
{
|
||||
this->value_.store(std::move(val));
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<std::shared_ptr<T>> value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace chatterino
|
||||
|
|
|
@ -74,7 +74,8 @@ int MessageLayout::getWidth() const
|
|||
|
||||
// Layout
|
||||
// return true if redraw is required
|
||||
bool MessageLayout::layout(int width, float scale, MessageElementFlags flags)
|
||||
bool MessageLayout::layout(int width, float scale, MessageElementFlags flags,
|
||||
bool shouldInvalidateBuffer)
|
||||
{
|
||||
// BenchmarkGuard benchmark("MessageLayout::layout()");
|
||||
|
||||
|
@ -108,6 +109,11 @@ bool MessageLayout::layout(int width, float scale, MessageElementFlags flags)
|
|||
|
||||
if (!layoutRequired)
|
||||
{
|
||||
if (shouldInvalidateBuffer)
|
||||
{
|
||||
this->invalidateBuffer();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ public:
|
|||
|
||||
MessageLayoutFlags flags;
|
||||
|
||||
bool layout(int width, float scale_, MessageElementFlags flags);
|
||||
bool layout(int width, float scale_, MessageElementFlags flags,
|
||||
bool shouldInvalidateBuffer);
|
||||
|
||||
// Painting
|
||||
MessagePaintResult paint(const MessagePaintContext &ctx);
|
||||
|
|
|
@ -211,6 +211,11 @@ void WindowManager::forceLayoutChannelViews()
|
|||
this->layoutChannelViews(nullptr);
|
||||
}
|
||||
|
||||
void WindowManager::invalidateChannelViewBuffers(Channel *channel)
|
||||
{
|
||||
this->invalidateBuffersRequested.invoke(channel);
|
||||
}
|
||||
|
||||
void WindowManager::repaintVisibleChatWidgets(Channel *channel)
|
||||
{
|
||||
this->layoutRequested.invoke(channel);
|
||||
|
@ -407,10 +412,10 @@ void WindowManager::initialize(Settings &settings, const Paths &paths)
|
|||
this->forceLayoutChannelViews();
|
||||
});
|
||||
settings.alternateMessages.connect([this](auto, auto) {
|
||||
this->forceLayoutChannelViews();
|
||||
this->invalidateChannelViewBuffers();
|
||||
});
|
||||
settings.separateMessages.connect([this](auto, auto) {
|
||||
this->forceLayoutChannelViews();
|
||||
this->invalidateChannelViewBuffers();
|
||||
});
|
||||
settings.collpseMessagesMinLines.connect([this](auto, auto) {
|
||||
this->forceLayoutChannelViews();
|
||||
|
|
|
@ -66,6 +66,10 @@ public:
|
|||
// This is called, for example, when the emote scale or timestamp format has
|
||||
// changed
|
||||
void forceLayoutChannelViews();
|
||||
|
||||
// Tell a channel (or all channels if channel is nullptr) to invalidate all paint buffers
|
||||
void invalidateChannelViewBuffers(Channel *channel = nullptr);
|
||||
|
||||
void repaintVisibleChatWidgets(Channel *channel = nullptr);
|
||||
void repaintGifEmotes();
|
||||
|
||||
|
@ -124,6 +128,9 @@ public:
|
|||
// This signal fires whenever views rendering a channel, or all views if the
|
||||
// channel is a nullptr, need to redo their layout
|
||||
pajlada::Signals::Signal<Channel *> layoutRequested;
|
||||
// This signal fires whenever views rendering a channel, or all views if the
|
||||
// channel is a nullptr, need to invalidate their paint buffers
|
||||
pajlada::Signals::Signal<Channel *> invalidateBuffersRequested;
|
||||
|
||||
pajlada::Signals::NoArgSignal wordFlagsChanged;
|
||||
|
||||
|
|
|
@ -425,6 +425,16 @@ void ChannelView::initializeSignals()
|
|||
}
|
||||
});
|
||||
|
||||
this->signalHolder_.managedConnect(
|
||||
getIApp()->getWindows()->invalidateBuffersRequested,
|
||||
[this](Channel *channel) {
|
||||
if (this->isVisible() &&
|
||||
(channel == nullptr || this->channel_.get() == channel))
|
||||
{
|
||||
this->invalidateBuffers();
|
||||
}
|
||||
});
|
||||
|
||||
this->signalHolder_.managedConnect(getIApp()->getFonts()->fontChanged,
|
||||
[this] {
|
||||
this->queueLayout();
|
||||
|
@ -590,6 +600,12 @@ void ChannelView::queueUpdate(const QRect &area)
|
|||
this->update(area);
|
||||
}
|
||||
|
||||
void ChannelView::invalidateBuffers()
|
||||
{
|
||||
this->bufferInvalidationQueued_ = true;
|
||||
this->queueLayout();
|
||||
}
|
||||
|
||||
void ChannelView::queueLayout()
|
||||
{
|
||||
if (this->isVisible())
|
||||
|
@ -651,12 +667,13 @@ void ChannelView::layoutVisibleMessages(
|
|||
{
|
||||
const auto &message = messages[i];
|
||||
|
||||
redrawRequired |=
|
||||
message->layout(layoutWidth, this->scale(), flags);
|
||||
redrawRequired |= message->layout(layoutWidth, this->scale(), flags,
|
||||
this->bufferInvalidationQueued_);
|
||||
|
||||
y += message->getHeight();
|
||||
}
|
||||
}
|
||||
this->bufferInvalidationQueued_ = false;
|
||||
|
||||
if (redrawRequired)
|
||||
{
|
||||
|
@ -685,7 +702,7 @@ void ChannelView::updateScrollbar(
|
|||
{
|
||||
auto *message = messages[i].get();
|
||||
|
||||
message->layout(layoutWidth, this->scale(), flags);
|
||||
message->layout(layoutWidth, this->scale(), flags, false);
|
||||
|
||||
h -= message->getHeight();
|
||||
|
||||
|
@ -1656,7 +1673,8 @@ void ChannelView::wheelEvent(QWheelEvent *event)
|
|||
else
|
||||
{
|
||||
snapshot[i - 1]->layout(this->getLayoutWidth(),
|
||||
this->scale(), this->getFlags());
|
||||
this->scale(), this->getFlags(),
|
||||
false);
|
||||
scrollFactor = 1;
|
||||
currentScrollLeft = snapshot[i - 1]->getHeight();
|
||||
}
|
||||
|
@ -1690,7 +1708,8 @@ void ChannelView::wheelEvent(QWheelEvent *event)
|
|||
else
|
||||
{
|
||||
snapshot[i + 1]->layout(this->getLayoutWidth(),
|
||||
this->scale(), this->getFlags());
|
||||
this->scale(), this->getFlags(),
|
||||
false);
|
||||
|
||||
scrollFactor = 1;
|
||||
currentScrollLeft = snapshot[i + 1]->getHeight();
|
||||
|
|
|
@ -148,7 +148,9 @@ public:
|
|||
bool hasSourceChannel() const;
|
||||
|
||||
LimitedQueueSnapshot<MessageLayoutPtr> &getMessagesSnapshot();
|
||||
|
||||
void queueLayout();
|
||||
void invalidateBuffers();
|
||||
|
||||
void clearMessages();
|
||||
|
||||
|
@ -270,6 +272,7 @@ private:
|
|||
bool canReplyToMessages() const;
|
||||
|
||||
bool layoutQueued_ = false;
|
||||
bool bufferInvalidationQueued_ = false;
|
||||
|
||||
bool lastMessageHasAlternateBackground_ = false;
|
||||
bool lastMessageHasAlternateBackgroundReverse_ = true;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "common/network/NetworkResult.hpp"
|
||||
#include "common/QLogging.hpp"
|
||||
#include "controllers/accounts/AccountController.hpp"
|
||||
#include "controllers/commands/Command.hpp"
|
||||
#include "controllers/commands/CommandController.hpp"
|
||||
#include "controllers/hotkeys/HotkeyController.hpp"
|
||||
#include "controllers/notifications/NotificationController.hpp"
|
||||
|
@ -684,15 +685,25 @@ void Split::addShortcuts()
|
|||
}},
|
||||
{"runCommand",
|
||||
[this](std::vector<QString> arguments) -> QString {
|
||||
if (arguments.size() == 0)
|
||||
if (arguments.empty())
|
||||
{
|
||||
qCWarning(chatterinoHotkeys)
|
||||
<< "runCommand hotkey called without arguments!";
|
||||
return "runCommand hotkey called without arguments!";
|
||||
}
|
||||
QString command = getIApp()->getCommands()->execCommand(
|
||||
arguments.at(0).replace('\n', ' '), this->getChannel(), false);
|
||||
this->getChannel()->sendMessage(command);
|
||||
QString requestedText = arguments.at(0).replace('\n', ' ');
|
||||
|
||||
QString inputText = this->getInput().getInputText();
|
||||
QString message = getIApp()->getCommands()->execCustomCommand(
|
||||
requestedText.split(' '), Command{"(hotkey)", requestedText},
|
||||
true, this->getChannel(), nullptr,
|
||||
{
|
||||
{"input.text", inputText},
|
||||
});
|
||||
|
||||
message = getIApp()->getCommands()->execCommand(
|
||||
message, this->getChannel(), false);
|
||||
this->getChannel()->sendMessage(message);
|
||||
return "";
|
||||
}},
|
||||
{"setChannelNotification",
|
||||
|
|
Loading…
Reference in a new issue