xref: /OK3568_Linux_fs/debian/packages-patches/openbox/3.6.1-8/0002-Support-outline-moving.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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