Re: How to put the GtkWidget to max screen size?
- From: "J. Ali Harlow" <gtk-list avrc city ac uk>
- To: <gtk-list gnome org>
- Subject: Re: How to put the GtkWidget to max screen size?
- Date: Thu, 21 Dec 2000 18:22:20 +0000
On Thu, 21 Dec 2000, Havoc Pennington wrote:
> "alan" <alan ielinux com> writes:
> > I set GtkWidget to max size of screen by use gtk_widget_set_usize() and
> > gtk_widget_set_uposition().
> > If I running in kde environmentis is ok.
> > but if I set widget position to (0,0), and running program in afterstop.
> > The title bar of afterstep will hide over screen.
>
> The problem is that window managers are broken in this respect. The
> new window manager spec clarifies the correct behavior; window
> managers should unbreak themselves eventually.
>
> > Have any other way to set GtkWidget to max size of screen.
> > And, How to know the border size and title bar height of window manager?
> >
>
> You can't really know this. There are some scary hacks to try to
> figure it out, but you'd have to know a lot about X.
I worked out a hack for this same problem, which seems to work.
Feel free to use it and/or comment on it's shotcomings.
Cheers,
--
Ali Harlow Email: ali avrc city ac uk
Research programmer Tel: (020) 7477 8000 X 4348
Applied Vision Research Centre Intl: +44 20 7477 8000 X 4348
City University Fax: (020) 7505 5515
London Intl: +44 20 7505 5515
/* ALI
* We need to know the border width and height so that we can correctly
* clamp dialogs to the screen. Unfortunately, GDK allows us no way to
* dermine the border sizes before we map the window. We get around this
* by remembering what they were for the last dialog displayed and
* checking that they haven't changed after the window is mapped. If
* we find we're offscreen after mapping we have to re-position the
* window. Clumsy, but effective.
*
* Note: there's no way that I know of to determine the width of the
* right border or the height of the bottom border. For now, we just
* assume that these are both equal to the left border. Typically,
* only the top border is different and this is a valid assumption.
*
* This is all further complicated by the fact that, at least under
* the Enlightenment window manager, gtk_widget_set_uposition() sets
* the position of the top left pixel of the border before the window
* is mapped, but the top left pixel of the window after it is mapped.
*
* Note: If the window manager is set up such that gtk_widget_set_upostion()
* always sets the position of the left left pixel of the window, and if
* gtk_window_get_origin() returns this same position, then this code
* will fail (gracefully) and dialogs may be positioned with their borders
* just off-screen.
*/
static gint popup_dialog_bw = 0, popup_dialog_bh = 0;
volatile int popup_dialog_abandon;
static gint popup_dialog_timeout(gpointer data)
{
if (!popup_dialog_abandon)
popup_dialog_abandon++;
return FALSE;
}
static void
popup_dialog_mapped(GtkWidget *w, gpointer data)
{
gint screen_width, screen_height;
GdkWindow *window = GTK_WIDGET(w)->window;
gint x, y, nx, ny;
data = gtk_object_get_user_data(GTK_OBJECT(w));
if (data) {
x = GPOINTER_TO_UINT(data) >> 16;
y = GPOINTER_TO_UINT(data) & 0xffff;
/* Wait for Window Manager to place window and add borders */
popup_dialog_abandon = 0;
gtk_timeout_add(100L, popup_dialog_timeout, 0);
do
{
gtk_main_iteration();
if (popup_dialog_abandon) { /* Don't wait for ever */
if (popup_dialog_abandon++ > 1) /* One final check? */
return;
}
gdk_window_get_origin(window, &nx, &ny);
} while (nx == 0 && ny == 0 || nx == x && ny == y);
popup_dialog_bw = nx - x;
popup_dialog_bh = ny - y;
/* Do we need to re-position this window to stay on-screen? */
screen_width = gdk_screen_width();
screen_height = gdk_screen_height();
if (nx + popup_dialog_bw + w->allocation.width > screen_width)
x = screen_width - popup_dialog_bw - w->allocation.width;
else x = nx;
if (ny + popup_dialog_bw + w->allocation.height > screen_height)
/* popup_dialog_bw because we assume bottom border same as left */
y = screen_height - popup_dialog_bw - w->allocation.height;
else y = ny;
if (x != nx || y != ny)
gtk_widget_set_uposition(w, x, y);
}
}
static void
popup_dialog_realizing(GtkWidget *w, gpointer data)
{
GdkWindow *window = GTK_WIDGET(main_window)->window;
gint x, y, width, height, ox, oy;
gint screen_width = gdk_screen_width(), screen_height = gdk_screen_height();
if (w->allocation.width > screen_width ||
w->allocation.height > screen_height) {
/* This is going to look bad anyway, we can't centre it because
* a position less than 0 is not valid, so the best we can do
* is place the pop-up at the top left of the screen and accept
* that the right and/or bottom edge will be off-screen.
*/
x = y = 0;
}
else {
gdk_window_get_geometry(window, &x, &y, &width, &height, NULL);
gdk_window_get_origin(window, &ox, &oy);
x += ox + (width - w->allocation.width) / 2;
y += oy + (height - w->allocation.height) / 2;
if (x + w->allocation.width + popup_dialog_bw > screen_width)
x = screen_width - popup_dialog_bw - w->allocation.width;
if (y + w->allocation.height + popup_dialog_bw > screen_height)
y = screen_height - popup_dialog_bw - w->allocation.height;
/* (x,y) is the desired position of the window,
* adjust to take into account the expected border. */
x -= popup_dialog_bw;
y -= popup_dialog_bh;
if (x < 0) x = 0;
if (y < 0) y = 0;
}
gtk_widget_set_uposition(w, x, y);
gtk_object_set_user_data(GTK_OBJECT(w), GUINT_TO_POINTER(x << 16 | y));
}
void
nh_position_popup_dialog(GtkWidget *w)
{
if (GTK_WIDGET_REALIZED(w))
popup_dialog_realizing(w, 0);
if (GTK_WIDGET_MAPPED(w))
popup_dialog_mapped(w, 0);
gtk_signal_connect(GTK_OBJECT(w), "realize",
GTK_SIGNAL_FUNC(popup_dialog_realizing), 0);
gtk_signal_connect_after(GTK_OBJECT(w), "map",
GTK_SIGNAL_FUNC(popup_dialog_mapped), 0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]