1From 116130994b622a6f02f237d95493afb0f4b28a18 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Mon, 8 Jul 2019 14:50:37 +0800 4Subject: [PATCH 2/3] Support outline moving 5 6Set "drawContents" to no in the rc.xml's resize section, eg. 7<drawContents>no</drawContents> to enable outline moving. 8 9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 10--- 11 openbox/client.c | 2 +- 12 openbox/config.c | 8 ++- 13 openbox/focus_cycle_popup.c | 4 ++ 14 openbox/moveresize.c | 109 ++++++++++++++++++++++++++++++++---- 15 openbox/moveresize.h | 2 + 16 openbox/popup.c | 5 ++ 17 6 files changed, 116 insertions(+), 14 deletions(-) 18 19diff --git a/openbox/client.c b/openbox/client.c 20index f110a66e..8b405d1b 100644 21--- a/openbox/client.c 22+++ b/openbox/client.c 23@@ -3220,7 +3220,7 @@ void client_configure(ObClient *self, gint x, gint y, gint w, gint h, 24 } 25 26 /* adjust the frame */ 27- if (fmoved || fresized) { 28+ if (final || fmoved || fresized) { 29 gulong ignore_start; 30 if (!user) 31 ignore_start = event_start_ignore_all_enters(); 32diff --git a/openbox/config.c b/openbox/config.c 33index d5129bc6..5f126258 100644 34--- a/openbox/config.c 35+++ b/openbox/config.c 36@@ -834,7 +834,13 @@ static void parse_resize(xmlNodePtr node, gpointer d) 37 else if (obt_xml_node_contains(n, "Nonpixel")) 38 config_resize_popup_show = 1; 39 } 40- if ((n = obt_xml_find_node(node, "popupPosition"))) { 41+ 42+ if (!config_resize_redraw) { 43+ /* Put popup center in outline moving mode */ 44+ config_resize_popup_pos = OB_RESIZE_POS_FIXED; 45+ config_resize_popup_fixed.x.center = TRUE; 46+ config_resize_popup_fixed.y.center = TRUE; 47+ } else if ((n = obt_xml_find_node(node, "popupPosition"))) { 48 if (obt_xml_node_contains(n, "Top")) 49 config_resize_popup_pos = OB_RESIZE_POS_TOP; 50 else if (obt_xml_node_contains(n, "Center")) 51diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c 52index e1ea8488..de6c3082 100644 53--- a/openbox/focus_cycle_popup.c 54+++ b/openbox/focus_cycle_popup.c 55@@ -421,6 +421,8 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) 56 g_assert(mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS || 57 mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST); 58 59+ moveresize_clear_outline(); 60+ 61 screen_area = screen_physical_area_primary(FALSE); 62 63 /* get the outside margins */ 64@@ -737,6 +739,8 @@ void focus_cycle_popup_hide(void) 65 { 66 gulong ignore_start; 67 68+ moveresize_clear_outline(); 69+ 70 ignore_start = event_start_ignore_all_enters(); 71 72 XUnmapWindow(obt_display, popup.bg); 73diff --git a/openbox/moveresize.c b/openbox/moveresize.c 74index 0a301caf..1db4726c 100644 75--- a/openbox/moveresize.c 76+++ b/openbox/moveresize.c 77@@ -71,6 +71,12 @@ static guint sync_timer = 0; 78 static glong last_move_time = 0; 79 static guint move_timer = 0; 80 81+static GC outline_gc = NULL; 82+static gint outline_x = 0; 83+static gint outline_y = 0; 84+static gint outline_w = 0; 85+static gint outline_h = 0; 86+ 87 static ObPopup *popup = NULL; 88 89 static void do_move(gboolean keyboard, gint keydist); 90@@ -333,6 +339,8 @@ void moveresize_end(gboolean cancel) 91 } else { 92 if (move_timer) g_source_remove(move_timer); 93 move_timer = 0; 94+ 95+ moveresize_clear_outline(); 96 } 97 98 /* don't use client_move() here, use the same width/height as 99@@ -375,11 +383,94 @@ void moveresize_end(gboolean cancel) 100 moveresize_client = NULL; 101 } 102 103-static gboolean move_func(gpointer data) 104+static void draw_outline(gint x, gint y, gint w, gint h) 105+{ 106+ if (!outline_gc) { 107+ /* Start outline moving */ 108+ XGCValues gcv; 109+ 110+ gcv.function = GXinvert; 111+ gcv.line_width = 2; 112+ gcv.subwindow_mode = IncludeInferiors; 113+ 114+ outline_gc = XCreateGC(obt_display, obt_root(ob_screen), 115+ GCFunction | GCLineWidth | GCSubwindowMode, 116+ &gcv); 117+ 118+ grab_server(TRUE); 119+ } 120+ 121+ if (outline_w || outline_h) 122+ XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, 123+ outline_x, outline_y, outline_w, outline_h); 124+ 125+ outline_x = x; 126+ outline_y = y; 127+ outline_w = w; 128+ outline_h = h; 129+ 130+ if (outline_w || outline_h) 131+ XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, 132+ outline_x, outline_y, outline_w, outline_h); 133+} 134+ 135+void moveresize_clear_outline(void) 136 { 137- client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, 138- TRUE, FALSE, FALSE); 139+ if (!outline_gc) 140+ return; 141+ 142+ XDrawRectangle(obt_display, obt_root(ob_screen), outline_gc, 143+ outline_x, outline_y, outline_w, outline_h); 144+ 145+ outline_x = outline_y = outline_w = outline_h = 0; 146+ 147+ /* Finish outline moving */ 148+ grab_server(FALSE); 149+ XFreeGC(obt_display, outline_gc); 150+ outline_gc = NULL; 151+} 152+ 153+static void do_move_func(void) 154+{ 155+ gint x, y, w, h, lw, lh; 156+ 157+ /* The opaque moving mode */ 158+ if (config_resize_redraw) { 159+ client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, 160+ TRUE, FALSE, FALSE); 161+ 162+ if (config_resize_popup_show == 2) /* == "Always" */ 163+ popup_coords(moveresize_client, "%d x %d", 164+ moveresize_client->frame->area.x, 165+ moveresize_client->frame->area.y); 166+ 167+ return; 168+ } 169+ 170+ /* Draw outline at new frame area */ 171+ x = cur_x; 172+ y = cur_y; 173+ w = cur_w; 174+ h = cur_h; 175+ client_try_configure(moveresize_client, &x, &y, &w, &h, 176+ &lw, &lh, TRUE); 177+ 178+ draw_outline(x, y, moveresize_client->frame->area.width, 179+ moveresize_client->frame->area.height); 180+ 181+ /* Draw popup above outline */ 182+ if (config_resize_popup_show == 2) /* == "Always" */ { 183+ /* Hacky way to avoid outline clear */ 184+ GC gc = outline_gc; 185+ outline_gc = NULL; 186+ popup_coords(moveresize_client, "%d x %d", x, y); 187+ outline_gc = gc; 188+ } 189+} 190 191+static gboolean move_func(gpointer data) 192+{ 193+ do_move_func(); 194 move_timer = 0; 195 return FALSE; /* don't repeat */ 196 } 197@@ -394,9 +485,9 @@ static void do_move(gboolean keyboard, gint keydist) 198 if (!keyboard) resist = config_resist_edge; 199 resist_move_monitors(moveresize_client, resist, &cur_x, &cur_y); 200 201+ config_move_interval = 16; 202 if (!config_move_interval) { 203- client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, 204- TRUE, FALSE, FALSE); 205+ do_move_func(); 206 } else if (!move_timer) { 207 GTimeVal curr_tm; 208 glong now_ms, next_ms; 209@@ -406,19 +497,13 @@ static void do_move(gboolean keyboard, gint keydist) 210 next_ms = last_move_time + config_move_interval; 211 212 if (next_ms <= now_ms) { 213- client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h, 214- TRUE, FALSE, FALSE); 215+ do_move_func(); 216 last_move_time = now_ms; 217 } else { 218 move_timer = g_timeout_add(config_move_interval, move_func, NULL); 219 last_move_time = next_ms; 220 } 221 } 222- 223- if (config_resize_popup_show == 2) /* == "Always" */ 224- popup_coords(moveresize_client, "%d x %d", 225- moveresize_client->frame->area.x, 226- moveresize_client->frame->area.y); 227 } 228 229 static void do_resize(void) 230diff --git a/openbox/moveresize.h b/openbox/moveresize.h 231index 2d0f7dce..87b4b7c8 100644 232--- a/openbox/moveresize.h 233+++ b/openbox/moveresize.h 234@@ -49,4 +49,6 @@ void moveresize_end(gboolean cancel); 235 236 gboolean moveresize_event(XEvent *e); 237 238+void moveresize_clear_outline(void); 239+ 240 #endif 241diff --git a/openbox/popup.c b/openbox/popup.c 242index 5ecf2fa5..fc219ead 100644 243--- a/openbox/popup.c 244+++ b/openbox/popup.c 245@@ -25,6 +25,7 @@ 246 #include "stacking.h" 247 #include "event.h" 248 #include "screen.h" 249+#include "moveresize.h" 250 #include "obrender/render.h" 251 #include "obrender/theme.h" 252 253@@ -163,6 +164,8 @@ void popup_delay_show(ObPopup *self, gulong msec, gchar *text) 254 Rect mon; 255 gboolean hasicon = self->hasicon; 256 257+ moveresize_clear_outline(); 258+ 259 /* when there is no icon and the text is not parent relative, then 260 fill the whole dialog with the text appearance, don't use the bg at all 261 */ 262@@ -317,6 +320,8 @@ void popup_hide(ObPopup *self) 263 if (self->mapped) { 264 gulong ignore_start; 265 266+ moveresize_clear_outline(); 267+ 268 /* kill enter events cause by this unmapping */ 269 ignore_start = event_start_ignore_all_enters(); 270 271-- 2722.17.1 273 274