1# You may distribute under the terms of either the GNU General Public License 2# or the Artistic License (the same terms as Perl itself) 3# 4# (C) Paul Evans, 2009-2019 -- leonerd@leonerd.org.uk 5 6package Tickit::Window 0.72; 7 8use v5.14; 9use warnings; 10 11use Carp; 12 13use Scalar::Util qw( weaken refaddr blessed ); 14use List::Util qw( first ); 15 16use Tickit::Pen; 17use Tickit::Rect; 18use Tickit::RectSet; 19use Tickit::RenderBuffer; 20use Tickit::Utils qw( string_countmore ); 21 22use Tickit::Debug; 23 24use constant WEAKEN_CHILDREN => $ENV{TICKIT_CHILD_WINDOWS_WEAKEN} // 1; 25 26=head1 NAME 27 28C<Tickit::Window> - a window for drawing operations 29 30=head1 SYNOPSIS 31 32 use Tickit; 33 use Tickit::Pen; 34 35 my $tickit = Tickit->new; 36 37 my $rootwin = $tickit->rootwin; 38 39 $rootwin->bind_event( expose => sub { 40 my ( $win, undef, $info ) = @_; 41 42 my $rb = $info->rb; 43 44 $rb->clear; 45 46 $rb->text_at( 47 int( $win->lines / 2 ), int( ($win->cols - 12) / 2 ), 48 "Hello, world" 49 ); 50 }); 51 $rootwin->bind_event( geomchange => sub { shift->expose } ); 52 $rootwin->set_pen( Tickit::Pen->new( fg => "white" ) ); 53 54 $rootwin->expose; 55 $tickit->run; 56 57=head1 DESCRIPTION 58 59Provides coordination of widget drawing activities. A C<Window> represents a 60region of the screen that a widget occupies. 61 62Windows cannot directly be constructed. Instead they are obtained by 63sub-division of other windows, ultimately coming from the 64root window associated with the terminal. 65 66Normally all windows are visible, but a window may be hidden by calling the 67C<hide> method. After this, the window will not respond to any of the drawing 68methods, until it is made visible again with the C<show> method. A hidden 69window will not receive focus or input events. It may still receive geometry 70change events if it is resized. 71 72=head2 Sub Windows 73 74A division of a window made by calling C<make_sub> or C<make_float> obtains a 75window that represents some portion of the drawing area of the parent window. 76Child windows are stored in order; C<make_sub> adds a new child to the end of 77the list, and C<make_float> adds one at the start. 78 79Higher windows (windows more towards the start of the list), will always handle 80input events before lower siblings. The extent of windows also obscures lower 81windows; drawing on lower windows may not be visible because higher windows 82are above it. 83 84=head2 Deferred Child Window Operations 85 86In order to minimise the chances of ordering-specific bugs in window event 87handlers that cause child window creation, reordering or deletion, the actual 88child window list is only mutated after the event processing has finished, by 89using a L<Tickit> C<later> block. 90 91=cut 92 93# Internal constructor 94sub new 95{ 96 my $class = shift; 97 my ( $tickit ) = @_; 98 99 return $class->_new_root( $tickit->term, $tickit ); 100} 101 102# We need to ensure all geomety changes happen before any redrawing 103 104=head1 METHODS 105 106=cut 107 108=head2 close 109 110 $win->close 111 112Removes the window from its parent and clears any event handlers set using 113L<bind_event>. Also recursively closes any child windows. 114 115Currently this is an optional method, as child windows are stored as weakrefs, 116so should be destroyed when the last reference to them is dropped. Widgets 117should make sure to call this method anyway, because this will be changed in a 118future version. 119 120=cut 121 122=head2 make_sub 123 124 $sub = $win->make_sub( $top, $left, $lines, $cols ) 125 126Constructs a new sub-window of the given geometry, and places it at the end of 127the child window list; below any other siblings. 128 129=cut 130 131sub make_sub 132{ 133 my $self = shift; 134 return $self->_make_sub( @_, WINDOW_LOWEST ); 135} 136 137=head2 make_hidden_sub 138 139 $sub = $win->make_hidden_sub( $top, $left, $lines, $cols ) 140 141Constructs a new sub-window like C<make_sub>, but the window starts initially 142hidden. This avoids having to call C<hide> separately afterwards. 143 144=cut 145 146sub make_hidden_sub 147{ 148 my $self = shift; 149 return $self->_make_sub( @_, WINDOW_HIDDEN ); 150} 151 152=head2 make_float 153 154 $float = $win->make_float( $top, $left, $lines, $cols ) 155 156Constructs a new sub-window of the given geometry, and places it at the start 157of the child window list; above any other siblings. 158 159=cut 160 161sub make_float 162{ 163 my $self = shift; 164 return $self->_make_sub( @_, 0 ); 165} 166 167=head2 make_popup 168 169 $popup = $win->make_popup( $top, $left, $lines, $cols ) 170 171Constructs a new floating popup window starting at the given coordinates 172relative to this window. It will be sized to the given limits. 173 174This window will have the root window as its parent, rather than the window 175the method was called on. Additionally, a popup window will steal all keyboard 176and mouse events that happen, regardless of focus or mouse position. It is 177possible that, if the window has an C<on_mouse> handler, that it may receive 178mouse events from outwide the bounds of the window. 179 180=cut 181 182sub make_popup 183{ 184 my $self = shift; 185 return $self->_make_sub( @_, WINDOW_POPUP ); 186} 187 188=head2 bind_event 189 190 $id = $win->bind_event( $ev, $code, $data ) 191 192Installs a new event handler to watch for the event specified by C<$ev>, 193invoking the C<$code> reference when it occurs. C<$code> will be invoked with 194the given window, the event name, an event information object, and the 195C<$data> value it was installed with. C<bind_event> returns an ID value that 196may be used to remove the handler by calling C<unbind_event_id>. 197 198 $ret = $code->( $win, $ev, $info, $data ) 199 200The type of C<$info> will depend on the kind of event that was received, as 201indicated by C<$ev>. The information structure types are documented in 202L<Tickit::Event>. 203 204=head2 bind_event (with flags) 205 206 $id = $win->bind_event( $ev, $flags, $code, $data ) 207 208The C<$code> argument may optionally be preceded by an integer of flag 209values. This should be zero to apply default semantics, or a bitmask of 210constants. The constants are documented in 211L<Tickit::Term/bind_event (with flags)>. 212 213=cut 214 215sub bind_event 216{ 217 my $self = shift; 218 my $ev = shift; 219 my ( $flags, $code, $data ) = ( ref $_[0] ) ? ( 0, @_ ) : @_; 220 221 $self->_bind_event( $ev, $flags, $code, $data ); 222} 223 224=head2 unbind_event_id 225 226 $win->unbind_event_id( $id ) 227 228Removes an event handler that returned the given C<$id> value. 229 230=cut 231 232=head2 raise 233 234 $win->raise 235 236=head2 lower 237 238 $win->lower 239 240Moves the order of the window in its parent one higher or lower relative to 241its siblings. 242 243=cut 244 245=head2 raise_to_front 246 247 $win->raise_to_front 248 249Moves the order of the window in its parent to be the front-most among its 250siblings. 251 252=cut 253 254=head2 lower_to_back 255 256 $win->lower_to_back 257 258Moves the order of the window in its parent to be the back-most among its 259siblings. 260 261=cut 262 263=head2 parent 264 265 $parentwin = $win->parent 266 267Returns the parent window; i.e. the window on which C<make_sub> or 268C<make_float> was called to create this one 269 270=cut 271 272=head2 subwindows 273 274 @windows = $win->subwindows 275 276Returns a list of the subwindows of this one. They are returned in order, 277highest first. 278 279=cut 280 281=head2 root 282 283 $rootwin = $win->root 284 285Returns the root window 286 287=cut 288 289=head2 term 290 291 $term = $win->term 292 293Returns the L<Tickit::Term> instance of the terminal on which this window 294lives. 295 296Note that it is not guaranteed that this method will return the same 297Perl-level terminal instance that the root window was constructed with. In 298particular, if the root window in fact lives on a mock terminal created by 299L<Tickit::Test::MockTerm> this method may "forget" this fact, returning an 300object instance simply in the C<Tickit::Term> class instead. While the 301instance will still be useable as a terminal, the fact it was a mock terminal 302may get forgotten. 303 304=cut 305 306=head2 tickit 307 308 $tickit = $win->tickit 309 310Returns the L<Tickit> instance with which this window is associated. 311 312=cut 313 314sub tickit 315{ 316 return shift->root->_tickit; 317} 318 319=head2 show 320 321 $win->show 322 323Makes the window visible. Allows drawing methods to output to the terminal. 324Calling this method also exposes the window, invoking the C<on_expose> 325handler. Shows the cursor if this window currently has focus. 326 327=cut 328 329=head2 hide 330 331 $win->hide 332 333Makes the window invisible. Prevents drawing methods outputting to the 334terminal. Hides the cursor if this window currently has focus. 335 336=cut 337 338=head2 is_visible 339 340 $visible = $win->is_visible 341 342Returns true if the window is currently visible. 343 344=cut 345 346=head2 resize 347 348 $win->resize( $lines, $cols ) 349 350Change the size of the window. 351 352=cut 353 354=head2 reposition 355 356 $win->reposition( $top, $left ) 357 358Move the window relative to its parent. 359 360=cut 361 362=head2 change_geometry 363 364 $win->change_geometry( $top, $left, $lines, $cols ) 365 366A combination of C<resize> and C<reposition>, to atomically change all the 367coordinates of the window. Will only invoke C<on_geom_changed> once, rather 368than twice as would be the case calling the above methods individually. 369 370=cut 371 372our $INDENT = ""; 373sub _do_expose 374{ 375 my $self = shift; 376 my ( $rect, $rb ) = @_; 377 378 $rb->setpen( $self->pen ); 379 380 Tickit::Debug->log( Wx => "${INDENT}Expose %s %s", $self->sprintf, $rect->sprintf ) if DEBUG; 381 local $INDENT = "| $INDENT"; 382 383 foreach my $win ( $self->subwindows ) { 384 next unless $win->is_visible; 385 386 if( my $winrect = $rect->intersect( $win->rect ) ) { 387 $rb->save; 388 389 $rb->clip( $winrect ); 390 $rb->translate( $win->top, $win->left ); 391 $win->_do_expose( $winrect->translate( -$win->top, -$win->left ), $rb ); 392 393 $rb->restore; 394 } 395 396 $rb->mask( $win->rect ); 397 } 398 399 $rb->save; 400 401 $self->_fire_event( expose => Tickit::Event::Expose->_new( $rb, $rect ) ); 402 403 $rb->restore; 404} 405 406=head2 expose 407 408 $win->expose( $rect ) 409 410Marks the given region of the window as having been exposed, to invoke the 411C<on_expose> event handler on itself, and all its child windows. The window's 412own handler will be invoked first, followed by all the child windows, in 413screen order (top to bottom, then left to right). 414 415If C<$rect> is not supplied it defaults to exposing the entire window area. 416 417The C<on_expose> event handler isn't invoked immediately; instead, the 418C<Tickit> C<later> method is used to invoke it at the next round of IO event 419handling. Until then, any other window could be exposed. Duplicates are 420suppressed; so if a window and any of its ancestors are both queued for 421expose, the actual handler will only be invoked once per unique region of the 422window. 423 424=cut 425 426=head2 getctl 427 428=head2 setctl 429 430 $value = $win->getctl( $ctl ) 431 432 $success = $win->setctl( $ctl, $value ) 433 434Accessor and mutator for window control options. C<$ctl> should be one of the 435following options: 436 437=over 4 438 439=item cursor-blink (bool) 440 441=item cursor-shape (int) 442 443=item cursor-visible (bool) 444 445Cursor properties to set for the terminal cursor when this window has input 446focus. 447 448=item focus-child-notify (bool) 449 450Whether the window will also receive focus events about child windows. 451 452=item steal-input (bool) 453 454Whether the window is currently stealing input from its siblings. 455 456=back 457 458=cut 459 460=head2 set_focus_child_notify 461 462 $win->set_focus_child_notify( $notify ) 463 464If set to a true value, the C<on_focus> event handler will also be invoked 465when descendent windows gain or lose focus, in addition to when it gains or 466loses focus itself. Defaults to false; meaning the C<on_focus> handler only 467receives notifications about the window itself. 468 469=cut 470 471sub set_focus_child_notify 472{ 473 my $self = shift; 474 my ( $notify ) = @_; 475 476 $self->setctl( 'focus-child-notify' => $notify ); 477} 478 479=head2 top 480 481=head2 bottom 482 483=head2 left 484 485=head2 right 486 487 $top = $win->top 488 489 $bottom = $win->bottom 490 491 $left = $win->left 492 493 $right = $win->right 494 495Returns the coordinates of the start of the window, relative to the parent 496window. 497 498=cut 499 500sub bottom 501{ 502 my $self = shift; 503 return $self->top + $self->lines; 504} 505 506sub right 507{ 508 my $self = shift; 509 return $self->left + $self->cols; 510} 511 512=head2 abs_top 513 514=head2 abs_left 515 516 $top = $win->abs_top 517 518 $left = $win->abs_left 519 520Returns the coordinates of the start of the window, relative to the root 521window. 522 523=cut 524 525=head2 cols 526 527=head2 lines 528 529 $cols = $win->cols 530 531 $lines = $win->lines 532 533Obtain the size of the window 534 535=cut 536 537=head2 selfrect 538 539 $rect = $win->selfrect 540 541Returns a L<Tickit::Rect> containing representing the window's extent within 542itself. This will have C<top> and C<left> equal to 0. 543 544=cut 545 546sub selfrect 547{ 548 my $self = shift; 549 # TODO: Cache this, invalidate it in ->change_geometry 550 return Tickit::Rect->new( 551 top => 0, 552 left => 0, 553 lines => $self->lines, 554 cols => $self->cols, 555 ); 556} 557 558=head2 rect 559 560 $rect = $win->rect 561 562Returns a L<Tickit::Rect> containing representing the window's extent relative 563to its parent 564 565=cut 566 567sub rect 568{ 569 my $self = shift; 570 # TODO: Cache this, invalidate it in ->change_geometry 571 return Tickit::Rect->new( 572 top => $self->top, 573 left => $self->left, 574 lines => $self->lines, 575 cols => $self->cols, 576 ); 577} 578 579=head2 pen 580 581 $pen = $win->pen 582 583Returns the current L<Tickit::Pen> object associated with this window 584 585=cut 586 587=head2 set_pen 588 589 $win->set_pen( $pen ) 590 591Replace the current L<Tickit::Pen> object for this window with a new one. The 592object reference will be stored, allowing it to be shared with other objects. 593If C<undef> is set, then a new, blank pen will be constructed. 594 595=cut 596 597=head2 getpenattr 598 599 $val = $win->getpenattr( $attr ) 600 601Returns a single attribue from the current pen 602 603=cut 604 605sub getpenattr 606{ 607 my $self = shift; 608 my ( $attr ) = @_; 609 610 return $self->pen->getattr( $attr ); 611} 612 613=head2 get_effective_pen 614 615 $pen = $win->get_effective_pen 616 617Returns a new L<Tickit::Pen> containing the effective pen attributes for the 618window, combined by those of all its parents. 619 620=cut 621 622sub get_effective_pen 623{ 624 my $win = shift; 625 626 my $pen = $win->pen->as_mutable; 627 for( my $parent = $win->parent; $parent; $parent = $parent->parent ) { 628 $pen->default_from( $parent->pen ); 629 } 630 631 return $pen; 632} 633 634=head2 get_effective_penattr 635 636 $val = $win->get_effective_penattr( $attr ) 637 638Returns the effective value of a pen attribute. This will be the value of this 639window's attribute if set, or the effective value of the attribute from its 640parent. 641 642=cut 643 644sub get_effective_penattr 645{ 646 my $win = shift; 647 my ( $attr ) = @_; 648 649 for( ; $win; $win = $win->parent ) { 650 my $value = $win->pen->getattr( $attr ); 651 return $value if defined $value; 652 } 653 654 return undef; 655} 656 657=head2 scrollrect 658 659 $success = $win->scrollrect( $rect, $downward, $rightward ) 660 661 $success = $win->scrollrect( $top, $left, $lines, $cols, $downward, $rightward ) 662 663 $success = $win->scrollrect( ..., $pen ) 664 665 $success = $win->scrollrect( ..., %attrs ) 666 667Attempt to scroll the rectangle of the window (either given by a 668C<Tickit::Rect> or defined by the first four parameters) by an amount given 669by the latter two. Since most terminals cannot perform arbitrary rectangle 670scrolling, this method returns a boolean to indicate if it was successful. 671The caller should test this return value and fall back to another drawing 672strategy if the attempt was unsuccessful. 673 674Optionally, a C<Tickit::Pen> instance or hash of pen attributes may be 675provided, to override the background colour used for erased sections behind 676the scroll. 677 678The cursor may move as a result of calling this method; its location is 679undefined if this method returns successful. The terminal pen, in particular 680the background colour, may be modified by this method even if it fails to 681scroll the terminal (and returns false). 682 683This method will enqueue all of the required expose requests before returning, 684so in this case the return value is not interesting. 685 686=cut 687 688sub scrollrect 689{ 690 my $self = shift; 691 my $rect; 692 if( blessed $_[0] and $_[0]->isa( "Tickit::Rect" ) ) { 693 $rect = shift; 694 } 695 else { 696 my ( $top, $left, $lines, $cols ) = splice @_, 0, 4; 697 $rect = Tickit::Rect->new( 698 top => $top, 699 left => $left, 700 lines => $lines, 701 cols => $cols, 702 ); 703 } 704 my ( $downward, $rightward, @penargs ) = @_; 705 die "PENARGS" if @penargs; 706 707 my $pen = ( @penargs == 0 ) ? undef : 708 ( @penargs == 1 ) ? $penargs[0]->as_mutable : 709 Tickit::Pen::Mutable->new( @penargs ); 710 711 $self->_scrollrect( $rect, $downward, $rightward, $pen ); 712} 713 714=head2 scroll 715 716 $success = $win->scroll( $downward, $rightward ) 717 718A shortcut for calling C<scrollrect> on the entire region of the window. 719 720=cut 721 722sub scroll 723{ 724 my $self = shift; 725 my ( $downward, $rightward ) = @_; 726 727 return $self->scrollrect( 728 0, 0, $self->lines, $self->cols, 729 $downward, $rightward 730 ); 731} 732 733=head2 scroll_with_children 734 735 $win->scroll_with_children( $downward, $rightward ) 736 737Similar to C<scroll> but ignores child windows of this one, moving all of 738the terminal content paying attention only to obscuring by newer siblings of 739ancestor windows. 740 741This method is experimental, intended only for use by 742L<Tickit::Widget::ScrollBox>. After calling this method, the terminal content 743will have moved and the windows drawing them will be confused unless the 744window position was also updated. C<ScrollBox> takes care to do this. 745 746=cut 747 748sub scroll_with_children 749{ 750 my $self = shift; 751 my ( $downward, $rightward, @args ) = @_; 752 die "PENARGS" if @args; 753 754 my $pen = ( @args == 0 ) ? undef : 755 ( @args == 1 ) ? $args[0]->as_mutable : 756 Tickit::Pen::Mutable->new( @args ); 757 758 $self->_scroll_with_children( $downward, $rightward ); 759} 760 761=head2 cursor_at 762 763 $win->cursor_at( $line, $col ) 764 765Sets the position in the window at which the terminal cursor will be placed if 766this window has focus. This method does I<not> force the window to take the 767focus though; for that see C<take_focus>. 768 769=cut 770 771sub cursor_at 772{ 773 my $self = shift; 774 $self->set_cursor_position( @_ ); 775} 776 777=head2 cursor_visible 778 779 $win->cursor_visible( $visible ) 780 781Sets whether the terminal cursor is visible on the window when it has focus. 782Normally it is, but passing a false value will make the cursor hidden even 783when the window is focused. 784 785=cut 786 787sub set_cursor_visible 788{ 789 my $self = shift; 790 my ( $visible ) = @_; 791 792 $self->setctl( 'cursor-visible' => $visible ); 793} 794 795*cursor_visible = \&set_cursor_visible; 796 797=head2 cursor_shape 798 799 $win->cursor_shape( $shape ) 800 801Sets the shape that the terminal cursor will have if this window has focus. 802This method does I<not> force the window to take the focus though; for that 803see C<take_focus>. Valid values for C<$shape> are the various 804C<CURSORSHAPE_*> constants from L<Tickit::Term>. 805 806=cut 807 808sub set_cursor_shape 809{ 810 my $self = shift; 811 my ( $shape ) = @_; 812 813 $self->setctl( 'cursor-shape' => $shape ); 814} 815 816*cursor_shape = \&set_cursor_shape; 817 818=head2 take_focus 819 820 $win->take_focus 821 822Causes this window to take the input focus, and updates the cursor position to 823the stored active position given by C<cursor_at>. 824 825=cut 826 827=head2 focus 828 829 $win->focus( $line, $col ) 830 831A convenient shortcut combining C<cursor_at> with C<take_focus>; setting the 832focus cursor position and taking the input focus. 833 834=cut 835 836sub focus 837{ 838 my $self = shift; 839 $self->cursor_at( @_ ); 840 $self->take_focus; 841} 842 843=head2 is_focused 844 845 $focused = $win->is_focused 846 847Returns true if this window currently has the input focus 848 849=cut 850 851=head2 is_steal_input 852 853 $steal = $win->is_steal_input 854 855Returns true if this window is currently stealing input from its siblings 856 857=cut 858 859sub is_steal_input 860{ 861 my $self = shift; 862 863 return $self->getctl( 'steal-input' ); 864} 865 866=head2 set_steal_input 867 868 $win->set_steal_input( $steal ) 869 870Controls whether this window is currently stealing input from its siblings 871 872=cut 873 874sub set_steal_input 875{ 876 my $self = shift; 877 my ( $steal ) = @_; 878 879 $self->setctl( 'steal-input' => $steal ); 880} 881 882sub sprintf 883{ 884 my $self = shift; 885 return sprintf "[%dx%d abs@%d,%d]", $self->cols, $self->lines, $self->abs_left, $self->abs_top; 886} 887 888use overload 889 '""' => sub { 890 my $self = shift; 891 return ref($self) . $self->sprintf, 892 }, 893 '0+' => sub { 894 my $self = shift; 895 return $self; 896 }, 897 bool => sub { 1 }, 898 fallback => 1; 899 900=head1 EVENTS 901 902The following event types are emitted and may be observed by L</bind_event>. 903 904=head2 key 905 906Emitted when a key on the keyboard is pressed while this window or one of its 907child windows has the input focus, or is set to steal input anyway. 908 909The event handler should return a true value if it considers the keypress 910dealt with, or false to pass it up to its parent window. 911 912Before passing it to its parent, a window will also try any other non-focused 913sibling windows of the currently-focused window in order of creation (though 914note this order is not necessarily the order the child widgets that own those 915windows were created or added to their container). 916 917If no window actually handles the keypress, then every window will eventually 918be consulted about it, preferring windows closer to the focused one. 919 920This broadcast-like behaviour allows widgets to handle keypresses that should 921make sense even though their window does not actually have the keyboard focus. 922This feature should be used sparingly, to only capture one or two keypresses 923that really make sense; for example to capture the C<PageUp> and C<PageDown> 924keys in a scrolling list, or a numbered function key that performs some 925special action. 926 927=head2 mouse 928 929Emitted when a mouse button is pressed or released, the cursor moved while a 930button is held (a dragging event), or the wheel is scrolled. 931 932The following event names may be observed: 933 934=over 8 935 936=item press 937 938A mouse button has been pressed down on this cell 939 940=item drag_start 941 942The mouse was moved while a button was held, and was initially in the given 943cell 944 945=item drag 946 947The mouse was moved while a button was held, and is now in the given cell 948 949=item drag_outside 950 951The mouse was moved outside of the window that handled the C<drag_start> 952event, and is still being dragged. 953 954=item drag_drop 955 956A mouse button was released after having been moved, while in the given cell 957 958=item drag_stop 959 960The drag operation has finished. This event is always given directly to the 961window that handled the C<drag_start> event, rather than the window on which 962the mouse release event happened. 963 964=item release 965 966A mouse button was released after being pressed 967 968=item wheel 969 970The mouse wheel was moved. C<button> will indicate the wheel direction as a 971string C<up> or C<down>. 972 973=back 974 975The invoked code should return a true value if it considers the mouse event 976dealt with, or false to pass it up to its parent window. 977 978Once a dragging operation has begun via C<drag_start>, the window that handled 979the event will always receive C<drag>, C<drag_outside>, and an eventual 980C<drag_stop> event even if the mouse moves outside that window. No other 981window will receive a C<drag_outside> or C<drag_stop> event than the one that 982started the operation. 983 984=head2 geomchange 985 986Emitted when the window is resized or repositioned; i.e. whenever its geometry 987changes. 988 989=head2 expose 990 991Emitted when a region of the window is exposed by the L<expose> method, or 992implicitly because it or another window has changed size, been shown or 993hidden, or the stacking order has been changed. 994 995When invoked, render buffer passed in the event will have its origin set to 996that of the window, and its clipping will be set to the damage rectangle. 997 998If any child windows overlap the region, these will be exposed first, before 999the containing window. 1000 1001=head2 focus 1002 1003Emitted when the window gains or loses input focus. 1004 1005If the C<focus-child-notify> behavior is enabled, this callback is also 1006invoked for changes of focus on descendent windows. In this case, it is 1007passed an additional argument, being the immediate child window in which the 1008focus chain has now changed (which may or may not be the focused window 1009directly; it could itself be another ancestor). 1010 1011When a window gains focus, any of its ancestors that have 1012C<focus-child-notify> enabled will be informed first, from the outermost 1013inwards, before the window itself. When one loses focus, it is notified 1014first, and then its parents from the innermost outwards. 1015 1016=cut 1017 1018=head1 AUTHOR 1019 1020Paul Evans <leonerd@leonerd.org.uk> 1021 1022=cut 1023 10240x55AA; 1025