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_GTK_Window *gtk_window = &ctx.gtk_window;
|
||||
|
||||
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,
|
||||
/* determine cursor location information */
|
||||
enum{
|
||||
LOCATION_NULL, LOCATION_SHADOW, LOCATION_TITLEBAR,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
CSD_U32 cursor_loc = LOCATION_NULL;
|
||||
CSD_S32 cursor_shadow_loc = 0;
|
||||
{
|
||||
{
|
||||
CSD_S32 l = (seat->hover_p[0] < 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 b = (!t && seat->hover_p[1] >= window->dim[1]);
|
||||
CSD_S32 loc = 3*(b - t) + (r - l);
|
||||
seat->cursor_shape = cursor_box[4 + loc];
|
||||
if (ctx.has_event &&
|
||||
ctx.event_button == BTN_LEFT &&
|
||||
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]);
|
||||
cursor_shadow_loc = 3*(b - t) + (r - l);
|
||||
}
|
||||
if (cursor_shadow_loc != 0){
|
||||
cursor_loc = LOCATION_SHADOW;
|
||||
}
|
||||
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;
|
||||
|
||||
|
|
@ -1108,6 +1098,26 @@ csd_gtk_update_and_render(void){
|
|||
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;
|
||||
|
||||
|
|
@ -1153,7 +1163,7 @@ csd_gtk_update_and_render(void){
|
|||
cairo_t *cr = cairo_create(cr_surface);
|
||||
cairo_surface_set_device_scale(cr_surface, 1, 1);
|
||||
|
||||
/* background */
|
||||
/* draw background */
|
||||
{
|
||||
GtkAllocation 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);
|
||||
}
|
||||
|
||||
/* title */
|
||||
/* draw title */
|
||||
{
|
||||
GtkWidget *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);
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
CSD_U32 buttons[3] = {0};
|
||||
int button_count = 0;
|
||||
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 = "";
|
||||
/* draw buttons */
|
||||
for (CSD_U32 i = 1; i < HEADER_BUTTON_COUNT; i += 1){
|
||||
if (header_button_active[i]){
|
||||
char *icon_name = "";
|
||||
switch (button_code){
|
||||
case 0: {
|
||||
button_name = ".minimize";
|
||||
switch (i){
|
||||
case HEADER_BUTTON_MIN: {
|
||||
icon_name = "window-minimize-symbolic";
|
||||
}break;
|
||||
case 1: {
|
||||
button_name = ".maximize";
|
||||
case HEADER_BUTTON_MAX: {
|
||||
icon_name = ((window->config.flags & CSD_WindowFlag_IsMax) ?
|
||||
"window-restore-symbolic" : "window-maximize-symbolic");
|
||||
}break;
|
||||
case 2: {
|
||||
button_name = ".close";
|
||||
case HEADER_BUTTON_CLOSE: {
|
||||
icon_name = "window-close-symbolic";
|
||||
}break;
|
||||
}
|
||||
|
||||
GtkWidget *button_widget =
|
||||
csd_gtk__widget_from_name(gtk_window->header, button_name);
|
||||
GtkWidget *widget =
|
||||
csd_gtk__widget_from_name(gtk_window->header, header_button_name[i]);
|
||||
|
||||
if (button_widget != 0){
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(button_widget);
|
||||
if (widget != 0){
|
||||
/* 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 */
|
||||
GtkStyleContext *style = gtk_widget_get_style_context(widget);
|
||||
GtkStateFlags style_state = 0;
|
||||
if (!(window->config.flags & CSD_WindowFlag_IsActivated)){
|
||||
style_state |= GTK_STATE_FLAG_BACKDROP;
|
||||
}
|
||||
if (gtk_window->hover_button_code == button_code){
|
||||
if (is_hovered){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* background */
|
||||
GtkAllocation allocation;
|
||||
gtk_widget_get_clip(button_widget, &allocation);
|
||||
|
||||
gtk_style_context_save(style);
|
||||
gtk_style_context_set_state(style, style_state);
|
||||
gtk_render_background(style, cr, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
gtk_render_frame(style, cr, allocation.x, allocation.y,
|
||||
allocation.width, allocation.height);
|
||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_style_context_restore(style);
|
||||
|
||||
/* get scale */
|
||||
|
|
@ -1255,7 +1256,7 @@ csd_gtk_update_and_render(void){
|
|||
int scale = (sx + sy)/2.0;
|
||||
|
||||
/* 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 */
|
||||
gint icon_width, icon_height;
|
||||
|
|
@ -1284,37 +1285,30 @@ csd_gtk_update_and_render(void){
|
|||
width = CSD_ClampBot(width, icon_width);
|
||||
height = CSD_ClampBot(height, icon_height);
|
||||
|
||||
gint left = 0;
|
||||
gint top = 0;
|
||||
gint right = 0;
|
||||
gint bottom = 0;
|
||||
|
||||
GtkBorder 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;
|
||||
gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding);
|
||||
left += padding.left;
|
||||
right += padding.right;
|
||||
top += padding.top;
|
||||
bottom += padding.bottom;
|
||||
|
||||
gint left = border.left + padding.left;
|
||||
gint right = border.right + padding.right;
|
||||
gint top = border.top + padding.top;
|
||||
gint bottom = border.bottom + padding.bottom;
|
||||
|
||||
width += left + right;
|
||||
height += top + bottom;
|
||||
|
||||
gtk_render_icon_surface(gtk_widget_get_style_context(icon_widget),
|
||||
cr, icon_surface,
|
||||
allocation.x + (width - icon_width)/2,
|
||||
allocation.y + (height - icon_height)/2);
|
||||
rect.x + (width - icon_width)/2,
|
||||
rect.y + (height - icon_height)/2);
|
||||
cairo_paint(cr);
|
||||
cairo_surface_destroy(icon_surface);
|
||||
g_object_unref(icon_pixbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cairo_destroy(cr);
|
||||
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_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 */
|
||||
|
|
|
|||
|
|
@ -167,16 +167,14 @@ typedef struct CSD_GTK_Ctx{
|
|||
} CSD_GTK_Ctx;
|
||||
|
||||
typedef struct CSD_GTK_Window{
|
||||
CSD_S32 double_click_time_ms;
|
||||
|
||||
CSD_SubSurface titlebar;
|
||||
CSD_SubSurface shadow;
|
||||
|
||||
GtkWidget *window;
|
||||
GtkWidget *header;
|
||||
|
||||
CSD_U32 hover_button_code;
|
||||
CSD_U32 active_button_code;
|
||||
CSD_S32 double_click_time_ms;
|
||||
CSD_U32 active_header_button;
|
||||
} CSD_GTK_Window;
|
||||
|
||||
/* csd gtk implementation */
|
||||
|
|
|
|||
Loading…
Reference in New Issue