Re: How to create a popup?



On Saturday, November 22, 2003, at 10:19 AM, Thomas Bayen wrote:

* How can I make that my popup behaves like a real one?

i would love to know. for a few years now, i've had a gtk-perl date-combo that just doesn't pop down correctly. i'm missing something simple-yet-important. but i've looked at it a lot and can give you some hints, so maybe you'll figure out what i've missed.


For example if I move my main window around with the mouse the popup stays on the old screen position :-(

erm, most popups go away when you click outside of them. think of optionmenus, menus in general, and comboboxen -- they're open until you click anywhere outside them, which means you can't grab the window border without the popup popping down.

to get this popup-moves-when-the-parent-moves behavior, you'd have to connect to something that tells you the window has been moved so you can move your child --- the only way to move two together (unless you're a window manager) is to have one be a child of the other, which popup windows aren't.


if I use "$self->{win}->set_property('type','popup')" the input focus does not go into the popup widget but stays in the main window.

you have to explicitly set the focus to be in that new popup window.

If I make it modal, it gets the focus, but I can't click into the main window any more to close the popup (like a menu popup would).

you don't want it to be modal, you want it to grab the pointer; then you test to see if you get an event outside the popup, and when you do, close the popup. (that's what the code in gtkcombo.c appears to do.)


Is there any simple (perl or C) example about creating my own popups?

not that i know of. i've been looking for some time so i can make the cellrenderer_date sample work correctly; before that, i was desperately trying to figure how to get a date combo's popup to popdown properly. the code in gtkcombo.c is a little labyrinthine and unhelpful in that respect, unfortunately, and testing out code that works with pointer grabs can be nightmarish if you don't have a second machine handy to log in and kill the app with the lost grab.


  Can't locate object method "get_root_window" via package ...

Is this method not implemented, if it is how can I call it or how can I find out the root coordinates of my widget in another way?

erm... well, no, that's not bound. it's a 2.2 method that appears to have slipped through the cracks. GtkWidget.xs was one of the first files created in gtk2-perl-xs, and came from the gtkwidget.h in my 2.0.6 installation which doesn't have that method and a few others.

this will get you going until i put it in cvs:

Index: xs/GtkWidget.xs
===================================================================
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/GtkWidget.xs,v
retrieving revision 1.38
diff -u -r1.38 GtkWidget.xs
--- xs/GtkWidget.xs     17 Nov 2003 02:43:10 -0000      1.38
+++ xs/GtkWidget.xs     23 Nov 2003 07:43:25 -0000
@@ -828,10 +828,13 @@
        GdkAtom     selection


-#GdkDisplay* gtk_widget_get_display (GtkWidget *widget)
-GdkDisplay *
-gtk_widget_get_display (widget)
-       GtkWidget * widget
+GdkDisplay * gtk_widget_get_display (GtkWidget * widget)
+
+GdkWindow * gtk_widget_get_root_window (GtkWidget * widget)
+
+GdkScreen * gtk_widget_get_screen (GtkWidget * widget)
+
+gboolean gtk_widget_has_screen (GtkWidget * widget);

 #endif


* I use the "allocation" function to get the coordinates of the widget. I can not find documentation to this function. I found it only with indirect mention. If this is a "documentation bug" I want to report it here...

it's an accessor for a member variable, not a *real* function. the allocation describes how much space was actually allocated to the widget, which asked for the amount of space in the requisition. i have no idea what the x and y in the allocation actually are -- i presume that they are the coordinates of the widget's origin relative to its parent, but i can't prove that.


sub callback_openpopup{
  my($self)= _;
  $self->{win}->destroy if defined $self->{win};

why destroy it if it already exists? usually you'd want just to show it again to keep from having to re-create it. (but destroying works, just a thought)

  $self->{win}=Gtk2::Window->new;
  # What's this for?!?:
  # $self->{win}->set_property('type','popup');

type is a construct-only property.  you want instead to do

   $self->{win} = Gtk2::Window->new ('popup')

  $self->{win}->set_destroy_with_parent(1);
  $self->{win}->set_decorated(0);

these are not necessary if you create the window correctly.


  $self->{win}->set_default_size(400,200);
  # find the right coordinates:
  my($winx,$winy)=$self->get_toplevel->get_position;
  my($x,$y)=($self->allocation->x,$self->allocation->y);

allocation doesn't do what you want it to do here. find the upper left corner of the GdkWindow associated with the widget, and use *that* for x and y.

  my ($x, $y) = $self->window->get_origin;

  $self->{win}->move($winx+$x,$winy+$y);
  my $search=Gtk2::RecordSearch->new();
  $self->{win}->add(my $f=Gtk2::Frame->new());
  $f->set_shadow_type('etched-out');
  $f->add($search);
  $self->{win}->show_all;
}



--
muppet <scott at asofyet dot org>




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