Implement rendering of titles in CSD
This commit is contained in:
2
glfw/glfw3.h
vendored
2
glfw/glfw3.h
vendored
@@ -1683,7 +1683,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
|||||||
|
|
||||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||||
typedef void (* GLFWtickcallback)(void*);
|
typedef void (* GLFWtickcallback)(void*);
|
||||||
typedef void (* GLFWdrawtextfun)(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||||
|
|
||||||
/*! @brief Video mode type.
|
/*! @brief Video mode type.
|
||||||
*
|
*
|
||||||
|
|||||||
3
glfw/wl_client_side_decorations.c
vendored
3
glfw/wl_client_side_decorations.c
vendored
@@ -50,6 +50,9 @@ alloc_buffer_pair(_GLFWWaylandBufferPair *pair, struct wl_shm_pool *pool, uint8_
|
|||||||
static void
|
static void
|
||||||
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
render_title_bar(_GLFWwindow *window, bool to_front_buffer) {
|
||||||
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
|
uint8_t *output = to_front_buffer ? decs.top.buffer.data.front : decs.top.buffer.data.back;
|
||||||
|
if (window->wl.title && window->wl.title[0] && _glfw.callbacks.draw_text) {
|
||||||
|
if (_glfw.callbacks.draw_text((GLFWwindow*)window, window->wl.title, 0, bg_color, output, decs.top.buffer.width, decs.top.buffer.height, 10, 0)) return;
|
||||||
|
}
|
||||||
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) {
|
for (uint32_t *px = (uint32_t*)output, *end = (uint32_t*)(output + decs.top.buffer.size_in_bytes); px < end; px++) {
|
||||||
*px = bg_color;
|
*px = bg_color;
|
||||||
}
|
}
|
||||||
|
|||||||
5
glfw/wl_window.c
vendored
5
glfw/wl_window.c
vendored
@@ -817,7 +817,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
{
|
{
|
||||||
if (window->wl.title) free(window->wl.title);
|
if (window->wl.title) {
|
||||||
|
if (title && strcmp(title, window->wl.title) == 0) return;
|
||||||
|
free(window->wl.title);
|
||||||
|
} else if (!title) return;
|
||||||
// Wayland cannot handle requests larger than ~8200 bytes. Sending
|
// Wayland cannot handle requests larger than ~8200 bytes. Sending
|
||||||
// one causes an abort(). Since titles this large are meaningless anyway
|
// one causes an abort(). Since titles this large are meaningless anyway
|
||||||
// ensure they do not happen.
|
// ensure they do not happen.
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ load_font(FontConfigFace *info, Face *ans) {
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
ensure_state(void) {
|
ensure_state(void) {
|
||||||
if (main_face.freetype && main_face.hb) return false;
|
if (main_face.freetype && main_face.hb) return true;
|
||||||
if (!information_for_font_family(main_face_family.name, main_face_family.bold, main_face_family.italic, &main_face_information)) return false;
|
if (!information_for_font_family(main_face_family.name, main_face_family.bold, main_face_family.italic, &main_face_information)) return false;
|
||||||
if (!load_font(&main_face_information, &main_face)) return false;
|
if (!load_font(&main_face_information, &main_face)) return false;
|
||||||
hb_buffer = hb_buffer_create();
|
hb_buffer = hb_buffer_create();
|
||||||
@@ -147,6 +147,7 @@ typedef struct RenderState {
|
|||||||
Face *current_face;
|
Face *current_face;
|
||||||
float x, y;
|
float x, y;
|
||||||
Region src, dest;
|
Region src, dest;
|
||||||
|
unsigned sz_px;
|
||||||
} RenderState;
|
} RenderState;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -227,7 +228,7 @@ render_run(RenderState *rs) {
|
|||||||
}
|
}
|
||||||
FT_Face face = rs->current_face->freetype;
|
FT_Face face = rs->current_face->freetype;
|
||||||
bool has_color = FT_HAS_COLOR(face);
|
bool has_color = FT_HAS_COLOR(face);
|
||||||
FT_UInt pixel_size = 3 * rs->output_height / 4;
|
FT_UInt pixel_size = rs->sz_px;
|
||||||
set_pixel_size(rs->current_face, pixel_size, has_color);
|
set_pixel_size(rs->current_face, pixel_size, has_color);
|
||||||
hb_shape(rs->current_face->hb, hb_buffer, NULL, 0);
|
hb_shape(rs->current_face->hb, hb_buffer, NULL, 0);
|
||||||
unsigned int len = hb_buffer_get_length(hb_buffer);
|
unsigned int len = hb_buffer_get_length(hb_buffer);
|
||||||
@@ -327,7 +328,7 @@ process_codepoint(RenderState *rs, char_type codep, char_type next_codep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
render_single_line(const char *text, pixel fg, pixel bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
render_single_line(const char *text, unsigned sz_px, pixel fg, pixel bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
||||||
if (!ensure_state()) return false;
|
if (!ensure_state()) return false;
|
||||||
bool has_text = text && text[0];
|
bool has_text = text && text[0];
|
||||||
pixel pbg = premult_pixel(bg, ((bg >> 24) & 0xff));
|
pixel pbg = premult_pixel(bg, ((bg >> 24) & 0xff));
|
||||||
@@ -343,7 +344,7 @@ render_single_line(const char *text, pixel fg, pixel bg, uint8_t *output_buf, si
|
|||||||
text_len = decode_utf8_string(text, text_len, unicode);
|
text_len = decode_utf8_string(text, text_len, unicode);
|
||||||
RenderState rs = {
|
RenderState rs = {
|
||||||
.current_face = &main_face, .fg = fg, .bg = bg, .output_width = width, .output_height = height,
|
.current_face = &main_face, .fg = fg, .bg = bg, .output_width = width, .output_height = height,
|
||||||
.output = (pixel*)output_buf, .x = x_offset, .y = y_offset
|
.output = (pixel*)output_buf, .x = x_offset, .y = y_offset, .sz_px = sz_px
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < text_len && rs.x < rs.output_width; i++) {
|
for (size_t i = 0; i < text_len && rs.x < rs.output_width; i++) {
|
||||||
@@ -376,7 +377,7 @@ render_line(PyObject *self UNUSED, PyObject *args, PyObject *kw) {
|
|||||||
PyObject *ans = PyBytes_FromStringAndSize(NULL, width * height * 4);
|
PyObject *ans = PyBytes_FromStringAndSize(NULL, width * height * 4);
|
||||||
if (!ans) return NULL;
|
if (!ans) return NULL;
|
||||||
uint8_t *buffer = (u_int8_t*) PyBytes_AS_STRING(ans);
|
uint8_t *buffer = (u_int8_t*) PyBytes_AS_STRING(ans);
|
||||||
if (!render_single_line(text, 0, 0xffffffff, buffer, width, height, x_offset, y_offset)) {
|
if (!render_single_line(text, 3 * height / 4, 0, 0xffffffff, buffer, width, height, x_offset, y_offset)) {
|
||||||
Py_CLEAR(ans);
|
Py_CLEAR(ans);
|
||||||
if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "Unknown error while rendering text");
|
if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "Unknown error while rendering text");
|
||||||
ans = NULL;
|
ans = NULL;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
#include <hb-ft.h>
|
#include <hb-ft.h>
|
||||||
|
|
||||||
bool render_single_line(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
bool render_single_line(const char *text, unsigned sz_px, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||||
|
|
||||||
typedef struct FontConfigFace {
|
typedef struct FontConfigFace {
|
||||||
char *path;
|
char *path;
|
||||||
|
|||||||
2
kitty/glfw-wrapper.h
generated
2
kitty/glfw-wrapper.h
generated
@@ -1421,7 +1421,7 @@ typedef void (* GLFWjoystickfun)(int,int);
|
|||||||
|
|
||||||
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
typedef void (* GLFWuserdatafun)(unsigned long long, void*);
|
||||||
typedef void (* GLFWtickcallback)(void*);
|
typedef void (* GLFWtickcallback)(void*);
|
||||||
typedef void (* GLFWdrawtextfun)(const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
typedef bool (* GLFWdrawtextfun)(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset);
|
||||||
|
|
||||||
/*! @brief Video mode type.
|
/*! @brief Video mode type.
|
||||||
*
|
*
|
||||||
|
|||||||
18
kitty/glfw.c
18
kitty/glfw.c
@@ -10,6 +10,9 @@
|
|||||||
#include "charsets.h"
|
#include "charsets.h"
|
||||||
#include <structmember.h>
|
#include <structmember.h>
|
||||||
#include "glfw-wrapper.h"
|
#include "glfw-wrapper.h"
|
||||||
|
#ifndef __APPLE__
|
||||||
|
#include "freetype_render_ui_text.h"
|
||||||
|
#endif
|
||||||
extern bool cocoa_make_window_resizable(void *w, bool);
|
extern bool cocoa_make_window_resizable(void *w, bool);
|
||||||
extern void cocoa_focus_window(void *w);
|
extern void cocoa_focus_window(void *w);
|
||||||
extern long cocoa_window_number(void *w);
|
extern long cocoa_window_number(void *w);
|
||||||
@@ -381,12 +384,25 @@ application_close_requested_callback(int flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void get_window_dpi(GLFWwindow *w, double *x, double *y);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static bool
|
static bool
|
||||||
apple_file_open_callback(const char* filepath) {
|
apple_file_open_callback(const char* filepath) {
|
||||||
set_cocoa_pending_action(OPEN_FILE, filepath);
|
set_cocoa_pending_action(OPEN_FILE, filepath);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
static bool
|
||||||
|
draw_text_callback(GLFWwindow *window, const char *text, uint32_t fg, uint32_t bg, uint8_t *output_buf, size_t width, size_t height, float x_offset, float y_offset) {
|
||||||
|
if (!set_callback_window(window)) return false;
|
||||||
|
double xdpi, ydpi;
|
||||||
|
get_window_dpi(window, &xdpi, &ydpi);
|
||||||
|
unsigned px_sz = (unsigned)(global_state.callback_os_window->font_sz_in_pts * ydpi / 72.);
|
||||||
|
px_sz = MIN(px_sz, 3 * height / 4);
|
||||||
|
return render_single_line(text, px_sz, fg, bg, output_buf, width, height, x_offset, y_offset);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
@@ -855,6 +871,8 @@ glfw_init(PyObject UNUSED *self, PyObject *args) {
|
|||||||
if (ans == Py_True) {
|
if (ans == Py_True) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
glfwSetCocoaFileOpenCallback(apple_file_open_callback);
|
glfwSetCocoaFileOpenCallback(apple_file_open_callback);
|
||||||
|
#else
|
||||||
|
glfwSetDrawTextFunction(draw_text_callback);
|
||||||
#endif
|
#endif
|
||||||
OSWindow w = {0};
|
OSWindow w = {0};
|
||||||
set_os_window_dpi(&w);
|
set_os_window_dpi(&w);
|
||||||
|
|||||||
Reference in New Issue
Block a user