clipboard: switched to async_texture_cache

This commit is contained in:
Lemmy
2026-05-08 08:28:46 -04:00
parent cb9d7c2d65
commit 6a97090a64
4 changed files with 53 additions and 14 deletions
+2 -1
View File
@@ -827,7 +827,8 @@ void Application::initUi() {
}
m_settingsWindow.open();
});
auto clipboardPanel = std::make_unique<ClipboardPanel>(&m_clipboardService, &m_configService, &m_thumbnailService);
auto clipboardPanel = std::make_unique<ClipboardPanel>(&m_clipboardService, &m_configService, &m_thumbnailService,
&m_asyncTextureCache);
clipboardPanel->setActivateCallback([this](const ClipboardEntry& entry) {
m_panelManager.close();
const ClipboardAutoPasteMode mode = m_configService.config().shell.clipboardAutoPaste;
+22 -1
View File
@@ -8,6 +8,7 @@
#include <cmath>
#include <cstdint>
#include <cstring>
#include <stb_image_resize2.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wexpansion-to-defined"
#include <librsvg/rsvg.h>
@@ -164,7 +165,27 @@ std::optional<LoadedImageFile> loadImageFile(const std::string& path, int target
}
if (auto decoded = decodeRasterImage(fileData.data(), fileData.size(), errorMessage)) {
return LoadedImageFile{.rgba = std::move(decoded->pixels), .width = decoded->width, .height = decoded->height};
int width = decoded->width;
int height = decoded->height;
auto pixels = std::move(decoded->pixels);
const int maxDim = std::max(width, height);
if (targetSize > 0 && maxDim > targetSize && width > 0 && height > 0) {
const float scale = static_cast<float>(targetSize) / static_cast<float>(maxDim);
const int resizedW = std::max(1, static_cast<int>(std::lround(static_cast<float>(width) * scale)));
const int resizedH = std::max(1, static_cast<int>(std::lround(static_cast<float>(height) * scale)));
std::vector<std::uint8_t> resized(static_cast<std::size_t>(resizedW) * static_cast<std::size_t>(resizedH) * 4U);
unsigned char* result =
stbir_resize_uint8_linear(pixels.data(), width, height, 0, resized.data(), resizedW, resizedH, 0, STBIR_RGBA);
if (result != nullptr) {
pixels = std::move(resized);
width = resizedW;
height = resizedH;
}
}
return LoadedImageFile{.rgba = std::move(pixels), .width = width, .height = height};
}
return std::nullopt;
+24 -11
View File
@@ -1,8 +1,10 @@
#include "shell/clipboard/clipboard_panel.h"
#include "config/config_service.h"
#include "core/deferred_call.h"
#include "core/ui_phase.h"
#include "i18n/i18n.h"
#include "render/core/async_texture_cache.h"
#include "render/core/renderer.h"
#include "render/scene/input_area.h"
#include "shell/control_center/tab.h"
@@ -23,6 +25,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
#include <ctime>
#include <memory>
#include <optional>
@@ -359,8 +362,9 @@ private:
std::function<void(std::size_t)> m_onActivate;
};
ClipboardPanel::ClipboardPanel(ClipboardService* clipboard, ConfigService* config, ThumbnailService* thumbnails)
: m_clipboard(clipboard), m_config(config), m_thumbnails(thumbnails) {}
ClipboardPanel::ClipboardPanel(ClipboardService* clipboard, ConfigService* config, ThumbnailService* thumbnails,
AsyncTextureCache* asyncTextures)
: m_clipboard(clipboard), m_config(config), m_thumbnails(thumbnails), m_asyncTextures(asyncTextures) {}
ClipboardPanel::~ClipboardPanel() = default;
@@ -720,6 +724,9 @@ void ClipboardPanel::onClose() {
if (m_clipboard != nullptr) {
m_clipboard->evictAllPayloads();
}
if (m_asyncTextures != nullptr) {
DeferredCall::callLater([asyncTextures = m_asyncTextures]() { asyncTextures->trimUnused(0); });
}
}
InputArea* ClipboardPanel::initialFocusArea() const {
@@ -824,22 +831,28 @@ void ClipboardPanel::rebuildPreview(Renderer& renderer, float width, float heigh
return;
}
if (m_clipboard != nullptr) {
if (m_previewPayloadIndex != static_cast<std::size_t>(-1) && m_previewPayloadIndex != historyIndex) {
m_clipboard->evictEntryPayload(m_previewPayloadIndex);
}
(void)m_clipboard->ensureEntryLoaded(historyIndex);
if (m_clipboard != nullptr && m_previewPayloadIndex != static_cast<std::size_t>(-1) &&
m_previewPayloadIndex != historyIndex) {
m_clipboard->evictEntryPayload(m_previewPayloadIndex);
}
const auto& loadedEntry = m_clipboard != nullptr ? m_clipboard->history()[historyIndex] : entry;
if (loadedEntry.isImage()) {
if (entry.isImage()) {
auto image = std::make_unique<Image>();
image->setSize(width, std::min(kPreviewImageHeight, std::max(180.0f, height - Style::spaceMd)));
const float imageHeight = std::min(kPreviewImageHeight, std::max(180.0f, height - Style::spaceMd));
image->setSize(width, imageHeight);
image->setFit(ImageFit::Contain);
image->setSourceBytes(renderer, loadedEntry.data.data(), loadedEntry.data.size());
const int previewTargetSize = static_cast<int>(std::ceil(std::max(width, imageHeight)));
image->setAsyncReadyCallback([]() { PanelManager::instance().refresh(); });
if (m_asyncTextures != nullptr && !entry.payloadPath.empty()) {
(void)image->setSourceFileAsync(renderer, *m_asyncTextures, entry.payloadPath, previewTargetSize);
}
m_previewImage = image.get();
m_previewContent->addChild(std::move(image));
} else {
if (m_clipboard != nullptr) {
(void)m_clipboard->ensureEntryLoaded(historyIndex);
}
const auto& loadedEntry = m_clipboard != nullptr ? m_clipboard->history()[historyIndex] : entry;
constexpr std::size_t kMaxPreviewChars = 8000;
constexpr int kMaxPreviewLines = 200;
+5 -1
View File
@@ -5,6 +5,8 @@
#include "shell/panel/panel.h"
#include "wayland/clipboard_service.h"
class AsyncTextureCache;
#include <cstddef>
#include <cstdint>
#include <functional>
@@ -27,7 +29,8 @@ class VirtualGridView;
class ClipboardPanel : public Panel {
public:
ClipboardPanel(ClipboardService* clipboard, ConfigService* config, ThumbnailService* thumbnails);
ClipboardPanel(ClipboardService* clipboard, ConfigService* config, ThumbnailService* thumbnails,
AsyncTextureCache* asyncTextures);
~ClipboardPanel() override;
void setActivateCallback(std::function<void(const ClipboardEntry&)> callback);
@@ -63,6 +66,7 @@ private:
std::function<void(const ClipboardEntry&)> m_activateCallback;
ConfigService* m_config = nullptr;
ThumbnailService* m_thumbnails = nullptr;
AsyncTextureCache* m_asyncTextures = nullptr;
InputArea* m_focusArea = nullptr;
Flex* m_rootLayout = nullptr;