#ifndef HAVE_GTK3
GtkRcStyle *style;
#endif
+ GtkWindowType type = GTK_WINDOW_TOPLEVEL;
char *title = 0;
PGTK_TRACE("xg_create_frame_widgets.");
}
else
#endif
- wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
#ifdef HAVE_PGTK
- gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK);
+ if (!NILP(f->parent_frame)){
+ type = GTK_WINDOW_POPUP;
+ }
+#endif
+
+ wtop = gtk_window_new (type);
+#ifdef HAVE_PGTK
+ gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK);
+ gtk_window_set_hide_titlebar_when_maximized(GTK_WINDOW(wtop), TRUE);
#endif
/* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu
#ifndef HAVE_PGTK
gtk_widget_realize (wfixed);
#else
- gtk_widget_show_all(wtop);
+ // gtk_widget_show_all(wtop);
#endif
#ifndef HAVE_PGTK
FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed);
sizeof (size_hints)) != 0)
{
block_input ();
-#ifndef HAVE_PGTK
gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
- NULL, &size_hints, hint_flags);
-#endif
+ NULL, &size_hints, hint_flags);
f->output_data.xp->size_hints = size_hints;
f->output_data.xp->hint_flags = hint_flags;
unblock_input ();
pgtk_set_tool_bar_position,
0, /* x_set_inhibit_double_buffering */
x_set_undecorated,
- 0, /* x_set_parent_frame, */
+ x_set_parent_frame,
x_set_skip_taskbar,
x_set_no_focus_on_map,
x_set_no_accept_focus,
gui_default_parameter (f, parms, Qalpha, Qnil,
"alpha", "Alpha", RES_TYPE_NUMBER);
-#if 0
if (!NILP (parent_frame))
{
struct frame *p = XFRAME (parent_frame);
block_input ();
- XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
- FRAME_X_WINDOW (p), f->left_pos, f->top_pos);
+ PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos);
+ gtk_window_set_transient_for(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)),
+ GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(p)));
+ gtk_window_set_attached_to(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)),
+ FRAME_GTK_WIDGET(p));
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)),
+ TRUE);
+ gtk_widget_show_all(FRAME_GTK_OUTER_WIDGET(f));
unblock_input ();
}
-#endif
+
+ gtk_widget_show_all(FRAME_GTK_OUTER_WIDGET(f));
gui_default_parameter (f, parms, Qno_focus_on_map, Qnil,
NULL, NULL, RES_TYPE_BOOLEAN);
DEFSYM (Qreverse_landscape, "reverse-landscape");
}
-#ifdef PGTK_DEBUG
+
#include <stdarg.h>
#include <time.h>
va_end(ap);
fputc('\n', stderr);
}
-
+#ifdef PGTK_DEBUG
void pgtk_backtrace(const char *file, int lineno)
{
Lisp_Object bt = make_uninit_vector(10);
#include "lisp.h"
#include "blockinput.h"
+#include "frame.h"
#include "sysselect.h"
#include "gtkutil.h"
#include "systime.h"
static struct frame *
pgtk_any_window_to_frame (GdkWindow *window);
+/*
+ * This is not a flip context in the same sense as gpu rendering
+ * scences, it only occurs when a new context was required due to a
+ * resize or other fundamental change. This is called when that
+ * context's surface has completed drawing
+ */
+
static void flip_cr_context(struct frame *f)
{
PGTK_TRACE("flip_cr_context");
External: Position the window
-------------------------------------------------------------------------- */
{
- /* not working on wayland. */
-
PGTK_TRACE("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity);
- if (change_gravity > 0)
- {
- PGTK_TRACE("x_set_offset: change_gravity > 0");
- f->top_pos = yoff;
+ struct frame *parent = FRAME_PARENT_FRAME(f);
+ GtkAllocation a = {0};
+ if (change_gravity > 0) {
+ if (parent) {
+ /* determing the "height" of the titlebar, by finding the
+ location of the "emacsfixed" widget on the surface/window */
+ GtkWidget *w = FRAME_GTK_WIDGET(parent);
+ gtk_widget_get_allocation(w, &a);
+ }
+
+ f->size_hint_flags &= ~ (XNegative | YNegative);
+ /* if the value is negative, don't include the titlebar offset */
+ if (xoff < 0) {
+ f->size_hint_flags |= XNegative;
f->left_pos = xoff;
- f->size_hint_flags &= ~ (XNegative | YNegative);
- if (xoff < 0)
- f->size_hint_flags |= XNegative;
- if (yoff < 0)
- f->size_hint_flags |= YNegative;
- f->win_gravity = NorthWestGravity;
+ } else {
+ f->left_pos = xoff + a.x; //~25
}
+ if (yoff < 0){
+ f->size_hint_flags |= YNegative;
+ f->top_pos = yoff;
+ } else {
+ f->top_pos = yoff + a.y; //~60
+ }
+ f->win_gravity = NorthWestGravity;
+ }
+
x_calc_absolute_position (f);
block_input ();
for (GtkWidget *w = FRAME_GTK_WIDGET(f); w != NULL; w = gtk_widget_get_parent(w)) {
gint wd, hi;
gtk_widget_get_size_request(w, &wd, &hi);
- GtkAllocation alloc;
- gtk_widget_get_allocation(w, &alloc);
}
f->output_data.pgtk->preferred_width = pixelwidth;
return gdk_screen_get_width(gscr);
}
+void
+x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
+/* --------------------------------------------------------------------------
+ Set frame F's `parent-frame' parameter. If non-nil, make F a child
+ frame of the frame specified by that parameter. Technically, this
+ makes F's window-system window a child window of the parent frame's
+ window-system window. If nil, make F's window-system window a
+ top-level window--a child of its display's root window.
+
+ A child frame's `left' and `top' parameters specify positions
+ relative to the top-left corner of its parent frame's native
+ rectangle. On macOS moving a parent frame moves all its child
+ frames too, keeping their position relative to the parent
+ unaltered. When a parent frame is iconified or made invisible, its
+ child frames are made invisible. When a parent frame is deleted,
+ its child frames are deleted too.
+
+ Whether a child frame has a tool bar may be window-system or window
+ manager dependent. It's advisable to disable it via the frame
+ parameter settings.
+
+ Some window managers may not honor this parameter.
+ -------------------------------------------------------------------------- */
+{
+ struct frame *p = NULL;
+ PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos);
+
+ if (!NILP (new_value)
+ && (!FRAMEP (new_value)
+ || !FRAME_LIVE_P (p = XFRAME (new_value))
+ || !FRAME_PGTK_P (p)))
+ {
+ store_frame_param (f, Qparent_frame, old_value);
+ error ("Invalid specification of `parent-frame'");
+ }
+
+ if (p != FRAME_PARENT_FRAME (f)
+ && (p != NULL))
+ {
+ block_input ();
+ gtk_window_set_transient_for(FRAME_NATIVE_WINDOW(f), FRAME_NATIVE_WINDOW(p));
+ gtk_window_set_attached_to(FRAME_NATIVE_WINDOW(f), FRAME_GTK_WIDGET(p));
+ gtk_window_move(FRAME_NATIVE_WINDOW(f), f->left_pos, f->top_pos);
+ gtk_window_set_keep_above(FRAME_NATIVE_WINDOW(f), true);
+ unblock_input ();
+
+ fset_parent_frame (f, new_value);
+ }
+}
+
void
x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
{
PGTK_TRACE("draw_window_cursor: %d, %d, %d, %d, %d, %d.",
x, y, cursor_type, cursor_width, on_p, active_p);
-
if (on_p)
{
w->phys_cursor_type = cursor_type;
xic_set_preeditarea (w, x, y);
#endif
}
+
}
static void
/* Tell Emacs about this window system. */
Fprovide (Qpgtk, Qnil);
-
}
-
+/* Cairo does not allow resizing a surface/context after it is
+ * created, so we need to trash the old context, create a new context
+ * on the next cr_clip_begin with the new dimensions and request a
+ * re-draw.
+ *
+ * This Will leave the active context available to present on screen
+ * until a redrawn frame is completed.
+ */
void
pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height)
{