From 116130994b622a6f02f237d95493afb0f4b28a18 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Mon, 8 Jul 2019 14:50:37 +0800 Subject: [PATCH 2/3] Support outline moving Set "drawContents" to no in the rc.xml's resize section, eg. no to enable outline moving. Signed-off-by: Jeffy Chen --- openbox/client.c | 2 +- openbox/config.c | 8 ++- openbox/focus_cycle_popup.c | 4 ++ openbox/moveresize.c | 109 ++++++++++++++++++++++++++++++++---- openbox/moveresize.h | 2 + openbox/popup.c | 5 ++ 6 files changed, 116 insertions(+), 14 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index f110a66e..8b405d1b 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3220,7 +3220,7 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, } /* adjust the frame */ - if (fmoved || fresized) { + if (final || fmoved || fresized) { gulong ignore_start; if (!user) ignore_start = event_start_ignore_all_enters(); diff --git a/openbox/config.c b/openbox/config.c index d5129bc6..5f126258 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -834,7 +834,13 @@ static void parse_resize(xmlNodePtr node, gpointer d) else if (obt_xml_node_contains(n, "Nonpixel")) config_resize_popup_show = 1; } - if ((n = obt_xml_find_node(node, "popupPosition"))) { + + if (!config_resize_redraw) { + /* Put popup center in outline moving mode */ + config_resize_popup_pos = OB_RESIZE_POS_FIXED; + config_resize_popup_fixed.x.center = TRUE; + config_resize_popup_fixed.y.center = TRUE; + } else if ((n = obt_xml_find_node(node, "popupPosition"))) { if (obt_xml_node_contains(n, "Top")) config_resize_popup_pos = OB_RESIZE_POS_TOP; else if (obt_xml_node_contains(n, "Center")) diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index e1ea8488..de6c3082 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -421,6 +421,8 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) g_assert(mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS || mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST); + moveresize_clear_outline(); + screen_area = screen_physical_area_primary(FALSE); /* get the outside margins */ @@ -737,6 +739,8 @@ void focus_cycle_popup_hide(void) { gulong ignore_start; + moveresize_clear_outline(); + ignore_start = event_start_ignore_all_enters(); XUnmapWindow(obt_display, popup.bg); diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 0a301caf..1db4726c 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -71,6 +71,12 @@ static guint sync_timer = 0; static glong last_move_time = 0; static guint move_timer = 0; +static GC outline_gc = NULL; +static gint outline_x = 0; +static gint outline_y = 0; +static gint outline_w = 0; +static gint outline_h = 0; + static ObPopup *popup = NULL; static void do_move(gboolean keyboard, gint keydist); @@ -333,6 +339,8 @@ void moveresize_end(gboolean cancel) } else { if (move_timer) g_source_remove(move_timer); move_timer = 0; + + moveresize_clear_outline(); } /* don't use client_move() here, use the same width/height as @@ -375,11 +383,94 @@ void moveresize_end(gboolean cancel) moveresize_client = NULL; } -static gboolean move_func(gpointer data) +static void draw_outline(gint x, gint y, gint w, gint h) +{ + if (!outline_gc) { + /* Start outline moving */ + XGCValues gcv; + + gcv.function = GXinvert; + gcv.line_width = 2; + gcv.subwindow_mode = IncludeInferiors; + + outline_gc = XCreateGC(obt_display, obt_root(ob_screen), + GCFunction | GCLineWidth | GCSubwindowMode, + &gcv); + + grab_server(TRUE); + } + + if (outline_w || outline_h) + XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, + outline_x, outline_y, outline_w, outline_h); + + outline_x = x; + outline_y = y; + outline_w = w; + outline_h = h; + + if (outline_w || outline_h) + XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, + outline_x, outline_y, outline_w, outline_h); +} + +void moveresize_clear_outline(void) { - client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, - TRUE, FALSE, FALSE); + if (!outline_gc) + return; + + XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, + outline_x, outline_y, outline_w, outline_h); + + outline_x = outline_y = outline_w = outline_h = 0; + + /* Finish outline moving */ + grab_server(FALSE); + XFreeGC(obt_display, outline_gc); + outline_gc = NULL; +} + +static void do_move_func(void) +{ + gint x, y, w, h, lw, lh; + + /* The opaque moving mode */ + if (config_resize_redraw) { + client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, + TRUE, FALSE, FALSE); + + if (config_resize_popup_show == 2) /* == "Always" */ + popup_coords(moveresize_client, "%d x %d", + moveresize_client->frame->area.x, + moveresize_client->frame->area.y); + + return; + } + + /* Draw outline at new frame area */ + x = cur_x; + y = cur_y; + w = cur_w; + h = cur_h; + client_try_configure(moveresize_client, &x, &y, &w, &h, + &lw, &lh, TRUE); + + draw_outline(x, y, moveresize_client->frame->area.width, + moveresize_client->frame->area.height); + + /* Draw popup above outline */ + if (config_resize_popup_show == 2) /* == "Always" */ { + /* Hacky way to avoid outline clear */ + GC gc = outline_gc; + outline_gc = NULL; + popup_coords(moveresize_client, "%d x %d", x, y); + outline_gc = gc; + } +} +static gboolean move_func(gpointer data) +{ + do_move_func(); move_timer = 0; return FALSE; /* don't repeat */ } @@ -394,9 +485,9 @@ static void do_move(gboolean keyboard, gint keydist) if (!keyboard) resist = config_resist_edge; resist_move_monitors(moveresize_client, resist, &cur_x, &cur_y); + config_move_interval = 16; if (!config_move_interval) { - client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, - TRUE, FALSE, FALSE); + do_move_func(); } else if (!move_timer) { GTimeVal curr_tm; glong now_ms, next_ms; @@ -406,19 +497,13 @@ static void do_move(gboolean keyboard, gint keydist) next_ms = last_move_time + config_move_interval; if (next_ms <= now_ms) { - client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, - TRUE, FALSE, FALSE); + do_move_func(); last_move_time = now_ms; } else { move_timer = g_timeout_add(config_move_interval, move_func, NULL); last_move_time = next_ms; } } - - if (config_resize_popup_show == 2) /* == "Always" */ - popup_coords(moveresize_client, "%d x %d", - moveresize_client->frame->area.x, - moveresize_client->frame->area.y); } static void do_resize(void) diff --git a/openbox/moveresize.h b/openbox/moveresize.h index 2d0f7dce..87b4b7c8 100644 --- a/openbox/moveresize.h +++ b/openbox/moveresize.h @@ -49,4 +49,6 @@ void moveresize_end(gboolean cancel); gboolean moveresize_event(XEvent *e); +void moveresize_clear_outline(void); + #endif diff --git a/openbox/popup.c b/openbox/popup.c index 5ecf2fa5..fc219ead 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -25,6 +25,7 @@ #include "stacking.h" #include "event.h" #include "screen.h" +#include "moveresize.h" #include "obrender/render.h" #include "obrender/theme.h" @@ -163,6 +164,8 @@ void popup_delay_show(ObPopup *self, gulong msec, gchar *text) Rect mon; gboolean hasicon = self->hasicon; + moveresize_clear_outline(); + /* when there is no icon and the text is not parent relative, then fill the whole dialog with the text appearance, don't use the bg at all */ @@ -317,6 +320,8 @@ void popup_hide(ObPopup *self) if (self->mapped) { gulong ignore_start; + moveresize_clear_outline(); + /* kill enter events cause by this unmapping */ ignore_start = event_start_ignore_all_enters(); -- 2.17.1