It looks like it's just going to be getting the subsurface offsets
parent
d7770effea
commit
070ab2f42f
|
|
@ -1032,39 +1032,29 @@ csd_gtk_update_and_render(void){
|
||||||
CSD_Window *window = &ctx.window;
|
CSD_Window *window = &ctx.window;
|
||||||
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
CSD_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||||
|
|
||||||
if (window->control_flags & CSD_WindowControlFlag_Resize){
|
/* determine cursor location information */
|
||||||
static const CSD_CursorShape cursor_box[] = {
|
enum{
|
||||||
CSD_CursorShape_Resize_TopLeft, CSD_CursorShape_Resize_Top, CSD_CursorShape_Resize_TopRight,
|
LOCATION_NULL, LOCATION_SHADOW, LOCATION_TITLEBAR,
|
||||||
CSD_CursorShape_Resize_Left, CSD_CursorShape_Pointer, CSD_CursorShape_Resize_Right,
|
|
||||||
CSD_CursorShape_Resize_BottomLeft, CSD_CursorShape_Resize_Bottom, CSD_CursorShape_Resize_BottomRight,
|
|
||||||
};
|
};
|
||||||
|
CSD_U32 cursor_loc = LOCATION_NULL;
|
||||||
static const enum xdg_toplevel_resize_edge xedge_box[] = {
|
CSD_S32 cursor_shadow_loc = 0;
|
||||||
XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT,
|
{
|
||||||
XDG_TOPLEVEL_RESIZE_EDGE_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_NONE, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT,
|
{
|
||||||
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
|
|
||||||
};
|
|
||||||
|
|
||||||
CSD_S32 l = (seat->hover_p[0] < 0);
|
CSD_S32 l = (seat->hover_p[0] < 0);
|
||||||
CSD_S32 r = (!l && seat->hover_p[0] >= window->dim[0]);
|
CSD_S32 r = (!l && seat->hover_p[0] >= window->dim[0]);
|
||||||
CSD_S32 t = (seat->hover_p[1] < -window->csd_frame.border[1][0]);
|
CSD_S32 t = (seat->hover_p[1] < -window->csd_frame.border[1][0]);
|
||||||
CSD_S32 b = (!t && seat->hover_p[1] >= window->dim[1]);
|
CSD_S32 b = (!t && seat->hover_p[1] >= window->dim[1]);
|
||||||
CSD_S32 loc = 3*(b - t) + (r - l);
|
cursor_shadow_loc = 3*(b - t) + (r - l);
|
||||||
seat->cursor_shape = cursor_box[4 + loc];
|
}
|
||||||
if (ctx.has_event &&
|
if (cursor_shadow_loc != 0){
|
||||||
ctx.event_button == BTN_LEFT &&
|
cursor_loc = LOCATION_SHADOW;
|
||||||
ctx.event_button_state == 1){
|
|
||||||
ctx.has_event = 0;
|
|
||||||
if (loc != 0){
|
|
||||||
xdg_toplevel_resize(window->main_xdg_toplevel, seat->wl_seat,
|
|
||||||
seat->serial, xedge_box[4 + loc]);
|
|
||||||
}
|
}
|
||||||
else if (seat->hover_p[1] < 0){
|
else if (seat->hover_p[1] < 0){
|
||||||
xdg_toplevel_move(window->main_xdg_toplevel, seat->wl_seat, seat->serial);
|
cursor_loc = LOCATION_TITLEBAR;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* draw shadow */
|
||||||
{
|
{
|
||||||
CSD_SubSurface *subsurface = >k_window->shadow;
|
CSD_SubSurface *subsurface = >k_window->shadow;
|
||||||
|
|
||||||
|
|
@ -1108,6 +1098,26 @@ csd_gtk_update_and_render(void){
|
||||||
csd_subsurface_commit(subsurface);
|
csd_subsurface_commit(subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* setup buttons */
|
||||||
|
enum{
|
||||||
|
HEADER_BUTTON_NULL,
|
||||||
|
HEADER_BUTTON_MIN, HEADER_BUTTON_MAX, HEADER_BUTTON_CLOSE,
|
||||||
|
HEADER_BUTTON_COUNT
|
||||||
|
};
|
||||||
|
static char* header_button_name[] = {
|
||||||
|
0, ".minimize", ".maximize", ".close"
|
||||||
|
};
|
||||||
|
CSD_B32 header_button_active[] = {
|
||||||
|
/*NULL*/ 0,
|
||||||
|
/*MIN*/ (window->control_flags & CSD_WindowControlFlag_Min),
|
||||||
|
/*MAX*/ ((window->control_flags & CSD_WindowControlFlag_Max) &&
|
||||||
|
(window->control_flags & CSD_WindowControlFlag_Resize)),
|
||||||
|
/*CLOSE*/ (window->control_flags & CSD_WindowControlFlag_Close)
|
||||||
|
};
|
||||||
|
CSD_U32 header_button_hover = 0;
|
||||||
|
|
||||||
|
/* draw frame */
|
||||||
{
|
{
|
||||||
CSD_SubSurface *subsurface = >k_window->titlebar;
|
CSD_SubSurface *subsurface = >k_window->titlebar;
|
||||||
|
|
||||||
|
|
@ -1153,7 +1163,7 @@ csd_gtk_update_and_render(void){
|
||||||
cairo_t *cr = cairo_create(cr_surface);
|
cairo_t *cr = cairo_create(cr_surface);
|
||||||
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
||||||
|
|
||||||
/* background */
|
/* draw background */
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gtk_widget_get_allocation(GTK_WIDGET(gtk_window->header), &allocation);
|
gtk_widget_get_allocation(GTK_WIDGET(gtk_window->header), &allocation);
|
||||||
|
|
@ -1163,7 +1173,7 @@ csd_gtk_update_and_render(void){
|
||||||
allocation.width, allocation.height);
|
allocation.width, allocation.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* title */
|
/* draw title */
|
||||||
{
|
{
|
||||||
GtkWidget *label_title =
|
GtkWidget *label_title =
|
||||||
csd_gtk__widget_from_name(gtk_window->header, "label.title:");
|
csd_gtk__widget_from_name(gtk_window->header, "label.title:");
|
||||||
|
|
@ -1181,72 +1191,63 @@ csd_gtk_update_and_render(void){
|
||||||
cairo_surface_destroy(cr_label_surface);
|
cairo_surface_destroy(cr_label_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* buttons */
|
/* draw buttons */
|
||||||
CSD_U32 buttons[3] = {0};
|
for (CSD_U32 i = 1; i < HEADER_BUTTON_COUNT; i += 1){
|
||||||
int button_count = 0;
|
if (header_button_active[i]){
|
||||||
if (window->control_flags & CSD_WindowControlFlag_Min){
|
|
||||||
buttons[button_count] = 0;
|
|
||||||
button_count += 1;
|
|
||||||
}
|
|
||||||
if ((window->control_flags & CSD_WindowControlFlag_Max) &&
|
|
||||||
(window->control_flags & CSD_WindowControlFlag_Resize)){
|
|
||||||
buttons[button_count] = 1;
|
|
||||||
button_count += 1;
|
|
||||||
}
|
|
||||||
if (window->control_flags & CSD_WindowControlFlag_Close){
|
|
||||||
buttons[button_count] = 2;
|
|
||||||
button_count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < button_count; i += 1){
|
|
||||||
CSD_U32 button_code = buttons[i];
|
|
||||||
|
|
||||||
char *button_name = "";
|
|
||||||
char *icon_name = "";
|
char *icon_name = "";
|
||||||
switch (button_code){
|
switch (i){
|
||||||
case 0: {
|
case HEADER_BUTTON_MIN: {
|
||||||
button_name = ".minimize";
|
|
||||||
icon_name = "window-minimize-symbolic";
|
icon_name = "window-minimize-symbolic";
|
||||||
}break;
|
}break;
|
||||||
case 1: {
|
case HEADER_BUTTON_MAX: {
|
||||||
button_name = ".maximize";
|
|
||||||
icon_name = ((window->config.flags & CSD_WindowFlag_IsMax) ?
|
icon_name = ((window->config.flags & CSD_WindowFlag_IsMax) ?
|
||||||
"window-restore-symbolic" : "window-maximize-symbolic");
|
"window-restore-symbolic" : "window-maximize-symbolic");
|
||||||
}break;
|
}break;
|
||||||
case 2: {
|
case HEADER_BUTTON_CLOSE: {
|
||||||
button_name = ".close";
|
|
||||||
icon_name = "window-close-symbolic";
|
icon_name = "window-close-symbolic";
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *button_widget =
|
GtkWidget *widget =
|
||||||
csd_gtk__widget_from_name(gtk_window->header, button_name);
|
csd_gtk__widget_from_name(gtk_window->header, header_button_name[i]);
|
||||||
|
|
||||||
if (button_widget != 0){
|
if (widget != 0){
|
||||||
GtkStyleContext *style = gtk_widget_get_style_context(button_widget);
|
/* layout */
|
||||||
|
GtkAllocation rect;
|
||||||
|
gtk_widget_get_clip(widget, &rect);
|
||||||
|
|
||||||
|
/* check pointer hover */
|
||||||
|
CSD_B32 is_hovered = 0;
|
||||||
|
{
|
||||||
|
CSD_S32 x0 = rect.x;
|
||||||
|
CSD_S32 y0 = rect.y - title_dim[1];
|
||||||
|
CSD_S32 x1 = rect.x + rect.width;
|
||||||
|
CSD_S32 y1 = rect.y + rect.height - title_dim[1];
|
||||||
|
if (x0 <= seat->hover_p[0] && seat->hover_p[0] < x1 &&
|
||||||
|
y0 <= seat->hover_p[1] && seat->hover_p[1] < y1){
|
||||||
|
header_button_hover = i;
|
||||||
|
is_hovered = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* change style based on window state and focus */
|
/* change style based on window state and focus */
|
||||||
|
GtkStyleContext *style = gtk_widget_get_style_context(widget);
|
||||||
GtkStateFlags style_state = 0;
|
GtkStateFlags style_state = 0;
|
||||||
if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
|
if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
|
||||||
style_state |= GTK_STATE_FLAG_BACKDROP;
|
style_state |= GTK_STATE_FLAG_BACKDROP;
|
||||||
}
|
}
|
||||||
if (gtk_window->hover_button_code == button_code){
|
if (is_hovered){
|
||||||
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
if (gtk_window->active_button_code == button_code){
|
if (i == gtk_window->active_header_button){
|
||||||
style_state |= GTK_STATE_FLAG_ACTIVE;
|
style_state |= GTK_STATE_FLAG_ACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* background */
|
/* background */
|
||||||
GtkAllocation allocation;
|
|
||||||
gtk_widget_get_clip(button_widget, &allocation);
|
|
||||||
|
|
||||||
gtk_style_context_save(style);
|
gtk_style_context_save(style);
|
||||||
gtk_style_context_set_state(style, style_state);
|
gtk_style_context_set_state(style, style_state);
|
||||||
gtk_render_background(style, cr, allocation.x, allocation.y,
|
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
allocation.width, allocation.height);
|
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||||
gtk_render_frame(style, cr, allocation.x, allocation.y,
|
|
||||||
allocation.width, allocation.height);
|
|
||||||
gtk_style_context_restore(style);
|
gtk_style_context_restore(style);
|
||||||
|
|
||||||
/* get scale */
|
/* get scale */
|
||||||
|
|
@ -1255,7 +1256,7 @@ csd_gtk_update_and_render(void){
|
||||||
int scale = (sx + sy)/2.0;
|
int scale = (sx + sy)/2.0;
|
||||||
|
|
||||||
/* get original icon dimensions */
|
/* get original icon dimensions */
|
||||||
GtkWidget *icon_widget = gtk_bin_get_child(GTK_BIN(button_widget));
|
GtkWidget *icon_widget = gtk_bin_get_child(GTK_BIN(widget));
|
||||||
|
|
||||||
/* icon info */
|
/* icon info */
|
||||||
gint icon_width, icon_height;
|
gint icon_width, icon_height;
|
||||||
|
|
@ -1284,37 +1285,30 @@ csd_gtk_update_and_render(void){
|
||||||
width = CSD_ClampBot(width, icon_width);
|
width = CSD_ClampBot(width, icon_width);
|
||||||
height = CSD_ClampBot(height, icon_height);
|
height = CSD_ClampBot(height, icon_height);
|
||||||
|
|
||||||
gint left = 0;
|
|
||||||
gint top = 0;
|
|
||||||
gint right = 0;
|
|
||||||
gint bottom = 0;
|
|
||||||
|
|
||||||
GtkBorder border;
|
GtkBorder border;
|
||||||
gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
|
gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border);
|
||||||
left += border.left;
|
|
||||||
right += border.right;
|
|
||||||
top += border.top;
|
|
||||||
bottom += border.bottom;
|
|
||||||
|
|
||||||
GtkBorder padding;
|
GtkBorder padding;
|
||||||
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
||||||
left += padding.left;
|
|
||||||
right += padding.right;
|
gint left = border.left + padding.left;
|
||||||
top += padding.top;
|
gint right = border.right + padding.right;
|
||||||
bottom += padding.bottom;
|
gint top = border.top + padding.top;
|
||||||
|
gint bottom = border.bottom + padding.bottom;
|
||||||
|
|
||||||
width += left + right;
|
width += left + right;
|
||||||
height += top + bottom;
|
height += top + bottom;
|
||||||
|
|
||||||
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
||||||
cr, icon_surface,
|
cr, icon_surface,
|
||||||
allocation.x + (width - icon_width)/2,
|
rect.x + (width - icon_width)/2,
|
||||||
allocation.y + (height - icon_height)/2);
|
rect.y + (height - icon_height)/2);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
cairo_surface_destroy(icon_surface);
|
cairo_surface_destroy(icon_surface);
|
||||||
g_object_unref(icon_pixbuf);
|
g_object_unref(icon_pixbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cairo_destroy(cr);
|
cairo_destroy(cr);
|
||||||
cairo_surface_destroy(cr_surface);
|
cairo_surface_destroy(cr_surface);
|
||||||
|
|
@ -1323,6 +1317,62 @@ csd_gtk_update_and_render(void){
|
||||||
csd_subsurface_set_position(subsurface, 0, -window->csd_frame.border[1][0]);
|
csd_subsurface_set_position(subsurface, 0, -window->csd_frame.border[1][0]);
|
||||||
csd_subsurface_commit(subsurface);
|
csd_subsurface_commit(subsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* process events */
|
||||||
|
if (ctx.has_event){
|
||||||
|
|
||||||
|
/* handle left-button press */
|
||||||
|
if (ctx.event_button == BTN_LEFT &&
|
||||||
|
ctx.event_button_state == 1){
|
||||||
|
switch (cursor_loc){
|
||||||
|
default: case LOCATION_NULL: break;
|
||||||
|
|
||||||
|
case LOCATION_SHADOW: {
|
||||||
|
static const enum xdg_toplevel_resize_edge xedge_box[] = {
|
||||||
|
XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP, XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT,
|
||||||
|
XDG_TOPLEVEL_RESIZE_EDGE_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_NONE, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT,
|
||||||
|
XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT,
|
||||||
|
};
|
||||||
|
xdg_toplevel_resize(window->main_xdg_toplevel, seat->wl_seat,
|
||||||
|
seat->serial, xedge_box[4 + cursor_shadow_loc]);
|
||||||
|
ctx.has_event = 0;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case LOCATION_TITLEBAR: {
|
||||||
|
if (header_button_hover == 0){
|
||||||
|
xdg_toplevel_move(window->main_xdg_toplevel, seat->wl_seat, seat->serial);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
gtk_window->active_header_button = header_button_hover;
|
||||||
|
}
|
||||||
|
ctx.has_event = 0;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle left-button release */
|
||||||
|
if (ctx.event_button == BTN_LEFT &&
|
||||||
|
ctx.event_button_state == 0){
|
||||||
|
if (gtk_window->active_header_button != 0 &&
|
||||||
|
gtk_window->active_header_button == header_button_hover){
|
||||||
|
// activate button effect here
|
||||||
|
}
|
||||||
|
gtk_window->active_header_button = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set cursor shape */
|
||||||
|
if (window->control_flags & CSD_WindowControlFlag_Resize){
|
||||||
|
static const CSD_CursorShape cursor_box[] = {
|
||||||
|
CSD_CursorShape_Resize_TopLeft, CSD_CursorShape_Resize_Top, CSD_CursorShape_Resize_TopRight,
|
||||||
|
CSD_CursorShape_Resize_Left, CSD_CursorShape_Pointer, CSD_CursorShape_Resize_Right,
|
||||||
|
CSD_CursorShape_Resize_BottomLeft, CSD_CursorShape_Resize_Bottom, CSD_CursorShape_Resize_BottomRight,
|
||||||
|
};
|
||||||
|
seat->cursor_shape = cursor_box[4 + cursor_shadow_loc];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
seat->cursor_shape = CSD_CursorShape_Pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cairo shadow rendering */
|
/* cairo shadow rendering */
|
||||||
|
|
|
||||||
|
|
@ -167,16 +167,14 @@ typedef struct CSD_GTK_Ctx{
|
||||||
} CSD_GTK_Ctx;
|
} CSD_GTK_Ctx;
|
||||||
|
|
||||||
typedef struct CSD_GTK_Window{
|
typedef struct CSD_GTK_Window{
|
||||||
CSD_S32 double_click_time_ms;
|
|
||||||
|
|
||||||
CSD_SubSurface titlebar;
|
CSD_SubSurface titlebar;
|
||||||
CSD_SubSurface shadow;
|
CSD_SubSurface shadow;
|
||||||
|
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *header;
|
GtkWidget *header;
|
||||||
|
|
||||||
CSD_U32 hover_button_code;
|
CSD_S32 double_click_time_ms;
|
||||||
CSD_U32 active_button_code;
|
CSD_U32 active_header_button;
|
||||||
} CSD_GTK_Window;
|
} CSD_GTK_Window;
|
||||||
|
|
||||||
/* csd gtk implementation */
|
/* csd gtk implementation */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue