From 116130994b622a6f02f237d95493afb0f4b28a18 Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
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.
|
<drawContents>no</drawContents> to enable outline moving.
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
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
|