[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/pgtk fbba846 017/100: Addframe highlighting support
From: |
Yuuki Harano |
Subject: |
feature/pgtk fbba846 017/100: Addframe highlighting support |
Date: |
Tue, 24 Nov 2020 08:02:27 -0500 (EST) |
branch: feature/pgtk
commit fbba846ee8d63304385b59e8f6a553398b533345
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Jeff Walsh <fejfighter@gmail.com>
Addframe highlighting support
* ../src/pgtkterm.c:
(pgtk_focus_frame, set_opacity_recursively, x_set_frame_alpha)
(frame_highlight, frame_unhighlight, pgtk_frame_rehighlight)
(XTframe_rehighlight, x_new_focus_frame, pgtk_create_terminal):
frame の highlight に対応。
とりあえず opacity のみ対応。
---
src/pgtkterm.c | 316 +++++++++++++++++++++++++++++++++------------------------
src/pgtkterm.h | 1 +
2 files changed, 187 insertions(+), 130 deletions(-)
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index fb25206..1c2f0c9 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -4351,6 +4351,190 @@ pgtk_free_pixmap (struct frame *_f, Emacs_Pixmap pixmap)
}
}
+void
+pgtk_focus_frame (struct frame *f, bool noactivate)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+
+ GtkWidget *wid = FRAME_GTK_OUTER_WIDGET(f);
+
+ if (dpyinfo->x_focus_frame != f)
+ {
+ block_input ();
+ gtk_window_present (GTK_WINDOW (wid));
+ unblock_input ();
+ }
+}
+
+
+static void set_opacity_recursively (GtkWidget *w, gpointer data)
+{
+ gtk_widget_set_opacity (w, *(double *) data);
+ if (GTK_IS_CONTAINER (w))
+ gtk_container_foreach (GTK_CONTAINER (w), set_opacity_recursively, data);
+}
+
+static void
+x_set_frame_alpha (struct frame *f)
+{
+ struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+ double alpha = 1.0;
+ double alpha_min = 1.0;
+
+ if (dpyinfo->highlight_frame == f)
+ alpha = f->alpha[0];
+ else
+ alpha = f->alpha[1];
+
+ if (alpha < 0.0)
+ return;
+
+ if (FLOATP (Vframe_alpha_lower_limit))
+ alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+ else if (FIXNUMP (Vframe_alpha_lower_limit))
+ alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0;
+
+ if (alpha > 1.0)
+ alpha = 1.0;
+ else if (alpha < alpha_min && alpha_min <= 1.0)
+ alpha = alpha_min;
+
+#if 0
+ /* If there is a parent from the window manager, put the property there
+ also, to work around broken window managers that fail to do that.
+ Do this unconditionally as this function is called on reparent when
+ alpha has not changed on the frame. */
+
+ if (!FRAME_PARENT_FRAME (f))
+ {
+ Window parent = x_find_topmost_parent (f);
+ if (parent != None)
+ XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &opac, 1);
+ }
+#endif
+
+ set_opacity_recursively (FRAME_GTK_OUTER_WIDGET (f), &alpha);
+ /* without this, blending mode is strange on wayland. */
+ gtk_widget_queue_resize_no_redraw (FRAME_GTK_OUTER_WIDGET (f));
+}
+
+static void
+frame_highlight (struct frame *f)
+{
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ block_input ();
+ /* I recently started to get errors in this XSetWindowBorder, depending on
+ the window-manager in use, tho something more is at play since I've been
+ using that same window-manager binary for ever. Let's not crash just
+ because of this (bug#9310). */
+#if 0
+ x_catch_errors (FRAME_X_DISPLAY (f));
+ XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ FRAME_X_OUTPUT(f)->border_pixel);
+ x_uncatch_errors ();
+#endif
+ unblock_input ();
+ gui_update_cursor (f, true);
+ x_set_frame_alpha (f);
+}
+
+static void
+frame_unhighlight (struct frame *f)
+{
+ /* We used to only do this if Vx_no_window_manager was non-nil, but
+ the ICCCM (section 4.1.6) says that the window's border pixmap
+ and border pixel are window attributes which are "private to the
+ client", so we can always change it to whatever we want. */
+ block_input ();
+ /* Same as above for XSetWindowBorder (bug#9310). */
+#if 0
+ x_catch_errors (FRAME_X_DISPLAY (f));
+ XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ FRAME_X_OUTPUT(f)->border_tile);
+ x_uncatch_errors ();
+#endif
+ unblock_input ();
+ gui_update_cursor (f, true);
+ x_set_frame_alpha (f);
+}
+
+
+static void
+pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo)
+{
+ struct frame *old_highlight = dpyinfo->highlight_frame;
+
+ if (dpyinfo->x_focus_frame)
+ {
+ dpyinfo->highlight_frame
+ = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
+ ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
+ : dpyinfo->x_focus_frame);
+ if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
+ {
+ fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
+ dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
+ }
+ }
+ else
+ dpyinfo->highlight_frame = 0;
+
+ if (dpyinfo->highlight_frame != old_highlight)
+ {
+ if (old_highlight)
+ frame_unhighlight (old_highlight);
+ if (dpyinfo->highlight_frame)
+ frame_highlight (dpyinfo->highlight_frame);
+ }
+}
+
+/* The focus has changed, or we have redirected a frame's focus to
+ another frame (this happens when a frame uses a surrogate
+ mini-buffer frame). Shift the highlight as appropriate.
+
+ The FRAME argument doesn't necessarily have anything to do with which
+ frame is being highlighted or un-highlighted; we only use it to find
+ the appropriate X display info. */
+
+static void
+XTframe_rehighlight (struct frame *frame)
+{
+ pgtk_frame_rehighlight (FRAME_DISPLAY_INFO (frame));
+}
+
+/* The focus has changed. Update the frames as necessary to reflect
+ the new situation. Note that we can't change the selected frame
+ here, because the Lisp code we are interrupting might become confused.
+ Each event gets marked with the frame in which it occurred, so the
+ Lisp code can tell when the switch took place by examining the events. */
+
+static void
+x_new_focus_frame (struct pgtk_display_info *dpyinfo, struct frame *frame)
+{
+ struct frame *old_focus = dpyinfo->x_focus_frame;
+ /* doesn't work on wayland */
+
+ if (frame != dpyinfo->x_focus_frame)
+ {
+ /* Set this before calling other routines, so that they see
+ the correct value of x_focus_frame. */
+ dpyinfo->x_focus_frame = frame;
+
+ if (old_focus && old_focus->auto_lower)
+ gdk_window_lower (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET
(old_focus)));
+
+ if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
+ gdk_window_raise (gtk_widget_get_window (FRAME_GTK_OUTER_WIDGET
(dpyinfo->x_focus_frame)));
+ }
+
+ pgtk_frame_rehighlight (dpyinfo);
+}
+
static struct terminal *
pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
/* --------------------------------------------------------------------------
@@ -4371,7 +4555,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
terminal->read_socket_hook = pgtk_read_socket;
// terminal->frame_up_to_date_hook = pgtk_frame_up_to_date;
terminal->mouse_position_hook = pgtk_mouse_position;
- // terminal->frame_rehighlight_hook = pgtk_frame_rehighlight;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
// terminal->frame_raise_lower_hook = pgtk_frame_raise_lower;
terminal->frame_visible_invisible_hook = pgtk_make_frame_visible_invisible;
terminal->fullscreen_hook = pgtk_fullscreen_hook;
@@ -5095,132 +5279,6 @@ static gboolean delete_event(GtkWidget *widget,
GdkEvent *event, gpointer *user_
return TRUE;
}
-void
-pgtk_focus_frame (struct frame *f, bool noactivate)
-{
- struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
-
- GtkWidget *wid = FRAME_GTK_OUTER_WIDGET(f);
-
- if (dpyinfo->x_focus_frame != f)
- {
- block_input ();
- gtk_window_present (GTK_WINDOW (wid));
- unblock_input ();
- }
-}
-
-
-static void
-frame_highlight (struct frame *f)
-{
- /* We used to only do this if Vx_no_window_manager was non-nil, but
- the ICCCM (section 4.1.6) says that the window's border pixmap
- and border pixel are window attributes which are "private to the
- client", so we can always change it to whatever we want. */
- block_input ();
- /* I recently started to get errors in this XSetWindowBorder, depending on
- the window-manager in use, tho something more is at play since I've been
- using that same window-manager binary for ever. Let's not crash just
- because of this (bug#9310). */
-#if 0
- x_catch_errors (FRAME_X_DISPLAY (f));
- XSetWindowBorder (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- FRAME_X_OUTPUT(f)->border_pixel);
- x_uncatch_errors ();
-#endif
- unblock_input ();
- gui_update_cursor (f, true);
-#if 0
- x_set_frame_alpha (f);
-#endif
-}
-
-static void
-frame_unhighlight (struct frame *f)
-{
- /* We used to only do this if Vx_no_window_manager was non-nil, but
- the ICCCM (section 4.1.6) says that the window's border pixmap
- and border pixel are window attributes which are "private to the
- client", so we can always change it to whatever we want. */
- block_input ();
- /* Same as above for XSetWindowBorder (bug#9310). */
-#if 0
- x_catch_errors (FRAME_X_DISPLAY (f));
- XSetWindowBorderPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- FRAME_X_OUTPUT(f)->border_tile);
- x_uncatch_errors ();
-#endif
- unblock_input ();
- gui_update_cursor (f, true);
-#if 0
- x_set_frame_alpha (f);
-#endif
-}
-
-
-static void
-x_frame_rehighlight (struct pgtk_display_info *dpyinfo)
-{
- struct frame *old_highlight = dpyinfo->highlight_frame;
-
- if (dpyinfo->x_focus_frame)
- {
- dpyinfo->highlight_frame
- = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
- ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
- : dpyinfo->x_focus_frame);
- if (! FRAME_LIVE_P (dpyinfo->highlight_frame))
- {
- fset_focus_frame (dpyinfo->x_focus_frame, Qnil);
- dpyinfo->highlight_frame = dpyinfo->x_focus_frame;
- }
- }
- else
- dpyinfo->highlight_frame = 0;
-
- if (dpyinfo->highlight_frame != old_highlight)
- {
- if (old_highlight)
- frame_unhighlight (old_highlight);
- if (dpyinfo->highlight_frame)
- frame_highlight (dpyinfo->highlight_frame);
- }
-}
-
-/* The focus has changed. Update the frames as necessary to reflect
- the new situation. Note that we can't change the selected frame
- here, because the Lisp code we are interrupting might become confused.
- Each event gets marked with the frame in which it occurred, so the
- Lisp code can tell when the switch took place by examining the events. */
-
-static void
-x_new_focus_frame (struct pgtk_display_info *dpyinfo, struct frame *frame)
-{
- struct frame *old_focus = dpyinfo->x_focus_frame;
-
- if (frame != dpyinfo->x_focus_frame)
- {
- /* Set this before calling other routines, so that they see
- the correct value of x_focus_frame. */
- dpyinfo->x_focus_frame = frame;
-
-#if 0
- if (old_focus && old_focus->auto_lower)
- x_lower_frame (old_focus);
-#endif
-
-#if 0
- if (dpyinfo->x_focus_frame && dpyinfo->x_focus_frame->auto_raise)
- dpyinfo->x_pending_autoraise_frame = dpyinfo->x_focus_frame;
- else
- dpyinfo->x_pending_autoraise_frame = NULL;
-#endif
- }
-
- x_frame_rehighlight (dpyinfo);
-}
-
/* The focus may have changed. Figure out if it is a real focus change,
by checking both FocusIn/Out and Enter/LeaveNotify events.
@@ -5269,10 +5327,8 @@ x_focus_changed (gboolean is_enter, int state, struct
pgtk_display_info *dpyinfo
XSETFRAME (bufp->ie.frame_or_window, frame);
}
-#if 0
if (frame->pointer_invisible)
- XTtoggle_invisible_pointer (frame, false);
-#endif
+ XTtoggle_invisible_pointer (frame, false);
}
}
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 4b58507..91990b2 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -579,5 +579,6 @@ extern void pgtk_set_scroll_bar_default_width (struct frame
*f);
extern void pgtk_set_scroll_bar_default_height (struct frame *f);
extern Lisp_Object x_get_focus_frame (struct frame *frame);
+extern void pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo);
#endif /* HAVE_PGTK */
- branch feature/pgtk created (now d6ef9af), Yuuki Harano, 2020/11/24
- feature/pgtk 1b621c8 004/100: Don't mark name_list_element as it's not required, Yuuki Harano, 2020/11/24
- feature/pgtk 526f727 036/100: Let gtk handle scaling., Yuuki Harano, 2020/11/24
- feature/pgtk 68b99a3 021/100: Implement invisible-pointer to create blinking effect, Yuuki Harano, 2020/11/24
- feature/pgtk 53cb431 007/100: replace listn with list., Yuuki Harano, 2020/11/24
- feature/pgtk 592badc 014/100: Early toolbar improvements, Yuuki Harano, 2020/11/24
- feature/pgtk 9d9c828 025/100: TIMERFD support for PGTK, prevent calling when timerfd<0, Yuuki Harano, 2020/11/24
- feature/pgtk fbba846 017/100: Addframe highlighting support,
Yuuki Harano <=
- feature/pgtk 0056ca2 064/100: * src/pgtkterm.h: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk f761a09 065/100: * src/pgtkim.c: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 27a92f7 072/100: Add font chooser functionality, Yuuki Harano, 2020/11/24
- feature/pgtk 9752896 042/100: Bring pgtk more inline with X11-cairo builds, Yuuki Harano, 2020/11/24
- feature/pgtk 164800d 013/100: Add Preferred geometry settings, Yuuki Harano, 2020/11/24
- feature/pgtk 383ced7 071/100: Fix migrating Child frames, Yuuki Harano, 2020/11/24
- feature/pgtk 3b161dd 066/100: * src/pgtkselect.h: Change coding style, Yuuki Harano, 2020/11/24
- feature/pgtk 89cbe37 070/100: * src/keyboard.c (make_lispy_event): Fix coding style, Yuuki Harano, 2020/11/24
- feature/pgtk f6d8c59 001/100: Introduce Pure GTK3 port, Yuuki Harano, 2020/11/24
- feature/pgtk a9c8a56 006/100: Fix xdg-open handling, Yuuki Harano, 2020/11/24