Re: Sizing top level windows and gtk_widget_size_request problems



nicholas allen <nicholas allen ireland sun com> writes:

I'm hoping someone may be able to offer me some advise here. I guess
I don't fully understand the way that gtk sizes widgets and, in
particular, top level windows. When I set the size of a window with
gtk_widget_set_usize (width, height) the widget usually resizes to
the size I have specified. However, if I call this on a top level
window widget and the size is smaller than its current size nothing
happens and the window remains its current size. I have also seen
the same thing when a widget is inside a gtk_scrolled_window and I
resize it. It never gets smaller. Am I using the wrong function for
this?

In GTK 1.2 this isn't entirely rational; fixing it is one of the last
API items in the GTK 2 queue.

Anyway, set_usize() is basically setting the size request, not the
actual size. Typically for a user-resizable toplevel, it will not auto
shrink to the size request, since the user may have resized it larger.
See gtk_window_set_policy() (which is in itself a fairly silly
function).

I have also noticed that if I create a button, say, with a label
inside it and then I change the text of the label and then ask the
button what size it wants to be (with gtk_widget_size_request) it
returns the same size as before the label was changed. Shouldn't it
recompute its size to take acount of the possibly longer or shorter
text? On looking at the code I can't see why this is not
happening. Should I be using a different function (eg
gtk_widget_size_allocate) for this too or do I need to call another
function to clear the cached size to cause the button (or whatever
widget it is) to recalculate its preferred size?

That's odd - have you set usize on the button?

gtk_widget_queue_resize() recalcs its size, but that certainly should
be done automatically when changing the label text. A set_usize()
would defeat the auto-size-request-computation though.

I'll append some notes on how it's all getting rearranged and
hopefully rationalized in GTK 2.

Havoc


gtk_widget_set_size_request ():
 - Sets the size that a widget will request, overriding its usual
   request. (Renaming of set_usize().)
   
   Passing -1 for width/height unsets that value.
   Passing 0 is equivalent to passing 1, because GTK always 
    allocates at least 1x1 despite a requisition of 0x0; 
    however we should allow 0 since it's an intuitive number
    to pass here.
   
gtk_window_resize ():
 - Resizes the window as if the user had done so, obeying geometry 
   constraints. If there's a geometry widget, specified size
   is for the geometry widget. (Renaming of gtk_window_set_default_size().)

   Sizes <= 0 g_return_if_fail().

gtk_window_move ():
 - Moves the window as if the user had done so, obeying 
   constraints of e.g. GTK_WIN_POS_CENTER_ALWAYS. 
   Position is given as the position of the gravity-determined 
   reference point.

   Position can be negative to move windows offscreen.

   Position is in root window coordinates, but allowing
   E's virtual root hack to work (we don't try to compensate
   for how E will offset our configure request)

gtk_window_get_size ():
 - If mapped, gets actual current size of widget->window

   Prior to mapping, tries to predict the window size (looks
   at size request, window_resize() values, and geometry constraints)

gtk_window_get_position ():
 - Gets the gravity-determined reference point location, 
   if unmapped, tries to predict window position (looks at 
   GTK_WIN_POS_*, gtk_window_move() values, falls back 
   to 0,0 or something)

   Position is normally in root window coordinates, but we 
   offset it to compensate for E's virtual root hack
   so that setting the position we get will give the expected
   result.

GtkWidget::width_request, GtkWidget::height_request:
 - Read-write properties, equivalent to set_size_request. 
   -1 if !width_request_set, etc.

GtkWidget::width_request_set, GtkWidget::height_request_set:
 - Read-write properties, whether the size request value 
   is used or not.

GtkWindow::default_width, GtkWindow::default_height:
 - still needed so you can set default size in a GUI builder.
   Setting them need not have any effect post-mapping. 
   Setting them pre-mapping is the same as calling
   gtk_window_resize().
   Maybe the implementation is:
     if (!GTK_WIDGET_MAPPED (window))
       gtk_window_resize (window, w, h);

   -1 if _set flags are unset

GtkWindow::default_width_set, GtkWindow::default_height_set:
 - whether default w/h are set                             

Deprecations:
  - gtk_widget_set_uposition() - use gtk_window_move() or
    gtk_fixed_move()/gtk_layout_move()
  - gtk_widget_set_usize() - use widget_set_size_request()
    or gtk_window_resize()
  - x/y/width/height properties on GtkWidget

General changes:

  Size calculation (internal function gtk_window_move_resize()) is
  done simply as:

    - compute geometry hints.
    - set initial size hint (before mapping window) to either size
      request or the gtk_window_resize() values if they were set,
      constraining to geometry hints.
    - after the window is onscreen, clamp current size to geometry
      hints, don't affect current size otherwise.
      (Do we need to send a configure request or will the WM 
      handle the clamping?)

  No "hysteresis" - current size has a fixed relationship to the
  parameters that have been set and actions users have taken.

  allow_shrink is equivalent to calling
  gtk_widget_set_size_request (widget, 0, 0). 

  allow_grow is now the flag sest by gtk_window_set_resizeable().
  If TRUE, max size is infinite by default. If FALSE, max size 
  is equal to the min size by default.

  auto_shrink is now ignored. This is reasonably backward
  compatible. If the legacy code using the new set_policy() didn't set
  allow_grow, then auto_shrink would do nothing, since we now clamp
  within min/max size in all cases. with allow_grow=false this means
  the window is always shrunk already. if legacy code did set
  allow_grow, then the behavior before just made no sense, but
  probably they wanted a resizable window.

  Geometry hints set with gtk_window_set_geometry_hints() simply
  override anything calculated in any other way, e.g. if you set the
  min size with geometry hints, it overrides the min size based on the
  window's size request.

Notes:

 There's no way to get GtkWidget size/position because there is no
 real reason to get those things unless you understand size_allocate
 and widget->allocation


 Instead of having set_position() not compensate for E and
 get_position() compensate for E, we could have get_position() not
 compensate for E but set_position() does compensate for E.
 In this case, you would call set_position() with root window
 coordinates, and internally we would translate those so that E
 positions the window properly.

 If we did things like this, we'd need a function
 gdk_workspace_get_extents() which should be used for the screen
 extents instead of (0,0) gdk_screen_width () x gdk_screen_height ()

 My bias toward compensating for E in get_position() rather than
 set_position() is that it's simpler and doesn't changing apps.
 The argument for gdk_workspace_get_extents() would be that 
 it's a better abstraction than forcing the workspace to 
 always be (0,0) gdk_screen_width () x gdk_screen_height ()

Issues:

 - whether to add get_size_request ()
 - readonly x/y props











[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]