|
|
|
@ -99,7 +99,14 @@ pointer_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
|
|
|
seat->pointer_y = wl_fixed_to_int(y);
|
|
|
|
seat->pointer_y = wl_fixed_to_int(y);
|
|
|
|
seat->serial = serial;
|
|
|
|
seat->serial = serial;
|
|
|
|
seat->pointer_focus = surface;
|
|
|
|
seat->pointer_focus = surface;
|
|
|
|
ctx.active = component_slot_from_wl_surface(surface);
|
|
|
|
|
|
|
|
|
|
|
|
ctx.active = 0;
|
|
|
|
|
|
|
|
for (int i = 1; i < COMPONENT_SLOT_COUNT; i += 1){
|
|
|
|
|
|
|
|
if (ctx.component_slot[i].wl_surface == surface){
|
|
|
|
|
|
|
|
ctx.active = i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
ctx.pointer_enter = 1;
|
|
|
|
ctx.pointer_enter = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -171,7 +178,7 @@ const struct wl_seat_listener seat_listener = {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
wl_registry_global(void *data, struct wl_registry *wl_registry,
|
|
|
|
registry_global(void *data, struct wl_registry *wl_registry,
|
|
|
|
uint32_t name, const char *interface,
|
|
|
|
uint32_t name, const char *interface,
|
|
|
|
uint32_t version){
|
|
|
|
uint32_t version){
|
|
|
|
if (strcmp(interface, "wl_compositor") == 0){
|
|
|
|
if (strcmp(interface, "wl_compositor") == 0){
|
|
|
|
@ -225,23 +232,22 @@ wl_registry_global(void *data, struct wl_registry *wl_registry,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
wl_registry_global_remove(void *data, struct wl_registry *registry,
|
|
|
|
registry_global_remove(void *data, struct wl_registry *registry,
|
|
|
|
uint32_t name){}
|
|
|
|
uint32_t name){}
|
|
|
|
|
|
|
|
|
|
|
|
const struct wl_registry_listener wl_registry_listener = {
|
|
|
|
const struct wl_registry_listener registry_listener = {
|
|
|
|
wl_registry_global,
|
|
|
|
registry_global,
|
|
|
|
wl_registry_global_remove,
|
|
|
|
registry_global_remove,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
xdg_surface_configure(void *user_data, struct xdg_surface *xdg_surface, uint32_t serial){
|
|
|
|
xdg_surface_configure(void *user_data, struct xdg_surface *xdg_surface,
|
|
|
|
|
|
|
|
uint32_t serial){
|
|
|
|
ctx.has_cached_config = 1;
|
|
|
|
ctx.has_cached_config = 1;
|
|
|
|
ctx.cached_config.serial = serial;
|
|
|
|
ctx.cached_config.serial = serial;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const struct xdg_surface_listener xdg_surface_listener = {
|
|
|
|
const struct xdg_surface_listener xdg_surface_listener = { xdg_surface_configure, };
|
|
|
|
xdg_surface_configure,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel,
|
|
|
|
xdg_toplevel_configure(void *user_data, struct xdg_toplevel *xdg_toplevel,
|
|
|
|
@ -336,15 +342,47 @@ xdg_toplevel_decoration_configure(void *data, struct zxdg_toplevel_decoration_v1
|
|
|
|
const struct zxdg_toplevel_decoration_v1_listener
|
|
|
|
const struct zxdg_toplevel_decoration_v1_listener
|
|
|
|
xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure };
|
|
|
|
xdg_toplevel_decoration_listener = { xdg_toplevel_decoration_configure };
|
|
|
|
|
|
|
|
|
|
|
|
static GtkWidget* find_widget_by_type(GtkWidget *root, enum header_element type);
|
|
|
|
|
|
|
|
static void ensure_component(struct border_component *cmpnt);
|
|
|
|
|
|
|
|
|
|
|
|
struct find_widget_variables{
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
GtkWidget *widget;
|
|
|
|
|
|
|
|
} find_widget_variables;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
hide_border_component(struct border_component *border_component){
|
|
|
|
fill_widget_from_name(GtkWidget *widget, void *data){
|
|
|
|
if (border_component->wl_surface != 0){
|
|
|
|
struct find_widget_variables *vars = data;
|
|
|
|
wl_surface_attach(border_component->wl_surface, 0, 0, 0);
|
|
|
|
if (vars->widget == 0){
|
|
|
|
wl_surface_commit(border_component->wl_surface);
|
|
|
|
bool match = false;
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(widget)){
|
|
|
|
|
|
|
|
GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
|
|
|
|
|
|
|
|
char *style_str = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
|
|
|
|
|
|
|
|
if (strstr(style_str, vars->name) != 0){
|
|
|
|
|
|
|
|
vars->widget = widget;
|
|
|
|
|
|
|
|
match = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(style_str);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!match && GTK_IS_CONTAINER(widget)){
|
|
|
|
|
|
|
|
gtk_container_forall(GTK_CONTAINER(widget), &fill_widget_from_name, data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static GtkWidget*
|
|
|
|
|
|
|
|
find_widget_by_type(GtkWidget *root, enum header_element type){
|
|
|
|
|
|
|
|
struct find_widget_variables vars = {0};
|
|
|
|
|
|
|
|
switch (type){
|
|
|
|
|
|
|
|
case HEADER_FULL: vars.name = "headerbar.titlebar:"; break;
|
|
|
|
|
|
|
|
case HEADER_TITLE: vars.name = "label.title:"; break;
|
|
|
|
|
|
|
|
case HEADER_MIN: vars.name = ".minimize"; break;
|
|
|
|
|
|
|
|
case HEADER_MAX: vars.name = ".maximize"; break;
|
|
|
|
|
|
|
|
case HEADER_CLOSE: vars.name = ".close"; break;
|
|
|
|
|
|
|
|
default:break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fill_widget_from_name(root, &vars);
|
|
|
|
|
|
|
|
return(vars.widget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
@ -384,6 +422,7 @@ border_component_reallocate(struct border_component *component, int w, int h){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
int main(){
|
|
|
|
/* get desktop settings */
|
|
|
|
/* get desktop settings */
|
|
|
|
ctx.color_scheme = desktop_settings_get_color_scheme();
|
|
|
|
ctx.color_scheme = desktop_settings_get_color_scheme();
|
|
|
|
@ -433,7 +472,7 @@ int main(){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx.wl_registry != 0){
|
|
|
|
if (ctx.wl_registry != 0){
|
|
|
|
wl_registry_add_listener(ctx.wl_registry, &wl_registry_listener, 0);
|
|
|
|
wl_registry_add_listener(ctx.wl_registry, ®istry_listener, 0);
|
|
|
|
|
|
|
|
|
|
|
|
wl_display_flush(ctx.wl_display);
|
|
|
|
wl_display_flush(ctx.wl_display);
|
|
|
|
wl_display_dispatch(ctx.wl_display);
|
|
|
|
wl_display_dispatch(ctx.wl_display);
|
|
|
|
@ -688,29 +727,6 @@ int main(){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* re-render cursor */
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
wl_surface_set_buffer_scale(ctx.seat->cursor_surface, 1);
|
|
|
|
|
|
|
|
wl_surface_attach(ctx.seat->cursor_surface, buffer, 0, 0);
|
|
|
|
|
|
|
|
wl_surface_damage_buffer(ctx.seat->cursor_surface, 0, 0, image->width, image->height);
|
|
|
|
|
|
|
|
wl_surface_commit(ctx.seat->cursor_surface);
|
|
|
|
|
|
|
|
wl_pointer_set_cursor(ctx.seat->wl_pointer, ctx.seat->serial, ctx.seat->cursor_surface, image->hotspot_x, image->hotspot_y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
#if 1
|
|
|
|
if (ctx.pointer_leave){
|
|
|
|
if (ctx.pointer_leave){
|
|
|
|
ctx.pointer_leave = 0;
|
|
|
|
ctx.pointer_leave = 0;
|
|
|
|
@ -903,26 +919,22 @@ int main(){
|
|
|
|
if (csd && !ctx.csd_active){
|
|
|
|
if (csd && !ctx.csd_active){
|
|
|
|
ctx.csd_active = 1;
|
|
|
|
ctx.csd_active = 1;
|
|
|
|
|
|
|
|
|
|
|
|
ensure_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
|
|
|
for (int slot = 1; slot < COMPONENT_SLOT_COUNT; slot += 1){
|
|
|
|
ensure_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
|
|
|
struct border_component *cmpnt = &ctx.component_slot[slot];
|
|
|
|
|
|
|
|
if (cmpnt->wl_surface == 0){
|
|
|
|
|
|
|
|
cmpnt->wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
|
|
|
|
|
|
|
wl_proxy_set_tag((struct wl_proxy *)cmpnt->wl_surface, &libdecor_gtk_proxy_tag);
|
|
|
|
|
|
|
|
cmpnt->wl_subsurface =
|
|
|
|
|
|
|
|
wl_subcompositor_get_subsurface(ctx.wl_subcompositor,
|
|
|
|
|
|
|
|
cmpnt->wl_surface, ctx.wl_surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface != 0){
|
|
|
|
|
|
|
|
wl_subsurface_place_above(ctx.component_slot[COMPONENT_SLOT_HEADER].wl_subsurface,
|
|
|
|
wl_subsurface_place_above(ctx.component_slot[COMPONENT_SLOT_HEADER].wl_subsurface,
|
|
|
|
ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface);
|
|
|
|
ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(ctx.header)){
|
|
|
|
|
|
|
|
gtk_widget_destroy(ctx.header);
|
|
|
|
|
|
|
|
ctx.header = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(ctx.window)){
|
|
|
|
|
|
|
|
gtk_widget_destroy(ctx.window);
|
|
|
|
|
|
|
|
ctx.window = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctx.window = gtk_offscreen_window_new();
|
|
|
|
|
|
|
|
ctx.header = gtk_header_bar_new();
|
|
|
|
ctx.header = gtk_header_bar_new();
|
|
|
|
|
|
|
|
ctx.window = gtk_offscreen_window_new();
|
|
|
|
|
|
|
|
|
|
|
|
g_object_get(gtk_widget_get_settings(ctx.window),
|
|
|
|
g_object_get(gtk_widget_get_settings(ctx.window),
|
|
|
|
"gtk-double-click-time", &ctx.double_click_time_ms,
|
|
|
|
"gtk-double-click-time", &ctx.double_click_time_ms,
|
|
|
|
@ -940,10 +952,12 @@ int main(){
|
|
|
|
gtk_window_set_titlebar(GTK_WINDOW(ctx.window), ctx.header);
|
|
|
|
gtk_window_set_titlebar(GTK_WINDOW(ctx.window), ctx.header);
|
|
|
|
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(ctx.header), TRUE);
|
|
|
|
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(ctx.header), TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
gtk_window_set_resizable(GTK_WINDOW(ctx.window), (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0);
|
|
|
|
gtk_widget_show_all(ctx.window);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!csd && ctx.csd_active){
|
|
|
|
if (!csd && ctx.csd_active){
|
|
|
|
|
|
|
|
ctx.csd_active = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx.header != 0){
|
|
|
|
if (ctx.header != 0){
|
|
|
|
gtk_widget_destroy(ctx.header);
|
|
|
|
gtk_widget_destroy(ctx.header);
|
|
|
|
ctx.header = 0;
|
|
|
|
ctx.header = 0;
|
|
|
|
@ -977,120 +991,103 @@ int main(){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enum decoration_type decoration_type = DECORATION_TYPE_ALL;
|
|
|
|
|
|
|
|
if (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN){
|
|
|
|
|
|
|
|
decoration_type = DECORATION_TYPE_NONE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (ctx.frame_window_state & (LIBDECOR_WINDOW_STATE_MAXIMIZED |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_LEFT |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_RIGHT |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_TOP |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_BOTTOM)){
|
|
|
|
|
|
|
|
decoration_type = DECORATION_TYPE_TITLE_ONLY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool shadow = 0;
|
|
|
|
|
|
|
|
bool title_bar = 0;
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
|
|
|
|
switch (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){
|
|
|
|
|
|
|
|
//ensure_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (title_bar){
|
|
|
|
|
|
|
|
//ensure_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
hide_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
|
|
|
|
if (title_bar){
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
if (ctx.header == 0){
|
|
|
|
|
|
|
|
if (ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface != 0){
|
|
|
|
|
|
|
|
wl_subsurface_place_above(ctx.component_slot[COMPONENT_SLOT_HEADER].wl_subsurface,
|
|
|
|
|
|
|
|
ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(ctx.header)){
|
|
|
|
|
|
|
|
gtk_widget_destroy(ctx.header);
|
|
|
|
|
|
|
|
ctx.header = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(ctx.window)){
|
|
|
|
|
|
|
|
gtk_widget_destroy(ctx.window);
|
|
|
|
|
|
|
|
ctx.window = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctx.window = gtk_offscreen_window_new();
|
|
|
|
|
|
|
|
ctx.header = gtk_header_bar_new();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_object_get(gtk_widget_get_settings(ctx.window),
|
|
|
|
|
|
|
|
"gtk-double-click-time", &ctx.double_click_time_ms,
|
|
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_set(ctx.header,
|
|
|
|
|
|
|
|
"title", ctx.title,
|
|
|
|
|
|
|
|
"has-subtitle", FALSE,
|
|
|
|
|
|
|
|
"show-close-button", TRUE,
|
|
|
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_window_set_titlebar(GTK_WINDOW(ctx.window), ctx.header);
|
|
|
|
|
|
|
|
gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(ctx.header), TRUE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_window_set_resizable(GTK_WINDOW(ctx.window), (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sides2D csd_size = {0};
|
|
|
|
Sides2D csd_size = {0};
|
|
|
|
|
|
|
|
Sides2D csd_size_bounds = {0};
|
|
|
|
|
|
|
|
csd_size_bounds.x[1] = (1 << 30);
|
|
|
|
|
|
|
|
csd_size_bounds.y[1] = (1 << 30);
|
|
|
|
if (csd){
|
|
|
|
if (csd){
|
|
|
|
if (title_bar){
|
|
|
|
if (csd_show_title_from_state(ctx.frame_window_state)){
|
|
|
|
gtk_widget_show_all(ctx.window);
|
|
|
|
|
|
|
|
gtk_widget_get_preferred_height(ctx.header, 0, &csd_size.y[0]);
|
|
|
|
gtk_widget_get_preferred_height(ctx.header, 0, &csd_size.y[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), "");
|
|
|
|
|
|
|
|
gtk_widget_get_preferred_width(ctx.header, 0, &csd_size_bounds.x[0]);
|
|
|
|
|
|
|
|
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), ctx.title);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int csd_w = csd_size.x[0] + csd_size.x[1];
|
|
|
|
|
|
|
|
int csd_h = csd_size.y[0] + csd_size.y[1];
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx.has_cached_config){
|
|
|
|
if (ctx.has_cached_config){
|
|
|
|
if (ctx.cached_config.initialized &&
|
|
|
|
if (ctx.cached_config.initialized &&
|
|
|
|
ctx.cached_config.window_width != 0 &&
|
|
|
|
ctx.cached_config.window_width != 0 &&
|
|
|
|
ctx.cached_config.window_height != 0){
|
|
|
|
ctx.cached_config.window_height != 0){
|
|
|
|
int w = ctx.cached_config.window_width;
|
|
|
|
ctx.w = ctx.cached_config.window_width - csd_w;
|
|
|
|
int h = ctx.cached_config.window_height;
|
|
|
|
ctx.h = ctx.cached_config.window_height - csd_h;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sides2D true_size_bounds;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
true_size_bounds.x[0] = CLAMP_BOT(ctx.size_bounds.x[0], csd_size_bounds.x[0]);
|
|
|
|
|
|
|
|
true_size_bounds.y[0] = CLAMP_BOT(ctx.size_bounds.y[0], csd_size_bounds.y[0]);
|
|
|
|
|
|
|
|
true_size_bounds.x[1] = CLAMP_TOP(ctx.size_bounds.x[1], csd_size_bounds.x[1]);
|
|
|
|
|
|
|
|
true_size_bounds.y[1] = CLAMP_TOP(ctx.size_bounds.y[1], csd_size_bounds.y[1]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctx.w = CLAMP_(true_size_bounds.x[0], ctx.w, true_size_bounds.x[1]);
|
|
|
|
|
|
|
|
ctx.h = CLAMP_(true_size_bounds.y[0], ctx.h, true_size_bounds.y[1]);
|
|
|
|
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
if (csd){
|
|
|
|
w -= csd_size.x[0] + csd_size.x[1];
|
|
|
|
{
|
|
|
|
h -= csd_size.y[0] + csd_size.y[1];
|
|
|
|
enum component_slot slot = COMPONENT_SLOT_SHADOW;
|
|
|
|
|
|
|
|
struct border_component *cmpnt = &ctx.component_slot[COMPONENT_SLOT_SHADOW];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (csd_show_shadow_from_state(ctx.frame_window_state)){
|
|
|
|
|
|
|
|
Extent2D extent = {0};
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
extent.x = -(int)SHADOW_MARGIN;
|
|
|
|
|
|
|
|
extent.y = -(int)(SHADOW_MARGIN + csd_size.y[0]);
|
|
|
|
|
|
|
|
extent.w = ctx.w + 2*SHADOW_MARGIN;
|
|
|
|
|
|
|
|
extent.h = csd_size.y[0] + ctx.h + 2*SHADOW_MARGIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!(ctx.cached_config.window_state & LIBDECOR_WINDOW_STATE_NON_FLOATING)){
|
|
|
|
border_component_reallocate(cmpnt, extent.w, extent.h);
|
|
|
|
w = CLAMP_(ctx.size_bounds.x[0], w, ctx.size_bounds.x[1]);
|
|
|
|
memset(cmpnt->data, 0, cmpnt->data_size);
|
|
|
|
h = CLAMP_(ctx.size_bounds.y[0], h, ctx.size_bounds.y[1]);
|
|
|
|
{
|
|
|
|
|
|
|
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, cmpnt->width);
|
|
|
|
|
|
|
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(cmpnt->data, CAIRO_FORMAT_ARGB32, cmpnt->width, cmpnt->height, stride);
|
|
|
|
|
|
|
|
cairo_t *cr = cairo_create(surface);
|
|
|
|
|
|
|
|
cairo_surface_set_device_scale(surface, 1, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
render_shadow(cr, ctx.shadow_blur,
|
|
|
|
|
|
|
|
-(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2,
|
|
|
|
|
|
|
|
cmpnt->width + SHADOW_MARGIN, cmpnt->height + SHADOW_MARGIN,
|
|
|
|
|
|
|
|
64, 64);
|
|
|
|
|
|
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
|
|
|
|
|
|
|
cairo_rectangle(cr, -extent.x, -extent.y, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
cairo_fill(cr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ctx.w = w;
|
|
|
|
wl_surface_attach(cmpnt->wl_surface, cmpnt->wl_buffer, 0, 0);
|
|
|
|
ctx.h = h;
|
|
|
|
wl_surface_set_buffer_scale(cmpnt->wl_surface, 1);
|
|
|
|
|
|
|
|
wl_surface_damage_buffer(cmpnt->wl_surface, 0, 0, extent.w, extent.h);
|
|
|
|
|
|
|
|
wl_subsurface_set_position(cmpnt->wl_subsurface, extent.x, extent.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
wl_surface_attach(cmpnt->wl_surface, 0, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_surface_commit(cmpnt->wl_surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
{
|
|
|
|
if (title_bar){
|
|
|
|
enum component_slot slot = COMPONENT_SLOT_HEADER;
|
|
|
|
enum libdecor_window_state state = ctx.frame_window_state;
|
|
|
|
struct border_component *cmpnt = &ctx.component_slot[slot];
|
|
|
|
|
|
|
|
|
|
|
|
if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
|
|
|
if (csd_show_title_from_state(ctx.frame_window_state)){
|
|
|
|
|
|
|
|
Extent2D extent = {0};
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
extent.x = 0;
|
|
|
|
|
|
|
|
extent.y = -csd_size.y[0];
|
|
|
|
|
|
|
|
extent.w = ctx.w;
|
|
|
|
|
|
|
|
extent.h = csd_size.y[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_window_set_resizable(GTK_WINDOW(ctx.window), (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE) != 0);
|
|
|
|
|
|
|
|
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
|
|
|
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
|
|
|
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
else{
|
|
|
|
@ -1103,134 +1100,42 @@ int main(){
|
|
|
|
else{
|
|
|
|
else{
|
|
|
|
gtk_style_context_add_class(style, "maximized");
|
|
|
|
gtk_style_context_add_class(style, "maximized");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gtk_widget_show_all(ctx.window);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int preferred_min_width;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
gtk_header_bar_set_title(GTK_HEADER_BAR(ctx.header), "");
|
|
|
|
|
|
|
|
gtk_widget_get_preferred_width(ctx.header, NULL, &preferred_min_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], preferred_min_width);
|
|
|
|
|
|
|
|
ctx.size_bounds.x[1] = CLAMP_BOT(ctx.size_bounds.x[1], ctx.size_bounds.x[0]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
|
|
|
|
|
|
|
xdg_toplevel_set_min_size(ctx.xdg_toplevel, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
xdg_toplevel_set_max_size(ctx.xdg_toplevel, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
int csd_added_w = csd_size.x[0] + csd_size.x[1];
|
|
|
|
|
|
|
|
int csd_added_h = csd_size.y[0] + csd_size.y[1];
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; i += 1){
|
|
|
|
|
|
|
|
int mw = ctx.size_bounds.x[i] + csd_added_w;
|
|
|
|
|
|
|
|
int mh = ctx.size_bounds.y[i] + csd_added_h;
|
|
|
|
|
|
|
|
if (i == 0){
|
|
|
|
|
|
|
|
xdg_toplevel_set_min_size(ctx.xdg_toplevel, mw, mh);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
xdg_toplevel_set_max_size(ctx.xdg_toplevel, mw, mh);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
|
|
|
|
if (shadow){
|
|
|
|
|
|
|
|
Extent2D extent = {0};
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
extent.x = -(int)SHADOW_MARGIN;
|
|
|
|
|
|
|
|
extent.y = -(int)(SHADOW_MARGIN + csd_size.y[0]);
|
|
|
|
|
|
|
|
extent.w = ctx.w + 2*SHADOW_MARGIN;
|
|
|
|
|
|
|
|
extent.h = csd_size.y[0] + ctx.h + 2*SHADOW_MARGIN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct wl_region *input_region = wl_compositor_create_region(ctx.wl_compositor);
|
|
|
|
|
|
|
|
wl_region_add(input_region, 0, 0, extent.w, extent.h);
|
|
|
|
|
|
|
|
wl_region_subtract(input_region, -extent.x, -extent.y, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
wl_surface_set_input_region(ctx.component_slot[COMPONENT_SLOT_SHADOW].wl_surface, input_region);
|
|
|
|
|
|
|
|
wl_region_destroy(input_region);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
enum component_slot slot = COMPONENT_SLOT_SHADOW;
|
|
|
|
|
|
|
|
struct border_component *component = &ctx.component_slot[slot];
|
|
|
|
|
|
|
|
border_component_reallocate(component, extent.w, extent.h);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(component->data, 0, component->data_size);
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, component->width);
|
|
|
|
|
|
|
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(component->data, CAIRO_FORMAT_ARGB32, component->width, component->height, stride);
|
|
|
|
|
|
|
|
cairo_t *cr = cairo_create(surface);
|
|
|
|
|
|
|
|
cairo_surface_set_device_scale(surface, 1, 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
render_shadow(cr, ctx.shadow_blur,
|
|
|
|
|
|
|
|
-(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2,
|
|
|
|
|
|
|
|
component->width + SHADOW_MARGIN, component->height + SHADOW_MARGIN,
|
|
|
|
|
|
|
|
64, 64);
|
|
|
|
|
|
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
|
|
|
|
|
|
|
cairo_rectangle(cr, -extent.x, -extent.y, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
cairo_fill(cr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_surface_attach(component->wl_surface, component->wl_buffer, 0, 0);
|
|
|
|
|
|
|
|
wl_surface_set_buffer_scale(component->wl_surface, 1);
|
|
|
|
|
|
|
|
wl_surface_commit(component->wl_surface);
|
|
|
|
|
|
|
|
wl_surface_damage_buffer(component->wl_surface, 0, 0, extent.w, extent.h);
|
|
|
|
|
|
|
|
wl_subsurface_set_position(component->wl_subsurface, extent.x, extent.y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (title_bar){
|
|
|
|
|
|
|
|
Extent2D extent = {0};
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
extent.x = 0;
|
|
|
|
|
|
|
|
extent.y = -csd_size.y[0];
|
|
|
|
|
|
|
|
extent.w = ctx.w;
|
|
|
|
|
|
|
|
extent.h = csd_size.y[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GtkAllocation allocation = {0, 0, ctx.w, csd_size.y[0]};
|
|
|
|
GtkAllocation allocation = {0, 0, ctx.w, csd_size.y[0]};
|
|
|
|
gtk_widget_size_allocate(ctx.header, &allocation);
|
|
|
|
gtk_widget_size_allocate(ctx.header, &allocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
border_component_reallocate(cmpnt, extent.w, extent.h);
|
|
|
|
|
|
|
|
memset(cmpnt->data, 0, cmpnt->data_size);
|
|
|
|
{
|
|
|
|
{
|
|
|
|
enum component_slot slot = COMPONENT_SLOT_HEADER;
|
|
|
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, cmpnt->width);
|
|
|
|
struct border_component *component = &ctx.component_slot[slot];
|
|
|
|
cairo_surface_t *surface =
|
|
|
|
border_component_reallocate(component, extent.w, extent.h);
|
|
|
|
cairo_image_surface_create_for_data(cmpnt->data, CAIRO_FORMAT_ARGB32,
|
|
|
|
|
|
|
|
cmpnt->width, cmpnt->height, stride);
|
|
|
|
memset(component->data, 0, component->data_size);
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, component->width);
|
|
|
|
|
|
|
|
cairo_surface_t *surface = cairo_image_surface_create_for_data(component->data, CAIRO_FORMAT_ARGB32, component->width, component->height, stride);
|
|
|
|
|
|
|
|
cairo_t *cr = cairo_create(surface);
|
|
|
|
cairo_t *cr = cairo_create(surface);
|
|
|
|
cairo_surface_set_device_scale(surface, 1, 1);
|
|
|
|
cairo_surface_set_device_scale(surface, 1, 1);
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* background */
|
|
|
|
/* background */
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GtkAllocation allocation;
|
|
|
|
GtkAllocation allocation;
|
|
|
|
gtk_widget_get_allocation(GTK_WIDGET(ctx.header), &allocation);
|
|
|
|
gtk_widget_get_allocation(GTK_WIDGET(ctx.header), &allocation);
|
|
|
|
GtkStyleContext* style = gtk_widget_get_style_context(ctx.header);
|
|
|
|
GtkStyleContext* style = gtk_widget_get_style_context(ctx.header);
|
|
|
|
gtk_render_background(style, cr, allocation.x, allocation.y, allocation.width, allocation.height);
|
|
|
|
gtk_render_background(style, cr,
|
|
|
|
|
|
|
|
allocation.x, allocation.y,
|
|
|
|
|
|
|
|
allocation.width, allocation.height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* title */
|
|
|
|
/* title */
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GtkWidget *label = find_widget_by_type(ctx.header, HEADER_TITLE);
|
|
|
|
GtkWidget *label = find_widget_by_type(ctx.header, HEADER_TITLE);
|
|
|
|
|
|
|
|
|
|
|
|
GtkAllocation allocation;
|
|
|
|
GtkAllocation allocation;
|
|
|
|
gtk_widget_get_allocation(label, &allocation);
|
|
|
|
gtk_widget_get_allocation(label, &allocation);
|
|
|
|
|
|
|
|
cairo_surface_t *label_surface =
|
|
|
|
cairo_surface_t *label_surface = cairo_surface_create_for_rectangle(surface, allocation.x, allocation.y, allocation.width, allocation.height);
|
|
|
|
cairo_surface_create_for_rectangle(surface,
|
|
|
|
|
|
|
|
allocation.x, allocation.y,
|
|
|
|
|
|
|
|
allocation.width, allocation.height);
|
|
|
|
cairo_t *cr2 = cairo_create(label_surface);
|
|
|
|
cairo_t *cr2 = cairo_create(label_surface);
|
|
|
|
gtk_widget_size_allocate(label, &allocation);
|
|
|
|
|
|
|
|
gtk_widget_draw(label, cr2);
|
|
|
|
gtk_widget_draw(label, cr2);
|
|
|
|
cairo_destroy(cr2);
|
|
|
|
cairo_destroy(cr2);
|
|
|
|
cairo_surface_destroy(label_surface);
|
|
|
|
cairo_surface_destroy(label_surface);
|
|
|
|
@ -1240,24 +1145,20 @@ int main(){
|
|
|
|
{
|
|
|
|
{
|
|
|
|
enum header_element buttons[3] = {0};
|
|
|
|
enum header_element buttons[3] = {0};
|
|
|
|
size_t nbuttons = 0;
|
|
|
|
size_t nbuttons = 0;
|
|
|
|
|
|
|
|
if (ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE){
|
|
|
|
if ((ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE)){
|
|
|
|
|
|
|
|
buttons[nbuttons] = HEADER_MIN;
|
|
|
|
buttons[nbuttons] = HEADER_MIN;
|
|
|
|
nbuttons += 1;
|
|
|
|
nbuttons += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
|
|
|
if (ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE){
|
|
|
|
buttons[nbuttons] = HEADER_MAX;
|
|
|
|
buttons[nbuttons] = HEADER_MAX;
|
|
|
|
nbuttons += 1;
|
|
|
|
nbuttons += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE)){
|
|
|
|
if (ctx.frame_capabilities & LIBDECOR_ACTION_CLOSE){
|
|
|
|
buttons[nbuttons] = HEADER_CLOSE;
|
|
|
|
buttons[nbuttons] = HEADER_CLOSE;
|
|
|
|
nbuttons += 1;
|
|
|
|
nbuttons += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < nbuttons; i += 1){
|
|
|
|
for (int i = 0; i < nbuttons; i += 1){
|
|
|
|
enum header_element button_type = buttons[i];
|
|
|
|
draw_header_button(cr, surface, buttons[i]);
|
|
|
|
draw_header_button(cr, surface, button_type);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -1265,37 +1166,65 @@ int main(){
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wl_surface_attach(component->wl_surface, component->wl_buffer, 0, 0);
|
|
|
|
wl_surface_attach(cmpnt->wl_surface, cmpnt->wl_buffer, 0, 0);
|
|
|
|
wl_surface_set_buffer_scale(component->wl_surface, 1);
|
|
|
|
wl_surface_set_buffer_scale(cmpnt->wl_surface, 1);
|
|
|
|
wl_surface_commit(component->wl_surface);
|
|
|
|
wl_surface_damage_buffer(cmpnt->wl_surface, 0, 0, extent.w, extent.h);
|
|
|
|
wl_surface_damage_buffer(component->wl_surface, 0, 0, extent.w, extent.h);
|
|
|
|
wl_subsurface_set_position(cmpnt->wl_subsurface, extent.x, extent.y);
|
|
|
|
wl_subsurface_set_position(component->wl_subsurface, extent.x, extent.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
wl_surface_attach(cmpnt->wl_surface, 0, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_surface_commit(cmpnt->wl_surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
|
|
|
|
|
|
|
xdg_toplevel_set_min_size(ctx.xdg_toplevel, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
xdg_toplevel_set_max_size(ctx.xdg_toplevel, ctx.w, ctx.h);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; i += 1){
|
|
|
|
|
|
|
|
int mw = true_size_bounds.x[i] + csd_w;
|
|
|
|
|
|
|
|
int mh = true_size_bounds.y[i] + csd_h;
|
|
|
|
|
|
|
|
if (i == 0){
|
|
|
|
|
|
|
|
xdg_toplevel_set_min_size(ctx.xdg_toplevel, mw, mh);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else{
|
|
|
|
|
|
|
|
xdg_toplevel_set_max_size(ctx.xdg_toplevel, mw, mh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
xdg_surface_set_window_geometry(ctx.xdg_surface,
|
|
|
|
Extent2D extent = {0};
|
|
|
|
-csd_size.x[0], -csd_size.y[0],
|
|
|
|
extent.w = ctx.w;
|
|
|
|
ctx.w + csd_w, ctx.h + csd_h);
|
|
|
|
extent.h = ctx.h;
|
|
|
|
|
|
|
|
if (csd){
|
|
|
|
|
|
|
|
extent.x = -csd_size.x[0];
|
|
|
|
|
|
|
|
extent.y = -csd_size.y[0];
|
|
|
|
|
|
|
|
extent.w += csd_size.x[0] + csd_size.x[1];
|
|
|
|
|
|
|
|
extent.h += csd_size.y[0] + csd_size.y[1];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
xdg_surface_set_window_geometry(ctx.xdg_surface, extent.x, extent.y, extent.w, extent.h);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_egl_window_resize(ctx.wl_egl_window, ctx.w, ctx.h, 0, 0);
|
|
|
|
wl_egl_window_resize(ctx.wl_egl_window, ctx.w, ctx.h, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* re-render cursor */
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
wl_surface_set_buffer_scale(ctx.seat->cursor_surface, 1);
|
|
|
|
|
|
|
|
wl_surface_attach(ctx.seat->cursor_surface, buffer, 0, 0);
|
|
|
|
|
|
|
|
wl_surface_damage_buffer(ctx.seat->cursor_surface, 0, 0, image->width, image->height);
|
|
|
|
|
|
|
|
wl_surface_commit(ctx.seat->cursor_surface);
|
|
|
|
|
|
|
|
wl_pointer_set_cursor(ctx.seat->wl_pointer, ctx.seat->serial, ctx.seat->cursor_surface, image->hotspot_x, image->hotspot_y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* app update & render */
|
|
|
|
/* app update & render */
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -1313,6 +1242,14 @@ int main(){
|
|
|
|
if (!swap_success){
|
|
|
|
if (!swap_success){
|
|
|
|
printf("eglSwapBuffers failed\n");
|
|
|
|
printf("eglSwapBuffers failed\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ctx.has_cached_config){
|
|
|
|
|
|
|
|
xdg_surface_ack_configure(ctx.xdg_surface, ctx.cached_config.serial);
|
|
|
|
|
|
|
|
ctx.has_cached_config = 0;
|
|
|
|
|
|
|
|
memset(&ctx.cached_config, 0, sizeof ctx.cached_config);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_surface_commit(ctx.wl_surface);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
return(0);
|
|
|
|
@ -1350,33 +1287,6 @@ int main(){
|
|
|
|
* SOFTWARE.
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//#include "libdecor.c"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Extent2D
|
|
|
|
|
|
|
|
extent2d_from_component_slot(enum component_slot slot, int title_height){
|
|
|
|
|
|
|
|
Extent2D result = {0};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (slot){
|
|
|
|
|
|
|
|
default: case COMPONENT_SLOT_NONE: break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case COMPONENT_SLOT_SHADOW: {
|
|
|
|
|
|
|
|
result.x = -(int)SHADOW_MARGIN;
|
|
|
|
|
|
|
|
result.y = -(int)(SHADOW_MARGIN + title_height);
|
|
|
|
|
|
|
|
result.w = ctx.w + 2*SHADOW_MARGIN;
|
|
|
|
|
|
|
|
result.h = title_height + ctx.h + 2*SHADOW_MARGIN;
|
|
|
|
|
|
|
|
}break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case COMPONENT_SLOT_HEADER: {
|
|
|
|
|
|
|
|
result.x = 0;
|
|
|
|
|
|
|
|
result.y = -title_height;
|
|
|
|
|
|
|
|
result.w = ctx.w;
|
|
|
|
|
|
|
|
result.h = title_height;
|
|
|
|
|
|
|
|
}break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#include "libdecor-cairo-blur.c"
|
|
|
|
//#include "libdecor-cairo-blur.c"
|
|
|
|
int
|
|
|
|
int
|
|
|
|
blur_surface(cairo_surface_t *surface, int margin){
|
|
|
|
blur_surface(cairo_surface_t *surface, int margin){
|
|
|
|
@ -1705,56 +1615,6 @@ int os_create_anonymous_file(off_t size){
|
|
|
|
|
|
|
|
|
|
|
|
//#include "plugins/gtk/libdecor-gtk.c"
|
|
|
|
//#include "plugins/gtk/libdecor-gtk.c"
|
|
|
|
|
|
|
|
|
|
|
|
struct find_widget_variables{
|
|
|
|
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
GtkWidget *widget;
|
|
|
|
|
|
|
|
} find_widget_variables;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
|
|
fill_widget_from_name(GtkWidget *widget, void *data){
|
|
|
|
|
|
|
|
struct find_widget_variables *vars = data;
|
|
|
|
|
|
|
|
if (vars->widget == 0){
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
|
|
|
|
if (GTK_IS_WIDGET(widget)){
|
|
|
|
|
|
|
|
GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
|
|
|
|
|
|
|
|
char *style_str = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
|
|
|
|
|
|
|
|
if (strstr(style_str, vars->name) != 0){
|
|
|
|
|
|
|
|
vars->widget = widget;
|
|
|
|
|
|
|
|
match = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
free(style_str);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!match && GTK_IS_CONTAINER(widget)){
|
|
|
|
|
|
|
|
gtk_container_forall(GTK_CONTAINER(widget), &fill_widget_from_name, data);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static GtkWidget*
|
|
|
|
|
|
|
|
find_widget_by_type(GtkWidget *root, enum header_element type){
|
|
|
|
|
|
|
|
struct find_widget_variables vars = {0};
|
|
|
|
|
|
|
|
switch (type){
|
|
|
|
|
|
|
|
case HEADER_FULL: vars.name = "headerbar.titlebar:"; break;
|
|
|
|
|
|
|
|
case HEADER_TITLE: vars.name = "label.title:"; break;
|
|
|
|
|
|
|
|
case HEADER_MIN: vars.name = ".minimize"; break;
|
|
|
|
|
|
|
|
case HEADER_MAX: vars.name = ".maximize"; break;
|
|
|
|
|
|
|
|
case HEADER_CLOSE: vars.name = ".close"; break;
|
|
|
|
|
|
|
|
default:break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fill_widget_from_name(root, &vars);
|
|
|
|
|
|
|
|
return(vars.widget);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
|
|
|
own_proxy(void *proxy){
|
|
|
|
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
if (proxy != 0){
|
|
|
|
|
|
|
|
result = (wl_proxy_get_tag((struct wl_proxy*)proxy) == &libdecor_gtk_proxy_tag);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
toggle_maximized(void){
|
|
|
|
toggle_maximized(void){
|
|
|
|
if (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED){
|
|
|
|
if (ctx.frame_window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED){
|
|
|
|
@ -1765,27 +1625,6 @@ toggle_maximized(void){
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static enum component_slot
|
|
|
|
|
|
|
|
component_slot_from_wl_surface(const struct wl_surface *surface){
|
|
|
|
|
|
|
|
enum component_slot result = 0;
|
|
|
|
|
|
|
|
for (int i = 1; i < COMPONENT_SLOT_COUNT; i += 1){
|
|
|
|
|
|
|
|
if (ctx.component_slot[i].wl_surface == surface){
|
|
|
|
|
|
|
|
result = i;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
|
|
ensure_component(struct border_component *cmpnt){
|
|
|
|
|
|
|
|
if (cmpnt->wl_surface == 0){
|
|
|
|
|
|
|
|
cmpnt->wl_surface = wl_compositor_create_surface(ctx.wl_compositor);
|
|
|
|
|
|
|
|
wl_proxy_set_tag((struct wl_proxy *)cmpnt->wl_surface, &libdecor_gtk_proxy_tag);
|
|
|
|
|
|
|
|
cmpnt->wl_subsurface = wl_subcompositor_get_subsurface(ctx.wl_subcompositor, cmpnt->wl_surface, ctx.wl_surface);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
static void
|
|
|
|
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|
|
|
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
|
|
|
enum header_element button_type){
|
|
|
|
enum header_element button_type){
|
|
|
|
@ -1948,17 +1787,15 @@ edge_from_pos(int x, int y){
|
|
|
|
|
|
|
|
|
|
|
|
//#include "desktop-settings.c"
|
|
|
|
//#include "desktop-settings.c"
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
static int
|
|
|
|
get_cursor_settings_from_env(char **theme, int *size){
|
|
|
|
get_cursor_settings_from_env(char **theme, int *size){
|
|
|
|
char *env_xtheme = getenv("XCURSOR_THEME");
|
|
|
|
char *env_xtheme = getenv("XCURSOR_THEME");
|
|
|
|
char *env_xsize = getenv("XCURSOR_SIZE");
|
|
|
|
char *env_xsize = getenv("XCURSOR_SIZE");
|
|
|
|
bool got_theme = (env_xtheme != 0 && env_xsize != 0);
|
|
|
|
int got_theme = (env_xtheme != 0 && env_xsize != 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (got_theme){
|
|
|
|
if (got_theme){
|
|
|
|
*theme = strdup(env_xtheme);
|
|
|
|
*theme = strdup(env_xtheme);
|
|
|
|
*size = atoi(env_xsize);
|
|
|
|
*size = atoi(env_xsize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return(got_theme);
|
|
|
|
return(got_theme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -2024,10 +1861,8 @@ desktop_settings_get_cursor_settings(char **theme, int *size){
|
|
|
|
const char *value_theme = 0;
|
|
|
|
const char *value_theme = 0;
|
|
|
|
|
|
|
|
|
|
|
|
DBusError error;
|
|
|
|
DBusError error;
|
|
|
|
DBusConnection *connection;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dbus_error_init(&error);
|
|
|
|
dbus_error_init(&error);
|
|
|
|
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
|
|
|
DBusConnection *connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
|
|
|
|
|
|
|
|
|
|
|
if (!dbus_error_is_set(&error)){
|
|
|
|
if (!dbus_error_is_set(&error)){
|
|
|
|
DBusMessage *reply = get_setting_sync(connection, name, key_theme);
|
|
|
|
DBusMessage *reply = get_setting_sync(connection, name, key_theme);
|
|
|
|
@ -2063,14 +1898,11 @@ desktop_settings_get_color_scheme(){
|
|
|
|
uint32_t color = 0;
|
|
|
|
uint32_t color = 0;
|
|
|
|
|
|
|
|
|
|
|
|
DBusError error;
|
|
|
|
DBusError error;
|
|
|
|
DBusConnection *connection;
|
|
|
|
|
|
|
|
DBusMessage *reply;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dbus_error_init(&error);
|
|
|
|
dbus_error_init(&error);
|
|
|
|
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
|
|
|
DBusConnection *connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
|
|
|
|
|
|
|
|
|
|
|
if (!dbus_error_is_set(&error)){
|
|
|
|
if (!dbus_error_is_set(&error)){
|
|
|
|
reply = get_setting_sync(connection, name, key_color_scheme);
|
|
|
|
DBusMessage *reply = get_setting_sync(connection, name, key_color_scheme);
|
|
|
|
if (reply){
|
|
|
|
if (reply){
|
|
|
|
if (!parse_type(reply, DBUS_TYPE_UINT32, &color)) {
|
|
|
|
if (!parse_type(reply, DBUS_TYPE_UINT32, &color)) {
|
|
|
|
color = 0;
|
|
|
|
color = 0;
|
|
|
|
@ -2078,7 +1910,6 @@ desktop_settings_get_color_scheme(){
|
|
|
|
dbus_message_unref(reply);
|
|
|
|
dbus_message_unref(reply);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return(color);
|
|
|
|
return(color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -2096,3 +1927,20 @@ desktop_settings_get_color_scheme(){
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
|
|
csd_show_title_from_state(enum libdecor_window_state state){
|
|
|
|
|
|
|
|
int result = (!(state & LIBDECOR_WINDOW_STATE_FULLSCREEN));
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
|
|
csd_show_shadow_from_state(enum libdecor_window_state state){
|
|
|
|
|
|
|
|
int result = (!(state & (LIBDECOR_WINDOW_STATE_FULLSCREEN |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_MAXIMIZED |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_LEFT |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_RIGHT |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_TOP |
|
|
|
|
|
|
|
|
LIBDECOR_WINDOW_STATE_TILED_BOTTOM)));
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|