[digesting_libdecor] extract redraw logic from each event path and just run once per frame (this introduces a bug with the title bar button highlights, will have to fix after simplifications are finished, not clear how to avoid incrementally)
parent
107aa41329
commit
59031ef536
|
|
@ -345,6 +345,8 @@ const struct zxdg_toplevel_decoration_v1_listener
|
|||
xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure, };
|
||||
|
||||
static GtkWidget* find_widget_by_type(GtkWidget *root, enum header_element type);
|
||||
static void ensure_title_bar_surfaces(void);
|
||||
static void ensure_component(struct border_component *cmpnt);
|
||||
|
||||
int main(){
|
||||
/* get desktop settings */
|
||||
|
|
@ -650,7 +652,17 @@ int main(){
|
|||
}
|
||||
|
||||
/* re-render cursor */
|
||||
ctx.seat->current_cursor = wl_cursor_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
|
||||
{
|
||||
struct wl_cursor *cursor = ctx.cursor_left_ptr;
|
||||
if (ctx.active == COMPONENT_SLOT_SHADOW &&
|
||||
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||
enum libdecor_resize_edge edge = edge_from_pos(ctx.seat->pointer_x, ctx.seat->pointer_y);
|
||||
if (edge != LIBDECOR_RESIZE_EDGE_NONE){
|
||||
cursor = ctx.cursors[edge - 1];
|
||||
}
|
||||
}
|
||||
ctx.seat->current_cursor = cursor;
|
||||
}
|
||||
if (ctx.seat->current_cursor != 0){
|
||||
struct wl_cursor_image *image = ctx.seat->current_cursor->images[0];
|
||||
struct wl_buffer *buffer = wl_cursor_image_get_buffer(image);
|
||||
|
|
@ -667,16 +679,10 @@ int main(){
|
|||
ctx.titlebar_gesture.first_pressed_button = 0;
|
||||
ctx.hdr_focus.widget = 0;
|
||||
ctx.hdr_focus.type = HEADER_NONE;
|
||||
draw_decoration();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
}
|
||||
|
||||
if (ctx.pointer_enter){
|
||||
ctx.pointer_enter = 0;
|
||||
if (ctx.active != 0){
|
||||
draw_decoration();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.pointer_motion){
|
||||
|
|
@ -720,9 +726,6 @@ int main(){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_title_bar();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
}
|
||||
|
||||
if (ctx.pointer_button){
|
||||
|
|
@ -757,8 +760,7 @@ int main(){
|
|||
xdg_toplevel_show_window_menu(ctx.xdg_toplevel, ctx.seat->wl_seat, ctx.seat->serial, ctx.seat->pointer_x, -title_height);
|
||||
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_CONSUMED;
|
||||
}
|
||||
else{
|
||||
if (ctx.pointer_button_button == BTN_LEFT &&
|
||||
else if (ctx.pointer_button_button == BTN_LEFT &&
|
||||
ctx.titlebar_gesture.first_pressed_button == BTN_LEFT &&
|
||||
ctx.pointer_button_time - ctx.titlebar_gesture.first_pressed_time < (uint32_t)ctx.double_click_time_ms){
|
||||
if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||
|
|
@ -774,19 +776,13 @@ int main(){
|
|||
ctx.titlebar_gesture.serial = ctx.seat->serial;
|
||||
ctx.titlebar_gesture.state = TITLEBAR_GESTURE_STATE_BUTTON_PRESSED;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.titlebar_gesture.button_pressed_count = 1;
|
||||
|
||||
switch (ctx.hdr_focus.type){
|
||||
case HEADER_MIN:
|
||||
case HEADER_MAX:
|
||||
case HEADER_CLOSE: {
|
||||
ctx.hdr_focus_is_active = 1;
|
||||
draw_title_bar();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
}break;
|
||||
|
||||
case HEADER_CLOSE: ctx.hdr_focus_is_active = 1; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
@ -833,11 +829,6 @@ int main(){
|
|||
else{
|
||||
ctx.hdr_focus_is_active = 0;
|
||||
}
|
||||
|
||||
if (GTK_IS_WIDGET(ctx.header)) {
|
||||
draw_title_bar();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
|
|
@ -859,13 +850,10 @@ int main(){
|
|||
|
||||
default: break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* apply new surface config */
|
||||
if (ctx.has_cached_config){
|
||||
ctx.has_cached_config = 0;
|
||||
|
||||
if (ctx.cached_config.initialized){
|
||||
ctx.frame_window_state = ctx.cached_config.window_state;
|
||||
}
|
||||
|
|
@ -900,8 +888,13 @@ int main(){
|
|||
ctx.w = w;
|
||||
ctx.h = h;
|
||||
}
|
||||
}
|
||||
|
||||
frame_commit();
|
||||
wl_surface_commit(ctx.wl_surface);
|
||||
|
||||
if (ctx.has_cached_config){
|
||||
ctx.has_cached_config = 0;
|
||||
xdg_surface_ack_configure(ctx.xdg_surface, ctx.cached_config.serial);
|
||||
}
|
||||
|
||||
|
|
@ -978,6 +971,14 @@ decoration_type_from_window_state(enum libdecor_window_state window_state){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
hide_border_component(struct border_component *border_component){
|
||||
if (border_component->wl_surface){
|
||||
wl_surface_attach(border_component->wl_surface, 0, 0, 0);
|
||||
wl_surface_commit(border_component->wl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
frame_commit(void){
|
||||
bool csd = false;
|
||||
|
|
@ -997,12 +998,8 @@ frame_commit(void){
|
|||
}
|
||||
|
||||
else{
|
||||
int csd_added_w = 0;
|
||||
int csd_added_h = 0;
|
||||
if (csd){
|
||||
csd_added_w = border_size.x[0] + border_size.x[1];
|
||||
csd_added_h = border_size.y[0] + border_size.y[1];
|
||||
}
|
||||
int csd_added_w = border_size.x[0] + border_size.x[1];
|
||||
int csd_added_h = border_size.y[0] + border_size.y[1];
|
||||
for (int i = 0; i < 2; i += 1){
|
||||
int mw = 0;
|
||||
int mh = 0;
|
||||
|
|
@ -1021,9 +1018,76 @@ frame_commit(void){
|
|||
|
||||
if (csd){
|
||||
ctx.decoration_type = decoration_type_from_window_state(ctx.frame_window_state);
|
||||
draw_decoration();
|
||||
|
||||
bool shadow = 0;
|
||||
bool title_bar = 0;
|
||||
switch (ctx.decoration_type){
|
||||
case DECORATION_TYPE_NONE: break;
|
||||
case DECORATION_TYPE_ALL: { shadow = 1; title_bar = 1; }break;
|
||||
case DECORATION_TYPE_TITLE_ONLY: { title_bar = 1; }break;
|
||||
}
|
||||
|
||||
if (shadow){
|
||||
ctx.component_slot[COMPONENT_SLOT_SHADOW].opaque = false;
|
||||
ensure_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||
draw_border_component(COMPONENT_SLOT_SHADOW);
|
||||
ctx.shadow_showing = true;
|
||||
}
|
||||
else{
|
||||
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||
ctx.shadow_showing = false;
|
||||
}
|
||||
|
||||
if (title_bar){
|
||||
ensure_title_bar_surfaces();
|
||||
|
||||
enum libdecor_window_state state = ctx.frame_window_state;
|
||||
|
||||
if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
||||
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
||||
}
|
||||
else{
|
||||
gtk_widget_unset_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP);
|
||||
}
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(ctx.window);
|
||||
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_NON_FLOATING)){
|
||||
gtk_style_context_remove_class(style, "maximized");
|
||||
}
|
||||
else{
|
||||
gtk_style_context_add_class(style, "maximized");
|
||||
}
|
||||
gtk_widget_show_all(ctx.window);
|
||||
|
||||
int pref_width;
|
||||
{
|
||||
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), "");
|
||||
gtk_widget_get_preferred_width(ctx.header, NULL, &pref_width);
|
||||
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), ctx.title);
|
||||
}
|
||||
|
||||
ctx.size_bounds.x[0] = CLAMP_BOT(ctx.size_bounds.x[0], pref_width);
|
||||
if (ctx.size_bounds.x[1] != 0){
|
||||
ctx.size_bounds.x[1] = CLAMP_BOT(ctx.size_bounds.x[1], ctx.size_bounds.x[0]);
|
||||
}
|
||||
|
||||
if (ctx.w < ctx.size_bounds.x[0]){
|
||||
ctx.w = ctx.size_bounds.x[0];
|
||||
frame_commit();
|
||||
}
|
||||
else{
|
||||
GtkAllocation allocation = {0, 0, ctx.w, 0};
|
||||
gtk_widget_get_preferred_height(ctx.header, 0, &allocation.height);
|
||||
gtk_widget_size_allocate(ctx.header, &allocation);
|
||||
draw_border_component(COMPONENT_SLOT_HEADER);
|
||||
}
|
||||
}
|
||||
else{
|
||||
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
ctx.decoration_type = DECORATION_TYPE_NONE;
|
||||
|
||||
g_clear_pointer(&ctx.header, gtk_widget_destroy);
|
||||
g_clear_pointer(&ctx.window, gtk_widget_destroy);
|
||||
|
||||
|
|
@ -1031,29 +1095,19 @@ frame_commit(void){
|
|||
struct border_component * border_component = &ctx.component_slot[i];
|
||||
if (border_component->wl_subsurface != 0){
|
||||
wl_subsurface_destroy(border_component->wl_subsurface);
|
||||
border_component->wl_subsurface = 0;
|
||||
}
|
||||
if (border_component->wl_surface != 0){
|
||||
wl_surface_destroy(border_component->wl_surface);
|
||||
border_component->wl_surface = 0;
|
||||
}
|
||||
if (border_component->wl_buffer != 0){
|
||||
wl_buffer_destroy(border_component->wl_buffer);
|
||||
border_component->wl_buffer = 0;
|
||||
}
|
||||
if (border_component->data != 0){
|
||||
munmap(border_component->data, border_component->data_size);
|
||||
border_component->data = 0;
|
||||
}
|
||||
border_component->data_size = 0;
|
||||
border_component->width = 0;
|
||||
border_component->height = 0;
|
||||
}
|
||||
memset(ctx.component_slot, 0, sizeof ctx.component_slot);
|
||||
ctx.shadow_showing = false;
|
||||
|
||||
g_clear_pointer(&ctx.title, free);
|
||||
|
||||
ctx.decoration_type = DECORATION_TYPE_NONE;
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1066,7 +1120,6 @@ frame_commit(void){
|
|||
extent.w += border_size.x[0] + border_size.x[1];
|
||||
extent.h += border_size.y[0] + border_size.y[1];
|
||||
}
|
||||
|
||||
xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h);
|
||||
}
|
||||
}
|
||||
|
|
@ -1459,14 +1512,6 @@ toggle_maximized(void){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hide_border_component(struct border_component *border_component){
|
||||
if (border_component->wl_surface){
|
||||
wl_surface_attach(border_component->wl_surface, 0, 0, 0);
|
||||
wl_surface_commit(border_component->wl_surface);
|
||||
}
|
||||
}
|
||||
|
||||
static enum component_slot
|
||||
component_slot_from_wl_surface(const struct wl_surface *surface){
|
||||
enum component_slot result = 0;
|
||||
|
|
@ -1490,8 +1535,6 @@ ensure_component(struct border_component *cmpnt){
|
|||
|
||||
static void
|
||||
ensure_title_bar_surfaces(void){
|
||||
GtkStyleContext *context_hdr;
|
||||
|
||||
ctx.component_slot[COMPONENT_SLOT_HEADER].opaque = false;
|
||||
ensure_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
||||
|
||||
|
|
@ -1521,7 +1564,7 @@ ensure_title_bar_surfaces(void){
|
|||
"show-close-button", TRUE,
|
||||
NULL);
|
||||
|
||||
context_hdr = gtk_widget_get_style_context(ctx.header);
|
||||
GtkStyleContext *context_hdr = gtk_widget_get_style_context(ctx.header);
|
||||
gtk_style_context_add_class(context_hdr, GTK_STYLE_CLASS_TITLEBAR);
|
||||
gtk_style_context_add_class(context_hdr, "default-decoration");
|
||||
|
||||
|
|
@ -1564,8 +1607,6 @@ extent2d_from_component_slot(enum component_slot slot){
|
|||
static void
|
||||
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
||||
enum header_element button_type){
|
||||
GtkWidget *button;
|
||||
|
||||
GtkAllocation allocation;
|
||||
|
||||
gchar *icon_name;
|
||||
|
|
@ -1574,7 +1615,8 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|||
GtkAllocation allocation_icon;
|
||||
GtkIconInfo* icon_info;
|
||||
|
||||
double sx, sy;
|
||||
double sx;
|
||||
double sy;
|
||||
|
||||
gint icon_width, icon_height;
|
||||
|
||||
|
|
@ -1586,12 +1628,12 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|||
GtkBorder border;
|
||||
GtkBorder padding;
|
||||
|
||||
button = find_widget_by_type(ctx.header, button_type);
|
||||
if (button){
|
||||
GtkWidget *button = find_widget_by_type(ctx.header, button_type);
|
||||
if (button != 0){
|
||||
GtkStyleContext *button_style = gtk_widget_get_style_context(button);
|
||||
GtkStateFlags style_state = 0;
|
||||
|
||||
/* change style based on window state and focus */
|
||||
GtkStateFlags style_state = 0;
|
||||
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
||||
style_state |= GTK_STATE_FLAG_BACKDROP;
|
||||
}
|
||||
|
|
@ -1622,9 +1664,9 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|||
}break;
|
||||
|
||||
case HEADER_MAX:{
|
||||
icon_name = (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ?
|
||||
icon_name = ((ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ?
|
||||
"window-restore-symbolic" :
|
||||
"window-maximize-symbolic";
|
||||
"window-maximize-symbolic");
|
||||
}break;
|
||||
|
||||
case HEADER_CLOSE: {
|
||||
|
|
@ -1638,7 +1680,7 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|||
|
||||
/* get scale */
|
||||
cairo_surface_get_device_scale(surface, &sx, &sy);
|
||||
scale = (sx+sy) / 2.0;
|
||||
scale = (sx+sy)/2.0;
|
||||
|
||||
/* get original icon dimensions */
|
||||
icon_widget = gtk_bin_get_child(GTK_BIN(button));
|
||||
|
|
@ -1655,14 +1697,14 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|||
/* icon pixel buffer*/
|
||||
gtk_style_context_save(button_style);
|
||||
gtk_style_context_set_state(button_style, style_state);
|
||||
icon_pixbuf = gtk_icon_info_load_symbolic_for_context(
|
||||
icon_info, button_style, NULL, NULL);
|
||||
icon_pixbuf = gtk_icon_info_load_symbolic_for_context(icon_info, button_style, 0, 0);
|
||||
icon_surface = gdk_cairo_surface_create_from_pixbuf(icon_pixbuf, scale, NULL);
|
||||
gtk_style_context_restore(button_style);
|
||||
|
||||
/* dimensions and position */
|
||||
gtk_style_context_get(button_style, gtk_style_context_get_state(button_style),
|
||||
"min-width", &width, "min-height", &height, NULL);
|
||||
"min-width", &width,
|
||||
"min-height", &height, NULL);
|
||||
|
||||
if (width < icon_width){
|
||||
width = icon_width;
|
||||
|
|
@ -1842,76 +1884,6 @@ draw_border_component(enum component_slot slot){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_title_bar(void){
|
||||
enum libdecor_window_state state = ctx.frame_window_state;
|
||||
|
||||
if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
||||
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
||||
}
|
||||
else{
|
||||
gtk_widget_unset_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP);
|
||||
}
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(ctx.window);
|
||||
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_NON_FLOATING)){
|
||||
gtk_style_context_remove_class(style, "maximized");
|
||||
}
|
||||
else{
|
||||
gtk_style_context_add_class(style, "maximized");
|
||||
}
|
||||
gtk_widget_show_all(ctx.window);
|
||||
|
||||
int pref_width;
|
||||
{
|
||||
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), "");
|
||||
gtk_widget_get_preferred_width(ctx.header, NULL, &pref_width);
|
||||
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), ctx.title);
|
||||
}
|
||||
|
||||
ctx.size_bounds.x[0] = CLAMP_BOT(ctx.size_bounds.x[0], pref_width);
|
||||
if (ctx.size_bounds.x[1] != 0){
|
||||
ctx.size_bounds.x[1] = CLAMP_BOT(ctx.size_bounds.x[1], ctx.size_bounds.x[0]);
|
||||
}
|
||||
|
||||
if (ctx.w < ctx.size_bounds.x[0]){
|
||||
ctx.w = ctx.size_bounds.x[0];
|
||||
frame_commit();
|
||||
}
|
||||
else{
|
||||
GtkAllocation allocation = {0, 0, ctx.w, 0};
|
||||
gtk_widget_get_preferred_height(ctx.header, 0, &allocation.height);
|
||||
gtk_widget_size_allocate(ctx.header, &allocation);
|
||||
draw_border_component(COMPONENT_SLOT_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_decoration(void){
|
||||
switch (ctx.decoration_type){
|
||||
case DECORATION_TYPE_NONE: {
|
||||
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||
ctx.shadow_showing = false;
|
||||
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
||||
}break;
|
||||
|
||||
case DECORATION_TYPE_ALL: {
|
||||
ctx.component_slot[COMPONENT_SLOT_SHADOW].opaque = false;
|
||||
ensure_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||
draw_border_component(COMPONENT_SLOT_SHADOW);
|
||||
ctx.shadow_showing = true;
|
||||
ensure_title_bar_surfaces();
|
||||
draw_title_bar();
|
||||
}break;
|
||||
|
||||
case DECORATION_TYPE_TITLE_ONLY: {
|
||||
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
||||
ctx.shadow_showing = false;
|
||||
ensure_title_bar_surfaces();
|
||||
draw_title_bar();
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
static Sides2D
|
||||
border_size_from_window_state(enum libdecor_window_state window_state){
|
||||
Sides2D border_size = {0};
|
||||
|
|
@ -1960,19 +1932,6 @@ edge_from_pos(int x, int y){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static struct wl_cursor *
|
||||
wl_cursor_from_pos(int x, int y){
|
||||
struct wl_cursor *result = ctx.cursor_left_ptr;
|
||||
if (ctx.active == COMPONENT_SLOT_SHADOW &&
|
||||
(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||
enum libdecor_resize_edge edge = edge_from_pos(x, y);
|
||||
if (edge != LIBDECOR_RESIZE_EDGE_NONE){
|
||||
result = ctx.cursors[edge - 1];
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
//#include "desktop-settings.c"
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -270,7 +270,6 @@ static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
|
|||
static Sides2D border_size_from_window_state(enum libdecor_window_state window_state);
|
||||
|
||||
static struct wl_cursor* wl_cursor_from_pos(int x, int y);
|
||||
static void draw_decoration(void);
|
||||
static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type);
|
||||
static void draw_border_component(enum component_slot slot);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue