mirror of
https://github.com/hyprwm/hyprpicker.git
synced 2024-12-22 06:09:48 +01:00
core: implement fractional scaling support
Additionally, adds --quiet, --verbose.
This commit is contained in:
parent
c9238d39f6
commit
ed3f644af7
7 changed files with 102 additions and 46 deletions
|
@ -8,6 +8,12 @@
|
|||
void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||
std::string levelstr = "";
|
||||
|
||||
if (quiet && (level != ERR && level != CRIT))
|
||||
return;
|
||||
|
||||
if (!verbose && level == TRACE)
|
||||
return;
|
||||
|
||||
switch (level) {
|
||||
case LOG: levelstr = "[LOG] "; break;
|
||||
case WARN: levelstr = "[WARN] "; break;
|
||||
|
|
|
@ -9,9 +9,11 @@ enum LogLevel {
|
|||
WARN,
|
||||
ERR,
|
||||
CRIT,
|
||||
INFO
|
||||
INFO,
|
||||
TRACE,
|
||||
};
|
||||
|
||||
namespace Debug {
|
||||
void log(LogLevel level, const char* fmt, ...);
|
||||
inline bool quiet = false, verbose = false;
|
||||
void log(LogLevel level, const char* fmt, ...);
|
||||
};
|
|
@ -13,6 +13,17 @@ CLayerSurface::CLayerSurface(SMonitor* pMonitor) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!g_pHyprpicker->m_bNoFractional) {
|
||||
pViewport = makeShared<CCWpViewport>(g_pHyprpicker->m_pViewporter->sendGetViewport(pSurface->resource()));
|
||||
|
||||
// this will not actually be used, as we assume we'll be fullscreen and we can get the real dimensions from screencopy, but we'll have
|
||||
// this for if we need it in the future
|
||||
pFractionalScale = makeShared<CCWpFractionalScaleV1>(g_pHyprpicker->m_pFractionalMgr->sendGetFractionalScale(pSurface->resource()));
|
||||
pFractionalScale->setPreferredScale([this](CCWpFractionalScaleV1* r, uint32_t scale120) { //
|
||||
Debug::log(TRACE, "Received a preferredScale for %s: %.2f", m_pMonitor->name.c_str(), scale120 / 120.F);
|
||||
});
|
||||
}
|
||||
|
||||
pLayerSurface = makeShared<CCZwlrLayerSurfaceV1>(
|
||||
g_pHyprpicker->m_pLayerShell->sendGetLayerSurface(pSurface->resource(), pMonitor->output->resource(), ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "hyprpicker"));
|
||||
|
||||
|
@ -62,8 +73,15 @@ void CLayerSurface::sendFrame() {
|
|||
frameCallback = makeShared<CCWlCallback>(pSurface->sendFrame());
|
||||
frameCallback->setDone([this](CCWlCallback* r, uint32_t when) { onCallbackDone(this, when); });
|
||||
|
||||
pSurface->sendAttach(lastBuffer == 0 ? buffers[0]->buffer.get() : buffers[1]->buffer.get(), 0, 0);
|
||||
pSurface->sendSetBufferScale(m_pMonitor->scale);
|
||||
const auto& PBUFFER = lastBuffer == 0 ? buffers[0] : buffers[1];
|
||||
|
||||
pSurface->sendAttach(PBUFFER->buffer.get(), 0, 0);
|
||||
if (!g_pHyprpicker->m_bNoFractional) {
|
||||
pSurface->sendSetBufferScale(1);
|
||||
pViewport->sendSetDestination(m_pMonitor->size.x, m_pMonitor->size.y);
|
||||
} else
|
||||
pSurface->sendSetBufferScale(m_pMonitor->scale);
|
||||
|
||||
pSurface->sendDamageBuffer(0, 0, 0xFFFF, 0xFFFF);
|
||||
pSurface->sendCommit();
|
||||
|
||||
|
|
|
@ -10,28 +10,30 @@ class CLayerSurface {
|
|||
CLayerSurface(SMonitor*);
|
||||
~CLayerSurface();
|
||||
|
||||
void sendFrame();
|
||||
void markDirty();
|
||||
void sendFrame();
|
||||
void markDirty();
|
||||
|
||||
SMonitor* m_pMonitor = nullptr;
|
||||
SMonitor* m_pMonitor = nullptr;
|
||||
|
||||
SP<CCZwlrLayerSurfaceV1> pLayerSurface = nullptr;
|
||||
SP<CCWlSurface> pSurface = nullptr;
|
||||
SP<CCZwlrLayerSurfaceV1> pLayerSurface = nullptr;
|
||||
SP<CCWlSurface> pSurface = nullptr;
|
||||
SP<CCWpViewport> pViewport = nullptr;
|
||||
SP<CCWpFractionalScaleV1> pFractionalScale = nullptr;
|
||||
|
||||
bool wantsACK = false;
|
||||
uint32_t ACKSerial = 0;
|
||||
bool working = false;
|
||||
bool wantsACK = false;
|
||||
uint32_t ACKSerial = 0;
|
||||
bool working = false;
|
||||
|
||||
int lastBuffer = 0;
|
||||
SP<SPoolBuffer> buffers[2];
|
||||
int lastBuffer = 0;
|
||||
SP<SPoolBuffer> buffers[2];
|
||||
|
||||
SP<SPoolBuffer> screenBuffer;
|
||||
uint32_t scflags = 0;
|
||||
uint32_t screenBufferFormat = 0;
|
||||
SP<SPoolBuffer> screenBuffer;
|
||||
uint32_t scflags = 0;
|
||||
uint32_t screenBufferFormat = 0;
|
||||
|
||||
bool dirty = true;
|
||||
bool dirty = true;
|
||||
|
||||
bool rendered = false;
|
||||
bool rendered = false;
|
||||
|
||||
SP<CCWlCallback> frameCallback = nullptr;
|
||||
SP<CCWlCallback> frameCallback = nullptr;
|
||||
};
|
|
@ -70,6 +70,11 @@ void CHyprpicker::init() {
|
|||
} else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
|
||||
m_pCursorShapeMgr =
|
||||
makeShared<CCWpCursorShapeManagerV1>((wl_proxy*)wl_registry_bind((wl_registry*)m_pRegistry->resource(), name, &wp_cursor_shape_manager_v1_interface, 1));
|
||||
} else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) {
|
||||
m_pFractionalMgr =
|
||||
makeShared<CCWpFractionalScaleManagerV1>((wl_proxy*)wl_registry_bind((wl_registry*)m_pRegistry->resource(), name, &wp_fractional_scale_manager_v1_interface, 1));
|
||||
} else if (strcmp(interface, wp_viewporter_interface.name) == 0) {
|
||||
m_pViewporter = makeShared<CCWpViewporter>((wl_proxy*)wl_registry_bind((wl_registry*)m_pRegistry->resource(), name, &wp_viewporter_interface, 1));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -83,6 +88,15 @@ void CHyprpicker::init() {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (!m_pFractionalMgr) {
|
||||
Debug::log(WARN, "wp_fractional_scale_v1 not supported, fractional scaling won't work");
|
||||
m_bNoFractional = true;
|
||||
}
|
||||
if (!m_pViewporter) {
|
||||
Debug::log(WARN, "wp_viewporter not supported, fractional scaling won't work");
|
||||
m_bNoFractional = true;
|
||||
}
|
||||
|
||||
for (auto& m : m_vMonitors) {
|
||||
m_vLayerSurfaces.emplace_back(std::make_unique<CLayerSurface>(m.get()));
|
||||
|
||||
|
@ -121,6 +135,8 @@ void CHyprpicker::finish(int code) {
|
|||
m_pSeat.reset();
|
||||
m_pKeyboard.reset();
|
||||
m_pPointer.reset();
|
||||
m_pViewporter.reset();
|
||||
m_pFractionalMgr.reset();
|
||||
|
||||
wl_display_disconnect(m_pWLDisplay);
|
||||
m_pWLDisplay = nullptr;
|
||||
|
@ -135,9 +151,11 @@ void CHyprpicker::recheckACK() {
|
|||
ls->wantsACK = false;
|
||||
ls->pLayerSurface->sendAckConfigure(ls->ACKSerial);
|
||||
|
||||
if (!ls->buffers[0] || ls->buffers[0]->pixelSize != ls->m_pMonitor->size * ls->m_pMonitor->scale) {
|
||||
ls->buffers[0] = makeShared<SPoolBuffer>(ls->m_pMonitor->size * ls->m_pMonitor->scale, WL_SHM_FORMAT_ARGB8888, ls->m_pMonitor->size.x * ls->m_pMonitor->scale * 4);
|
||||
ls->buffers[1] = makeShared<SPoolBuffer>(ls->m_pMonitor->size * ls->m_pMonitor->scale, WL_SHM_FORMAT_ARGB8888, ls->m_pMonitor->size.x * ls->m_pMonitor->scale * 4);
|
||||
const auto MONITORSIZE = ls->screenBuffer && !g_pHyprpicker->m_bNoFractional ? ls->screenBuffer->pixelSize : ls->m_pMonitor->size * ls->m_pMonitor->scale;
|
||||
|
||||
if (!ls->buffers[0] || ls->buffers[0]->pixelSize != MONITORSIZE) {
|
||||
ls->buffers[0] = makeShared<SPoolBuffer>(MONITORSIZE, WL_SHM_FORMAT_ARGB8888, MONITORSIZE.x * 4);
|
||||
ls->buffers[1] = makeShared<SPoolBuffer>(MONITORSIZE, WL_SHM_FORMAT_ARGB8888, MONITORSIZE.x * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,8 +341,8 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
|
|||
return;
|
||||
}
|
||||
|
||||
PBUFFER->surface = cairo_image_surface_create_for_data((unsigned char*)PBUFFER->data, CAIRO_FORMAT_ARGB32, pSurface->m_pMonitor->size.x * pSurface->m_pMonitor->scale,
|
||||
pSurface->m_pMonitor->size.y * pSurface->m_pMonitor->scale, PBUFFER->pixelSize.x * 4);
|
||||
PBUFFER->surface =
|
||||
cairo_image_surface_create_for_data((unsigned char*)PBUFFER->data, CAIRO_FORMAT_ARGB32, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y, PBUFFER->pixelSize.x * 4);
|
||||
|
||||
PBUFFER->cairo = cairo_create(PBUFFER->surface);
|
||||
|
||||
|
@ -334,15 +352,13 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
|
|||
|
||||
cairo_set_source_rgba(PCAIRO, 0, 0, 0, 0);
|
||||
|
||||
cairo_rectangle(PCAIRO, 0, 0, pSurface->m_pMonitor->size.x * pSurface->m_pMonitor->scale, pSurface->m_pMonitor->size.y * pSurface->m_pMonitor->scale);
|
||||
cairo_rectangle(PCAIRO, 0, 0, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y);
|
||||
cairo_fill(PCAIRO);
|
||||
|
||||
if (pSurface == g_pHyprpicker->m_pLastSurface && !forceInactive) {
|
||||
const auto SCALEBUFS = pSurface->screenBuffer->pixelSize / PBUFFER->pixelSize;
|
||||
const auto SCALECURSOR = Vector2D{
|
||||
g_pHyprpicker->m_pLastSurface->screenBuffer->pixelSize.x / (g_pHyprpicker->m_pLastSurface->buffers[0]->pixelSize.x / g_pHyprpicker->m_pLastSurface->m_pMonitor->scale),
|
||||
g_pHyprpicker->m_pLastSurface->screenBuffer->pixelSize.y / (g_pHyprpicker->m_pLastSurface->buffers[0]->pixelSize.y / g_pHyprpicker->m_pLastSurface->m_pMonitor->scale)};
|
||||
const auto CLICKPOS = Vector2D{g_pHyprpicker->m_vLastCoords.floor().x * SCALECURSOR.x, g_pHyprpicker->m_vLastCoords.floor().y * SCALECURSOR.y};
|
||||
if (pSurface == m_pLastSurface && !forceInactive) {
|
||||
const auto SCALEBUFS = pSurface->screenBuffer->pixelSize / PBUFFER->pixelSize;
|
||||
const auto MOUSECOORDSABS = m_vLastCoords.floor() / pSurface->m_pMonitor->size;
|
||||
const auto CLICKPOS = MOUSECOORDSABS * PBUFFER->pixelSize;
|
||||
|
||||
const auto PATTERNPRE = cairo_pattern_create_for_surface(pSurface->screenBuffer->surface);
|
||||
cairo_pattern_set_filter(PATTERNPRE, CAIRO_FILTER_BILINEAR);
|
||||
|
@ -368,15 +384,17 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
|
|||
//
|
||||
|
||||
cairo_restore(PCAIRO);
|
||||
if (!g_pHyprpicker->m_bNoZoom) {
|
||||
if (!m_bNoZoom) {
|
||||
cairo_save(PCAIRO);
|
||||
|
||||
const auto PIXCOLOR = getColorFromPixel(pSurface, CLICKPOS);
|
||||
const auto CLICKPOSBUF = CLICKPOS / PBUFFER->pixelSize * pSurface->screenBuffer->pixelSize;
|
||||
|
||||
const auto PIXCOLOR = getColorFromPixel(pSurface, CLICKPOSBUF);
|
||||
cairo_set_source_rgba(PCAIRO, PIXCOLOR.r / 255.f, PIXCOLOR.g / 255.f, PIXCOLOR.b / 255.f, PIXCOLOR.a / 255.f);
|
||||
|
||||
cairo_scale(PCAIRO, 1, 1);
|
||||
|
||||
cairo_arc(PCAIRO, m_vLastCoords.x * pSurface->m_pMonitor->scale, m_vLastCoords.y * pSurface->m_pMonitor->scale, 105 / SCALEBUFS.x, 0, 2 * M_PI);
|
||||
cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, 105 / SCALEBUFS.x, 0, 2 * M_PI);
|
||||
cairo_clip(PCAIRO);
|
||||
|
||||
cairo_fill(PCAIRO);
|
||||
|
@ -391,12 +409,12 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
|
|||
cairo_pattern_set_filter(PATTERN, CAIRO_FILTER_NEAREST);
|
||||
cairo_matrix_t matrix;
|
||||
cairo_matrix_init_identity(&matrix);
|
||||
cairo_matrix_translate(&matrix, CLICKPOS.x + 0.5f, CLICKPOS.y + 0.5f);
|
||||
cairo_matrix_translate(&matrix, CLICKPOSBUF.x + 0.5f, CLICKPOSBUF.y + 0.5f);
|
||||
cairo_matrix_scale(&matrix, 0.1f, 0.1f);
|
||||
cairo_matrix_translate(&matrix, -CLICKPOS.x / SCALEBUFS.x - 0.5f, -CLICKPOS.y / SCALEBUFS.y - 0.5f);
|
||||
cairo_matrix_translate(&matrix, -CLICKPOSBUF.x / SCALEBUFS.x - 0.5f, -CLICKPOSBUF.y / SCALEBUFS.y - 0.5f);
|
||||
cairo_pattern_set_matrix(PATTERN, &matrix);
|
||||
cairo_set_source(PCAIRO, PATTERN);
|
||||
cairo_arc(PCAIRO, m_vLastCoords.x * pSurface->m_pMonitor->scale, m_vLastCoords.y * pSurface->m_pMonitor->scale, 100 / SCALEBUFS.x, 0, 2 * M_PI);
|
||||
cairo_arc(PCAIRO, CLICKPOS.x, CLICKPOS.y, 100 / SCALEBUFS.x, 0, 2 * M_PI);
|
||||
cairo_clip(PCAIRO);
|
||||
cairo_paint(PCAIRO);
|
||||
|
||||
|
@ -406,10 +424,10 @@ void CHyprpicker::renderSurface(CLayerSurface* pSurface, bool forceInactive) {
|
|||
|
||||
cairo_pattern_destroy(PATTERN);
|
||||
}
|
||||
} else if (!g_pHyprpicker->m_bRenderInactive) {
|
||||
} else if (!m_bRenderInactive) {
|
||||
cairo_set_operator(PCAIRO, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_rgba(PCAIRO, 0, 0, 0, 0);
|
||||
cairo_rectangle(PCAIRO, 0, 0, pSurface->m_pMonitor->size.x * pSurface->m_pMonitor->scale, pSurface->m_pMonitor->size.y * pSurface->m_pMonitor->scale);
|
||||
cairo_rectangle(PCAIRO, 0, 0, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y);
|
||||
cairo_fill(PCAIRO);
|
||||
} else {
|
||||
const auto SCALEBUFS = pSurface->screenBuffer->pixelSize / PBUFFER->pixelSize;
|
||||
|
@ -537,10 +555,8 @@ void CHyprpicker::initMouse() {
|
|||
const auto FLUMI = [](const float& c) -> float { return c <= 0.03928 ? c / 12.92 : powf((c + 0.055) / 1.055, 2.4); };
|
||||
|
||||
// get the px and print it
|
||||
const auto SCALE = Vector2D{m_pLastSurface->screenBuffer->pixelSize.x / (m_pLastSurface->buffers[0]->pixelSize.x / m_pLastSurface->m_pMonitor->scale),
|
||||
m_pLastSurface->screenBuffer->pixelSize.y / (m_pLastSurface->buffers[0]->pixelSize.y / m_pLastSurface->m_pMonitor->scale)};
|
||||
|
||||
const auto CLICKPOS = m_vLastCoords.floor() * SCALE;
|
||||
const auto MOUSECOORDSABS = m_vLastCoords.floor() / m_pLastSurface->m_pMonitor->size;
|
||||
const auto CLICKPOS = MOUSECOORDSABS * m_pLastSurface->screenBuffer->pixelSize;
|
||||
|
||||
const auto COL = getColorFromPixel(m_pLastSurface, CLICKPOS);
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ class CHyprpicker {
|
|||
SP<CCWlSeat> m_pSeat;
|
||||
SP<CCWlKeyboard> m_pKeyboard;
|
||||
SP<CCWlPointer> m_pPointer;
|
||||
SP<CCWpFractionalScaleManagerV1> m_pFractionalMgr;
|
||||
SP<CCWpViewporter> m_pViewporter;
|
||||
wl_display* m_pWLDisplay = nullptr;
|
||||
|
||||
xkb_context* m_pXKBContext = nullptr;
|
||||
|
@ -41,6 +43,7 @@ class CHyprpicker {
|
|||
bool m_bAutoCopy = false;
|
||||
bool m_bRenderInactive = false;
|
||||
bool m_bNoZoom = false;
|
||||
bool m_bNoFractional = false;
|
||||
|
||||
bool m_bRunning = true;
|
||||
|
||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -11,7 +11,10 @@ static void help(void) {
|
|||
<< " -n | --no-fancy | Disables the \"fancy\" (aka. colored) outputting\n"
|
||||
<< " -h | --help | Show this help message\n"
|
||||
<< " -r | --render-inactive | Render (freeze) inactive displays\n"
|
||||
<< " -z | --no-zoom | Disable the zoom lens\n";
|
||||
<< " -z | --no-zoom | Disable the zoom lens\n"
|
||||
<< " -q | --quiet | Disable most logs (leaves errors)\n"
|
||||
<< " -v | --verbose | Enable more logs\n"
|
||||
<< " -t | --no-fractional | Disable fractional scaling support\n";
|
||||
}
|
||||
|
||||
int main(int argc, char** argv, char** envp) {
|
||||
|
@ -25,9 +28,12 @@ int main(int argc, char** argv, char** envp) {
|
|||
{"no-fancy", no_argument, NULL, 'n'},
|
||||
{"render-inactive", no_argument, NULL, 'r'},
|
||||
{"no-zoom", no_argument, NULL, 'z'},
|
||||
{"no-fractional", no_argument, NULL, 't'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{NULL, 0, NULL, 0}};
|
||||
|
||||
int c = getopt_long(argc, argv, ":f:hnarz", long_options, &option_index);
|
||||
int c = getopt_long(argc, argv, ":f:hnarzqvt", long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
|
@ -53,6 +59,9 @@ int main(int argc, char** argv, char** envp) {
|
|||
case 'a': g_pHyprpicker->m_bAutoCopy = true; break;
|
||||
case 'r': g_pHyprpicker->m_bRenderInactive = true; break;
|
||||
case 'z': g_pHyprpicker->m_bNoZoom = true; break;
|
||||
case 't': g_pHyprpicker->m_bNoFractional = true; break;
|
||||
case 'q': Debug::quiet = true; break;
|
||||
case 'v': Debug::verbose = true; break;
|
||||
|
||||
default: help(); exit(1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue