1<?xml version="1.0" encoding="UTF-8" ?> 2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> 3 4<chapter id='Geometry_Management'> 5<title>Geometry Management</title> 6 7<para> 8A widget does not directly control its size and location; 9rather, its parent is responsible for controlling them. 10Although the position of children is usually left up to their parent, 11the widgets themselves often have the best idea of their optimal sizes 12and, possibly, preferred locations. 13</para> 14 15<para> 16To resolve physical layout conflicts between sibling widgets and between 17a widget and its parent, the Intrinsics provide the geometry management mechanism. 18Almost all 19composite 20widgets have a geometry manager specified in the <emphasis remap='I'>geometry_manager</emphasis> field 21in the widget class record that is responsible for the size, position, and 22stacking order of the widget's children. 23The only exception is fixed boxes, 24which create their children themselves and can ensure that 25their children will never make a geometry request. 26</para> 27 28<sect1 id="Initiating_Geometry_Changes"> 29<title>Initiating Geometry Changes</title> 30 31<para> 32Parents, children, and clients each initiate geometry changes differently. 33Because a parent has absolute control of its children's geometry, 34it changes the geometry directly by calling 35<function>XtMoveWidget</function>, 36<xref linkend='XtResizeWidget' xrefstyle='select: title'/>, 37or 38<xref linkend='XtConfigureWidget' xrefstyle='select: title'/>. 39A child must ask its parent for a geometry change by calling 40<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 41or 42<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/>. 43An application or other client code initiates a geometry change by calling 44<xref linkend='XtSetValues' xrefstyle='select: title'/> 45on the appropriate geometry fields, 46thereby giving the widget the opportunity to modify or reject the client 47request before it gets propagated to the parent and the opportunity 48to respond appropriately to the parent's reply. 49</para> 50 51<para> 52When a widget that needs to change its size, position, border width, 53or stacking depth asks its parent's geometry manager to make the desired 54changes, 55the geometry manager can allow the request, disallow the request, or 56suggest a compromise. 57</para> 58 59<para> 60When the geometry manager is asked to change the geometry of a child, 61the geometry manager may also rearrange and resize any or all 62of the other children that it controls. 63The geometry manager can move children around freely using 64<xref linkend='XtMoveWidget' xrefstyle='select: title'/>. 65When it resizes a child (that is, changes the width, height, or 66border width) other than the one making the request, 67it should do so by calling 68<xref linkend='XtResizeWidget' xrefstyle='select: title'/>. 69The requesting child may be given special treatment; see 70<xref linkend='Child_Geometry_Management_The_geometry_manager_Procedure' />. 71It can simultaneously move and resize a child with a single call to 72<xref linkend='XtConfigureWidget' xrefstyle='select: title'/>. 73</para> 74 75<para> 76Often, geometry managers find that they can satisfy a request only if 77they can reconfigure a widget that they are not in control of; in particular, 78the 79composite 80widget may want to change its own size. 81In this case, 82the geometry manager makes a request to its parent's geometry manager. 83Geometry requests can cascade this way to arbitrary depth. 84</para> 85 86<para> 87Because such cascaded arbitration of widget geometry can involve extended 88negotiation, 89windows are not actually allocated to widgets at application 90startup until all widgets are satisfied with their geometry; 91see <xref linkend='Creating_Widgets' /> and 92<xref linkend='Realizing_Widgets' />. 93</para> 94 95<note> 96<orderedlist> 97 <listitem> 98 <para> 99The Intrinsics treatment of stacking requests is deficient in several areas. 100Stacking requests for unrealized widgets are granted but will have no effect. 101In addition, there is no way to do an 102<xref linkend='XtSetValues' xrefstyle='select: title'/> 103that will generate a stacking geometry request. 104 </para> 105 </listitem> 106 <listitem> 107 <para> 108After a successful geometry request (one that returned 109<function>XtGeometryYes</function>), 110a widget does not know whether its resize procedure has been called. 111Widgets should have resize procedures that can be called more than once 112without ill effects. 113 </para> 114 </listitem> 115</orderedlist> 116</note> 117</sect1> 118 119<sect1 id="General_Geometry_Manager_Requests"> 120<title>General Geometry Manager Requests</title> 121<para> 122When making a geometry request, the child specifies an 123<function>XtWidgetGeometry</function> 124structure. 125</para> 126 127<programlisting> 128typedef unsigned long XtGeometryMask; 129typedef struct { 130 XtGeometryMask request_mode; 131 Position x, y; 132 Dimension width, height; 133 Dimension border_width; 134 Widget sibling; 135 int stack_mode; 136} XtWidgetGeometry; 137</programlisting> 138 139<para> 140To make a general geometry manager request from a widget, use 141<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>. 142</para> 143 144<funcsynopsis id='XtMakeGeometryRequest'> 145<funcprototype> 146<funcdef>XtGeometryResult <function>XtMakeGeometryRequest</function></funcdef> 147 <paramdef>Widget <parameter>w</parameter></paramdef> 148 <paramdef>XtWidgetGeometry *<parameter>request</parameter></paramdef> 149 <paramdef>XtWidgetGeometry *<parameter>reply_return</parameter></paramdef> 150</funcprototype> 151</funcsynopsis> 152 153<variablelist> 154 <varlistentry> 155 <term> 156 <emphasis remap='I'>w</emphasis> 157 </term> 158 <listitem> 159 <para> 160Specifies the widget making the request. Must be of class RectObj or any subclass thereof. 161 </para> 162 </listitem> 163 </varlistentry> 164 <varlistentry> 165 <term> 166 <emphasis remap='I'>request</emphasis> 167 </term> 168 <listitem> 169 <para> 170Specifies the desired widget geometry (size, position, border width, 171and stacking order). 172 </para> 173 </listitem> 174 </varlistentry> 175 <varlistentry> 176 <term> 177 <emphasis remap='I'>reply_return</emphasis> 178 </term> 179 <listitem> 180 <para> 181Returns the allowed widget size, or may be NULL 182if the requesting widget is not interested in handling 183<function>XtGeometryAlmost</function>. 184 </para> 185 </listitem> 186 </varlistentry> 187</variablelist> 188 189 190<para> 191Depending on the condition, 192<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 193performs the following: 194</para> 195 196<itemizedlist spacing='compact'> 197 <listitem> 198 <para> 199If the widget is unmanaged or the widget's parent is not realized, 200it makes the changes and returns 201<function>XtGeometryYes</function>. 202 </para> 203 </listitem> 204 <listitem> 205 <para> 206If the parent's class is not a subclass of 207<function>compositeWidgetClass</function> 208or the parent's <emphasis remap='I'>geometry_manager</emphasis> field is NULL, 209it issues an error. 210 </para> 211 </listitem> 212 <listitem> 213 <para> 214If the widget's <emphasis remap='I'>being_destroyed</emphasis> field is 215<function>True</function>, 216it returns 217<function>XtGeometryNo</function>. 218 </para> 219 </listitem> 220 <listitem> 221 <para> 222If the widget <emphasis remap='I'>x</emphasis>, <emphasis remap='I'>y</emphasis>, <emphasis remap='I'>width</emphasis>, <emphasis remap='I'>height</emphasis>, and 223<emphasis remap='I'>border_width</emphasis> fields are 224all equal to the requested values, 225it returns 226<function>XtGeometryYes</function>; 227otherwise, it calls the parent's geometry_manager procedure 228with the given parameters. 229 </para> 230 </listitem> 231 <listitem> 232 <para> 233If the parent's geometry manager returns 234<function>XtGeometryYes</function> 235and if 236<function>XtCWQueryOnly</function> 237is not set in <emphasis remap='I'>request->request_mode</emphasis> 238and if the widget is realized, 239<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 240calls the 241<function>XConfigureWindow</function> 242Xlib function to reconfigure the widget's window (set its size, location, 243and stacking order as appropriate). 244 </para> 245 </listitem> 246 <listitem> 247 <para> 248If the geometry manager returns 249<function>XtGeometryDone</function>, 250the change has been approved and actually has been done. 251In this case, 252<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 253does no configuring and returns 254<function>XtGeometryYes</function>. 255<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 256never returns 257<function>XtGeometryDone</function>. 258 </para> 259 </listitem> 260 <listitem> 261 <para> 262Otherwise, 263<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 264just returns the resulting value from the parent's geometry manager. 265 </para> 266 </listitem> 267</itemizedlist> 268 269<para> 270Children of primitive widgets are always unmanaged; therefore, 271<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 272always returns 273<function>XtGeometryYes</function> 274when called by a child of a primitive widget. 275</para> 276 277<para> 278The return codes from geometry managers are 279</para> 280 281<programlisting> 282typedef enum { 283 XtGeometryYes, 284 XtGeometryNo, 285 XtGeometryAlmost, 286 XtGeometryDone 287} XtGeometryResult; 288</programlisting> 289 290<para> 291The <emphasis remap='I'>request_mode</emphasis> definitions are from 292<filename class="headerfile"><X11/X.h></filename>. 293</para> 294 295<informaltable frame='none'> 296 <?dbfo keep-together="always" ?> 297 <tgroup cols='3' align='left' colsep='0' rowsep='0'> 298 <colspec colwidth='1.0*' colname='c1'/> 299 <colspec colwidth='1.0*' colname='c2'/> 300 <colspec colwidth='1.0*' colname='c3'/> 301 <tbody> 302 <row> 303 <entry>#define</entry> 304 <entry><function>CWX</function></entry> 305 <entry>(1<<0)</entry> 306 </row> 307 <row> 308 <entry>#define</entry> 309 <entry><function>CWY</function></entry> 310 <entry>(1<<1)</entry> 311 </row> 312 <row> 313 <entry>#define</entry> 314 <entry><function>CWWidth</function></entry> 315 <entry>(1<<2)</entry> 316 </row> 317 <row> 318 <entry>#define</entry> 319 <entry><function>CWHeight</function></entry> 320 <entry>(1<<3)</entry> 321 </row> 322 <row> 323 <entry>#define</entry> 324 <entry><function>CWBorderWidth</function></entry> 325 <entry>(1<<4)</entry> 326 </row> 327 <row> 328 <entry>#define</entry> 329 <entry><function>CWSibling</function></entry> 330 <entry>(1<<5)</entry> 331 </row> 332 <row> 333 <entry>#define</entry> 334 <entry><function>CWStackMode</function></entry> 335 <entry>(1<<6)</entry> 336 </row> 337 </tbody> 338 </tgroup> 339</informaltable> 340 341<para> 342The Intrinsics also support the following value. 343</para> 344 345<informaltable frame='none'> 346 <?dbfo keep-together="always" ?> 347 <tgroup cols='3' align='left' colsep='0' rowsep='0'> 348 <colspec colwidth='1.0*' colname='c1'/> 349 <colspec colwidth='1.0*' colname='c2'/> 350 <colspec colwidth='1.0*' colname='c3'/> 351 <tbody> 352 <row> 353 <entry>#define</entry> 354 <entry><function>XtCWQueryOnly</function></entry> 355 <entry>(1<<7)</entry> 356 </row> 357 </tbody> 358 </tgroup> 359</informaltable> 360 361<para> 362<function>XtCWQueryOnly</function> 363indicates that the corresponding geometry request is only a query 364as to what would happen if this geometry request were made 365and that no widgets should actually be changed. 366</para> 367 368<para> 369<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>, 370like the 371<function>XConfigureWindow</function> 372Xlib function, uses <emphasis remap='I'>request_mode</emphasis> to determine which fields in the 373<function>XtWidgetGeometry</function> 374structure the caller wants to specify. 375</para> 376 377<para> 378The <emphasis remap='I'>stack_mode</emphasis> definitions are from 379<filename class="headerfile"><X11/X.h></filename>: 380</para> 381 382<informaltable frame='none'> 383 <?dbfo keep-together="always" ?> 384 <tgroup cols='3' align='left' colsep='0' rowsep='0'> 385 <colspec colwidth='1.0*' colname='c1'/> 386 <colspec colwidth='1.0*' colname='c2'/> 387 <colspec colwidth='1.0*' colname='c3'/> 388 <tbody> 389 <row> 390 <entry>#define</entry> 391 <entry><function>Above</function></entry> 392 <entry>0</entry> 393 </row> 394 <row> 395 <entry>#define</entry> 396 <entry><function>Below</function></entry> 397 <entry>1</entry> 398 </row> 399 <row> 400 <entry>#define</entry> 401 <entry><function>TopIf</function></entry> 402 <entry>2</entry> 403 </row> 404 <row> 405 <entry>#define</entry> 406 <entry><function>BottomIf</function></entry> 407 <entry>3</entry> 408 </row> 409 <row> 410 <entry>#define</entry> 411 <entry><function>Opposite</function></entry> 412 <entry>4</entry> 413 </row> 414 </tbody> 415 </tgroup> 416</informaltable> 417 418<para> 419The Intrinsics also support the following value. 420</para> 421 422<informaltable frame='none'> 423 <?dbfo keep-together="always" ?> 424 <tgroup cols='3' align='left' colsep='0' rowsep='0'> 425 <colspec colwidth='1.0*' colname='c1'/> 426 <colspec colwidth='1.0*' colname='c2'/> 427 <colspec colwidth='1.0*' colname='c3'/> 428 <tbody> 429 <row> 430 <entry>#define</entry> 431 <entry><function>XtSMDontChange</function></entry> 432 <entry>5</entry> 433 </row> 434 </tbody> 435 </tgroup> 436</informaltable> 437 438<para> 439For definition and behavior of 440<function>Above</function>, 441<function>Below</function>, 442<function>TopIf</function>, 443<function>BottomIf</function>, 444and 445<function>Opposite</function>, 446<olink targetdoc='libX11' targetptr='Configuring_Windows' >BLAH</olink> 447in <olink targetptr='libX11' targetdoc='libX11'>Xlib — C Language X Interface</olink>. 448<function>XtSMDontChange</function> 449indicates that the widget wants its current stacking order preserved. 450</para> 451</sect1> 452 453<sect1 id="Resize_Requests"> 454<title>Resize Requests</title> 455<para> 456To make a simple resize request from a widget, you can use 457<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/> 458as an alternative to 459<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>. 460</para> 461 462<funcsynopsis id='XtMakeResizeRequest'> 463<funcprototype> 464<funcdef>typedef XtGeometryResult <function>XtMakeResizeRequest</function></funcdef> 465 <paramdef>Widget <parameter>w</parameter></paramdef> 466 <paramdef>Dimension <parameter>width</parameter></paramdef> 467 <paramdef>Dimension *<parameter>width_return</parameter></paramdef> 468</funcprototype> 469</funcsynopsis> 470 471<variablelist> 472 <varlistentry> 473 <term> 474 <emphasis remap='I'>w</emphasis> 475 </term> 476 <listitem> 477 <para> 478Specifies the widget making the request. Must be of class RectObj or any subclass thereof. 479 </para> 480 </listitem> 481 </varlistentry> 482 <varlistentry> 483 <term> 484 <emphasis remap='I'>width</emphasis> 485 </term> 486 <listitem> 487 <para> 488Specify the desired widget width and height. 489 </para> 490 </listitem> 491 </varlistentry> 492 <varlistentry> 493 <term> 494 <emphasis remap='I'>height</emphasis> 495 </term> 496 <listitem> 497 <para></para> 498 </listitem> 499 </varlistentry> 500 <varlistentry> 501 <term> 502 <emphasis remap='I'>width_return</emphasis> 503 </term> 504 <listitem> 505 <para> 506Return the allowed widget width and height. 507 </para> 508 </listitem> 509 </varlistentry> 510 <varlistentry> 511 <term> 512 <emphasis remap='I'>height_return</emphasis> 513 </term> 514 <listitem> 515 <para></para> 516 </listitem> 517 </varlistentry> 518</variablelist> 519 520 521<para> 522The 523<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/> 524function, a simple interface to 525<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>, 526creates an 527<function>XtWidgetGeometry</function> 528structure and specifies that width and height should change 529by setting <emphasis remap='I'>request_mode</emphasis> to 530<function>CWWidth</function> 531<function>|</function> 532<function>CWHeight</function>. 533The geometry manager is free to modify any of the other window attributes 534(position or stacking order) to satisfy the resize request. 535If the return value is 536<function>XtGeometryAlmost</function>, 537<emphasis remap='I'>width_return</emphasis> and <emphasis remap='I'>height_return</emphasis> contain a compromise width and height. 538If these are acceptable, 539the widget should immediately call 540<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/> 541again and request that the compromise width and height be applied. 542If the widget is not interested in 543<function>XtGeometryAlmost</function> 544replies, 545it can pass NULL for <emphasis remap='I'>width_return</emphasis> and <emphasis remap='I'>height_return</emphasis>. 546</para> 547</sect1> 548 549<sect1 id="Potential_Geometry_Changes"> 550<title>Potential Geometry Changes</title> 551<para> 552Sometimes a geometry manager cannot respond to 553a geometry request from a child without first making a geometry request 554to the widget's own parent (the original requestor's grandparent). 555If the request to the grandparent would allow the parent to satisfy the 556original request, 557the geometry manager can make the intermediate geometry request 558as if it were the originator. 559On the other hand, 560if the geometry manager already has determined that the original request 561cannot be completely satisfied (for example, if it always denies 562position changes), 563it needs to tell the grandparent to respond to the intermediate request 564without actually changing the geometry 565because it does not know if the child will accept the compromise. 566To accomplish this, the geometry manager uses 567<function>XtCWQueryOnly</function> 568in the intermediate request. 569</para> 570 571<para> 572When 573<function>XtCWQueryOnly</function> 574is used, the geometry manager needs to cache 575enough information to exactly reconstruct the intermediate request. 576If the grandparent's response to the intermediate query was 577<function>XtGeometryAlmost</function>, 578the geometry manager needs to cache the entire 579reply geometry in the event the child accepts the parent's compromise. 580</para> 581 582<para> 583If the grandparent's response was 584<function>XtGeometryAlmost</function>, 585it may also be necessary to cache the entire reply geometry from 586the grandparent when 587<function>XtCWQueryOnly</function> 588is not used. 589If the geometry manager is still able to satisfy the original request, 590it may immediately accept the grandparent's compromise 591and then act on the child's request. 592If the grandparent's compromise geometry is insufficient to allow 593the child's request and if the geometry manager is willing to offer 594a different compromise to the child, 595the grandparent's compromise should not be accepted until the child 596has accepted the new compromise. 597</para> 598 599<para> 600Note that a compromise geometry returned with 601<function>XtGeometryAlmost</function> 602is guaranteed only for the next call to the same widget; 603therefore, a cache of size 1 is sufficient. 604</para> 605</sect1> 606 607<sect1 id="Child_Geometry_Management_The_geometry_manager_Procedure"> 608<title>Child Geometry Management: The geometry_manager Procedure</title> 609<para> 610The geometry_manager procedure pointer in a composite widget class is of type 611<xref linkend='XtGeometryHandler' xrefstyle='select: title'/>. 612</para> 613 614<funcsynopsis id='XtGeometryHandler'> 615<funcprototype> 616<funcdef>typedef XtGeometryResult *<function>XtGeometryHandler</function></funcdef> 617 <paramdef>Widget <parameter>w</parameter></paramdef> 618 <paramdef>XtWidgetGeometry *<parameter>request</parameter></paramdef> 619 <paramdef>XtWidgetGeometry *<parameter>geometry_return</parameter></paramdef> 620</funcprototype> 621</funcsynopsis> 622 623<variablelist> 624 <varlistentry> 625 <term> 626 <emphasis remap='I'>w</emphasis> 627 </term> 628 <listitem> 629 <para> 630Passes the widget making the request. 631 </para> 632 </listitem> 633 </varlistentry> 634 <varlistentry> 635 <term> 636 <emphasis remap='I'>request</emphasis> 637 </term> 638 <listitem> 639 <para> 640Passes the new geometry the child desires. 641 </para> 642 </listitem> 643 </varlistentry> 644 <varlistentry> 645 <term> 646 <emphasis remap='I'>geometry_return</emphasis> 647 </term> 648 <listitem> 649 <para> 650Passes a geometry structure in which the geometry manager may store a 651compromise. 652 </para> 653 </listitem> 654 </varlistentry> 655</variablelist> 656 657<para> 658A class can inherit its superclass's geometry manager during class 659initialization. 660</para> 661 662<para> 663A bit set to zero in the request's <emphasis remap='I'>request_mode</emphasis> 664field means that the child widget 665does not care about the value of the corresponding field, 666so the geometry manager can change this field as it wishes. 667A bit set to 1 means that the child wants that geometry element set 668to the value in the corresponding field. 669</para> 670 671<para> 672If the geometry manager can satisfy all changes requested 673and if 674<function>XtCWQueryOnly</function> 675is not specified, 676it updates the widget's <emphasis remap='I'>x</emphasis>, <emphasis remap='I'>y</emphasis>, <emphasis remap='I'>width</emphasis>, <emphasis remap='I'>height</emphasis>, 677and <emphasis remap='I'>border_width</emphasis> fields 678appropriately. 679Then, it returns 680<function>XtGeometryYes</function>, 681and the values pointed to by the <emphasis remap='I'>geometry_return</emphasis> argument are undefined. 682The widget's window is moved and resized automatically by 683<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>. 684</para> 685 686<para> 687Homogeneous composite widgets often find it convenient to treat the widget 688making the request the same as any other widget, including reconfiguring 689it using 690<xref linkend='XtConfigureWidget' xrefstyle='select: title'/> 691or 692<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 693as part of its layout process, unless 694<function>XtCWQueryOnly</function> 695is specified. 696If it does this, 697it should return 698<function>XtGeometryDone</function> 699to inform 700<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 701that it does not need to do the configuration itself. 702</para> 703 704<note> 705<para> 706To remain 707compatible with layout techniques used in older widgets (before 708<function>XtGeometryDone</function> 709was added to the Intrinsics), a geometry manager should avoid using 710<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 711or 712<xref linkend='XtConfigureWidget' xrefstyle='select: title'/> 713on the child making 714the request because the layout process of the child may be in an 715intermediate state in which it is not prepared to handle a call to its 716resize procedure. A self-contained widget set may choose this 717alternative geometry management scheme, however, provided that it 718clearly warns widget developers of the compatibility consequences. 719</para> 720</note> 721 722<para> 723Although 724<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 725resizes the widget's window 726(if the geometry 727manager returns 728<function>XtGeometryYes</function>), 729it does not call the widget class's resize procedure. 730The requesting widget must perform whatever 731resizing calculations are needed explicitly. 732</para> 733 734<para> 735If the geometry manager disallows the request, 736the widget cannot change its geometry. 737The values pointed to by <emphasis remap='I'>geometry_return</emphasis> are undefined, 738and the geometry manager returns 739<function>XtGeometryNo</function>. 740</para> 741 742<para> 743Sometimes the geometry manager cannot satisfy the request exactly 744but may be able to satisfy a similar request. 745That is, 746it could satisfy only a subset of the requests (for example, 747size but not position) or a lesser request 748(for example, it cannot make the child as big as the 749request but it can make the child bigger than its current size). 750In such cases, 751the geometry manager fills in the structure pointed to by 752<emphasis remap='I'>geometry_return</emphasis> with the actual changes 753it is willing to make, including an appropriate <emphasis remap='I'>request_mode</emphasis> mask, and returns 754<function>XtGeometryAlmost</function>. 755If a bit in <emphasis remap='I'>geometry_return->request_mode</emphasis> is zero, 756the geometry manager agrees not to change the corresponding value 757if <emphasis remap='I'>geometry_return</emphasis> is used immediately 758in a new request. 759If a bit is 1, 760the geometry manager does change that element to the corresponding 761value in <emphasis remap='I'>geometry_return</emphasis>. 762More bits may be set in <emphasis remap='I'>geometry_return->request_mode</emphasis> 763than in the original request if 764the geometry manager intends to change other fields should the 765child accept the compromise. 766</para> 767 768<para> 769When 770<function>XtGeometryAlmost</function> 771is returned, 772the widget must decide if the compromise suggested in <emphasis remap='I'>geometry_return</emphasis> 773is acceptable. 774If it is, the widget must not change its geometry directly; 775rather, it must make another call to 776<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/>. 777</para> 778 779<para> 780If the next geometry request from this child uses the 781<emphasis remap='I'>geometry_return</emphasis> values filled in by the geometry manager with an 782<function>XtGeometryAlmost</function> 783return and if there have been no intervening geometry requests on 784either its parent or any of its other children, 785the geometry manager must grant the request, if possible. 786That is, if the child asks immediately with the returned geometry, 787it should get an answer of 788<function>XtGeometryYes</function>. 789However, 790dynamic behavior in 791the user's window manager may affect the final outcome. 792</para> 793 794<para> 795To return 796<function>XtGeometryYes</function>, 797the geometry manager frequently rearranges the position of other managed 798children by calling 799<xref linkend='XtMoveWidget' xrefstyle='select: title'/>. 800However, a few geometry managers may sometimes change the 801size of other managed children by calling 802<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 803or 804<xref linkend='XtConfigureWidget' xrefstyle='select: title'/>. 805If 806<function>XtCWQueryOnly</function> 807is specified, 808the geometry manager must return data describing 809how it would react to this geometry 810request without actually moving or resizing any widgets. 811</para> 812 813<para> 814Geometry managers must not assume that the <emphasis remap='I'>request</emphasis> 815and <emphasis remap='I'>geometry_return</emphasis> arguments point to independent storage. 816The caller is permitted to use the same field for both, 817and the geometry manager must allocate its own temporary storage, 818if necessary. 819</para> 820</sect1> 821 822<sect1 id="Widget_Placement_and_Sizing"> 823<title>Widget Placement and Sizing</title> 824<para> 825To move a sibling widget of the child making the geometry request, 826the parent uses 827<xref linkend='XtMoveWidget' xrefstyle='select: title'/>. 828</para> 829 830<funcsynopsis id='XtMoveWidget'> 831<funcprototype> 832<funcdef>void <function>XtMoveWidget</function></funcdef> 833 <paramdef>Widget <parameter>w</parameter></paramdef> 834 <paramdef>Position <parameter>x</parameter></paramdef> 835 <paramdef>Position <parameter>y</parameter></paramdef> 836</funcprototype> 837</funcsynopsis> 838 839<variablelist> 840 <varlistentry> 841 <term> 842 <emphasis remap='I'>w</emphasis> 843 </term> 844 <listitem> 845 <para> 846Specifies the widget. Must be of class RectObj or any subclass thereof. 847 </para> 848 </listitem> 849 </varlistentry> 850 <varlistentry> 851 <term> 852 <emphasis remap='I'>x</emphasis> 853 </term> 854 <listitem> 855 <para></para> 856 </listitem> 857 </varlistentry> 858 <varlistentry> 859 <term> 860 <emphasis remap='I'>y</emphasis> 861 </term> 862 <listitem> 863 <para> 864Specify the new widget x and y coordinates. 865 </para> 866 </listitem> 867 </varlistentry> 868</variablelist> 869 870<para> 871The 872<xref linkend='XtMoveWidget' xrefstyle='select: title'/> 873function returns immediately if the specified geometry fields 874are the same as the old values. 875Otherwise, 876<xref linkend='XtMoveWidget' xrefstyle='select: title'/> 877writes the new <emphasis remap='I'>x</emphasis> and <emphasis remap='I'>y</emphasis> values into the object 878and, if the object is a widget and is realized, issues an Xlib 879<function>XMoveWindow</function> 880call on the widget's window. 881</para> 882 883<para> 884To resize a sibling widget of the child making the geometry request, 885the parent uses 886<xref linkend='XtResizeWidget' xrefstyle='select: title'/>. 887</para> 888 889<funcsynopsis id='XtResizeWidget'> 890<funcprototype> 891<funcdef>void <function>XtResizeWidget</function></funcdef> 892 <paramdef>Widget <parameter>w</parameter></paramdef> 893 <paramdef>Dimension <parameter>width</parameter></paramdef> 894 <paramdef>Dimension <parameter>height</parameter></paramdef> 895 <paramdef>Dimension <parameter>border_width</parameter></paramdef> 896</funcprototype> 897</funcsynopsis> 898 899<variablelist> 900 <varlistentry> 901 <term> 902 <emphasis remap='I'>w</emphasis> 903 </term> 904 <listitem> 905 <para> 906Specifies the widget. Must be of class RectObj or any subclass thereof. 907 </para> 908 </listitem> 909 </varlistentry> 910 <varlistentry> 911 <term> 912 <emphasis remap='I'>width</emphasis> 913 </term> 914 <listitem> 915 <para></para> 916 </listitem> 917 </varlistentry> 918 <varlistentry> 919 <term> 920 <emphasis remap='I'>height</emphasis> 921 </term> 922 <listitem> 923 <para></para> 924 </listitem> 925 </varlistentry> 926 <varlistentry> 927 <term> 928 <emphasis remap='I'>border_width</emphasis> 929 </term> 930 <listitem> 931 <para> 932Specify the new widget size. 933 </para> 934 </listitem> 935 </varlistentry> 936</variablelist> 937 938<para> 939The 940<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 941function returns immediately if the specified geometry fields 942are the same as the old values. 943Otherwise, 944<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 945writes the new <emphasis remap='I'>width</emphasis>, <emphasis remap='I'>height</emphasis>, and <emphasis remap='I'>border_width</emphasis> values into 946the object and, if the object is a widget and is realized, issues an 947<function>XConfigureWindow</function> 948call on the widget's window. 949</para> 950 951<para> 952If the new width or height is different from the old values, 953<xref linkend='XtResizeWidget' xrefstyle='select: title'/> 954calls the object's resize procedure to notify it of the size change. 955</para> 956 957<para> 958To move and resize the sibling widget of the child making the geometry request, 959the parent uses 960<xref linkend='XtConfigureWidget' xrefstyle='select: title'/>. 961</para> 962 963<funcsynopsis id='XtConfigureWidget'> 964<funcprototype> 965<funcdef>void <function>XtConfigureWidget</function></funcdef> 966 <paramdef>Widget <parameter>w</parameter></paramdef> 967 <paramdef>Position <parameter>x</parameter></paramdef> 968 <paramdef>Position <parameter>y</parameter></paramdef> 969 <paramdef>Dimension <parameter>width</parameter></paramdef> 970 <paramdef>Dimension <parameter>height</parameter></paramdef> 971 <paramdef>Dimension <parameter>border_width</parameter></paramdef> 972</funcprototype> 973</funcsynopsis> 974 975<variablelist> 976 <varlistentry> 977 <term> 978 <emphasis remap='I'>w</emphasis> 979 </term> 980 <listitem> 981 <para> 982Specifies the widget. Must be of class RectObj or any subclass thereof. 983 </para> 984 </listitem> 985 </varlistentry> 986 <varlistentry> 987 <term> 988 <emphasis remap='I'>x</emphasis> 989 </term> 990 <listitem> 991 <para></para> 992 </listitem> 993 </varlistentry> 994 <varlistentry> 995 <term> 996 <emphasis remap='I'>y</emphasis> 997 </term> 998 <listitem> 999 <para> 1000Specify the new widget x and y coordinates. 1001 </para> 1002 </listitem> 1003 </varlistentry> 1004 <varlistentry> 1005 <term> 1006 <emphasis remap='I'>width</emphasis> 1007 </term> 1008 <listitem> 1009 <para></para> 1010 </listitem> 1011 </varlistentry> 1012 <varlistentry> 1013 <term> 1014 <emphasis remap='I'>height</emphasis> 1015 </term> 1016 <listitem> 1017 <para></para> 1018 </listitem> 1019 </varlistentry> 1020 <varlistentry> 1021 <term> 1022 <emphasis remap='I'>border_width</emphasis> 1023 </term> 1024 <listitem> 1025 <para> 1026Specify the new widget size. 1027 </para> 1028 </listitem> 1029 </varlistentry> 1030</variablelist> 1031 1032<para> 1033The 1034<xref linkend='XtConfigureWidget' xrefstyle='select: title'/> 1035function returns immediately if the specified new geometry fields 1036are all equal to the current values. 1037Otherwise, 1038<xref linkend='XtConfigureWidget' xrefstyle='select: title'/> 1039writes the new <emphasis remap='I'>x</emphasis>, <emphasis remap='I'>y</emphasis>, <emphasis remap='I'>width</emphasis>, <emphasis remap='I'>height</emphasis>, 1040and <emphasis remap='I'>border_width</emphasis> values 1041into the object and, if the object is a widget and is realized, makes an Xlib 1042<function>XConfigureWindow</function> 1043call on the widget's window. 1044</para> 1045 1046<para> 1047If the new width or height is different from its old value, 1048<xref linkend='XtConfigureWidget' xrefstyle='select: title'/> 1049calls the object's resize procedure to notify it of the size change; 1050otherwise, it simply returns. 1051</para> 1052 1053<para> 1054To resize a child widget that already has the new values of its width, 1055height, and border width, the parent uses 1056<xref linkend='XtResizeWindow' xrefstyle='select: title'/>. 1057</para> 1058 1059<funcsynopsis id='XtResizeWindow'> 1060<funcprototype> 1061<funcdef>void <function>XtResizeWindow</function></funcdef> 1062 <paramdef>Widget <parameter>w</parameter></paramdef> 1063</funcprototype> 1064</funcsynopsis> 1065 1066<variablelist> 1067 <varlistentry> 1068 <term> 1069 <emphasis remap='I'>w</emphasis> 1070 </term> 1071 <listitem> 1072 <para> 1073Specifies the widget. Must be of class Core or any subclass thereof. 1074 </para> 1075 </listitem> 1076 </varlistentry> 1077</variablelist> 1078 1079<para> 1080The 1081<xref linkend='XtResizeWindow' xrefstyle='select: title'/> 1082function calls the 1083<function>XConfigureWindow</function> 1084Xlib function to make the window of the specified widget match its width, 1085height, and border width. 1086This request is done unconditionally because there is no 1087inexpensive way to tell if these 1088values match the current values. 1089Note that the widget's resize procedure is not called. 1090</para> 1091 1092<para> 1093There are very few times to use 1094<xref linkend='XtResizeWindow' xrefstyle='select: title'/>; 1095instead, the parent should use 1096<xref linkend='XtResizeWidget' xrefstyle='select: title'/>. 1097</para> 1098</sect1> 1099 1100<sect1 id="Preferred_Geometry"> 1101<title>Preferred Geometry</title> 1102<para> 1103Some parents may be willing to adjust their layouts to accommodate the 1104preferred geometries of their children. 1105They can use 1106<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1107to obtain the preferred geometry 1108and, as they see fit, can use or ignore any portion of the response. 1109</para> 1110 1111<para> 1112To query a child widget's preferred geometry, use 1113<xref linkend='XtQueryGeometry' xrefstyle='select: title'/>. 1114</para> 1115 1116<funcsynopsis id='XtQueryGeometry'> 1117<funcprototype> 1118<funcdef>XtGeometryResult <function>XtQueryGeometry</function></funcdef> 1119 <paramdef>Widget <parameter>w</parameter></paramdef> 1120 <paramdef>XtWidgetGeometry *<parameter>intended</parameter></paramdef> 1121 <paramdef>XtWidgetGeometry *<parameter>preferred_return</parameter></paramdef> 1122</funcprototype> 1123</funcsynopsis> 1124 1125<variablelist> 1126 <varlistentry> 1127 <term> 1128 <emphasis remap='I'>w</emphasis> 1129 </term> 1130 <listitem> 1131 <para> 1132Specifies the widget. Must be of class RectObj or any subclass thereof. 1133 </para> 1134 </listitem> 1135 </varlistentry> 1136 <varlistentry> 1137 <term> 1138 <emphasis remap='I'>intended</emphasis> 1139 </term> 1140 <listitem> 1141 <para> 1142Specifies the new geometry the parent plans to give to the child, or 1143NULL. 1144 </para> 1145 </listitem> 1146 </varlistentry> 1147 <varlistentry> 1148 <term> 1149 <emphasis remap='I'>preferred_return</emphasis> 1150 </term> 1151 <listitem> 1152 <para> 1153Returns the child widget's preferred geometry. 1154 </para> 1155 </listitem> 1156 </varlistentry> 1157</variablelist> 1158 1159<para> 1160To discover a child's preferred geometry, 1161the child's parent stores the new 1162geometry in the corresponding fields of 1163the intended structure, sets the corresponding bits in <emphasis remap='I'>intended.request_mode</emphasis>, 1164and calls 1165<xref linkend='XtQueryGeometry' xrefstyle='select: title'/>. 1166The parent should set only those fields that are important to it so 1167that the child can determine whether it may be able to attempt changes to 1168other fields. 1169</para> 1170 1171<para> 1172<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1173clears all bits in the <emphasis remap='I'>preferred_return->request_mode</emphasis> 1174field and checks the 1175<emphasis remap='I'>query_geometry</emphasis> field of the specified widget's class record. 1176If <emphasis remap='I'>query_geometry</emphasis> is not NULL, 1177<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1178calls the query_geometry procedure and passes as arguments the 1179specified widget, <emphasis remap='I'>intended</emphasis>, and <emphasis remap='I'>preferred_return</emphasis> structures. 1180If the <emphasis remap='I'>intended</emphasis> argument is NULL, 1181<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1182replaces it with a pointer to an 1183<function>XtWidgetGeometry</function> 1184structure with <emphasis remap='I'>request_mode</emphasis> equal to zero before calling the 1185query_geometry procedure. 1186</para> 1187 1188<note> 1189<para> 1190If 1191<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1192is called from within a geometry_manager 1193procedure for the widget that issued 1194<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 1195or 1196<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/>, 1197the results 1198are not guaranteed to be consistent with the requested changes. The 1199change request passed to the geometry manager takes precedence over 1200the preferred geometry. 1201</para> 1202</note> 1203 1204<para> 1205The query_geometry procedure pointer is of type 1206<xref linkend='XtGeometryHandler' xrefstyle='select: title'/>. 1207</para> 1208 1209<funcsynopsis id='_XtGeometryHandler'> 1210<funcprototype> 1211<funcdef>typedef XtGeometryResult <function>(*XtGeometryHandler)</function></funcdef> 1212 <paramdef>Widget <parameter>w</parameter></paramdef> 1213 <paramdef>XtWidgetGeometry *<parameter>request</parameter></paramdef> 1214 <paramdef>XtWidgetGeometry *<parameter>preferred_return</parameter></paramdef> 1215</funcprototype> 1216</funcsynopsis> 1217 1218<variablelist> 1219 <varlistentry> 1220 <term> 1221 <emphasis remap='I'>w</emphasis> 1222 </term> 1223 <listitem> 1224 <para> 1225Passes the child widget whose preferred geometry is required. 1226 </para> 1227 </listitem> 1228 </varlistentry> 1229 <varlistentry> 1230 <term> 1231 <emphasis remap='I'>request</emphasis> 1232 </term> 1233 <listitem> 1234 <para> 1235Passes the geometry changes that the parent plans to make. 1236 </para> 1237 </listitem> 1238 </varlistentry> 1239 <varlistentry> 1240 <term> 1241 <emphasis remap='I'>preferred_return</emphasis> 1242 </term> 1243 <listitem> 1244 <para> 1245Passes a structure in which the child returns its preferred geometry. 1246 </para> 1247 </listitem> 1248 </varlistentry> 1249</variablelist> 1250 1251<para> 1252The query_geometry procedure is expected to examine the bits set in 1253<emphasis remap='I'>request->request_mode</emphasis>, evaluate the preferred geometry of the widget, 1254and store the result in <emphasis remap='I'>preferred_return</emphasis> 1255(setting the bits in <emphasis remap='I'>preferred_return->request_mode</emphasis> corresponding 1256to those geometry fields that it cares about). 1257If the proposed geometry change is acceptable without modification, 1258the query_geometry procedure should return 1259<function>XtGeometryYes</function>. 1260If at least one field in <emphasis remap='I'>preferred_return</emphasis> 1261with a bit set in <emphasis remap='I'>preferred_return->request_mode</emphasis> 1262is different 1263from the corresponding field in <emphasis remap='I'>request</emphasis> 1264or if a bit was set in <emphasis remap='I'>preferred_return->request_mode</emphasis> 1265that was not set in the request, 1266the query_geometry procedure should return 1267<function>XtGeometryAlmost</function>. 1268If the preferred geometry is identical to the current geometry, 1269the query_geometry procedure should return 1270<function>XtGeometryNo</function>. 1271</para> 1272 1273<note><para> 1274The query_geometry procedure may assume 1275that no 1276<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/> 1277or 1278<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 1279is in progress 1280for the specified widget; that is, it is not required to construct 1281a reply consistent with the requested geometry if such a request 1282were actually outstanding. 1283</para></note> 1284 1285<para> 1286After calling the query_geometry procedure 1287or if the <emphasis remap='I'>query_geometry</emphasis> field is NULL, 1288<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1289examines all the unset bits in <emphasis remap='I'>preferred_return->request_mode</emphasis> 1290and sets the corresponding fields in <emphasis remap='I'>preferred_return</emphasis> 1291to the current values from the widget instance. 1292If 1293<function>CWStackMode</function> 1294is not set, 1295the <emphasis remap='I'>stack_mode</emphasis> field is set to 1296<function>XtSMDontChange</function>. 1297<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1298returns the value returned by the query_geometry procedure or 1299<function>XtGeometryYes</function> 1300if the <emphasis remap='I'>query_geometry</emphasis> field is NULL. 1301</para> 1302 1303<para> 1304Therefore, the caller can interpret a return of 1305<function>XtGeometryYes</function> 1306as not needing to evaluate the contents of the reply and, more important, 1307not needing to modify its layout plans. 1308A return of 1309<function>XtGeometryAlmost</function> 1310means either that both the parent and the child expressed interest 1311in at least one common field and the child's preference does not match 1312the parent's intentions or that the child expressed interest in a field that 1313the parent might need to consider. 1314A return value of 1315<function>XtGeometryNo</function> 1316means that both the parent and the child expressed interest in a field and 1317that the child suggests that the field's current value in the widget instance 1318is its preferred value. 1319In addition, whether or not the caller ignores the return value or the 1320reply mask, it is guaranteed that the <emphasis remap='I'>preferred_return</emphasis> structure contains complete 1321geometry information for the child. 1322</para> 1323 1324<para> 1325Parents are expected to call 1326<xref linkend='XtQueryGeometry' xrefstyle='select: title'/> 1327in their layout routine and wherever else the information is significant 1328after change_managed has been called. 1329The first time it is invoked, 1330the changed_managed procedure may assume that the child's current geometry 1331is its preferred geometry. 1332Thus, the child is still responsible for storing values 1333into its own geometry during its initialize procedure. 1334</para> 1335</sect1> 1336 1337<sect1 id="Size_Change_Management_The_resize_Procedure"> 1338<title>Size Change Management: The resize Procedure</title> 1339<para> 1340A child can be resized by its parent at any time. 1341Widgets usually need to know when they have changed size 1342so that they can lay out their displayed data again to match the new size. 1343When a parent resizes a child, it calls 1344<xref linkend='XtResizeWidget' xrefstyle='select: title'/>, 1345which updates the geometry fields in the widget, 1346configures the window if the widget is realized, 1347and calls the child's resize procedure to notify the child. 1348The resize procedure pointer is of type 1349<xref linkend='XtWidgetProc' xrefstyle='select: title'/>. 1350</para> 1351 1352<para> 1353If a class need not recalculate anything when a widget is resized, 1354it can specify NULL for the <emphasis remap='I'>resize</emphasis> field in its class record. 1355This is an unusual case and should occur only for widgets 1356with very trivial display semantics. 1357The resize procedure takes a widget as its only argument. 1358The <emphasis remap='I'>x</emphasis>, <emphasis remap='I'>y</emphasis>, <emphasis remap='I'>width</emphasis>, <emphasis remap='I'>height</emphasis>, 1359and <emphasis remap='I'>border_width</emphasis> fields of the widget contain the new values. 1360The resize procedure should recalculate the layout of internal data 1361as needed. 1362(For example, a centered Label in a window that changes size 1363should recalculate the starting position of the text.) 1364The widget must obey resize as a command and must not treat it as a request. 1365A widget must not issue an 1366<xref linkend='XtMakeGeometryRequest' xrefstyle='select: title'/> 1367or 1368<xref linkend='XtMakeResizeRequest' xrefstyle='select: title'/> 1369call from its resize procedure. 1370</para> 1371</sect1> 1372</chapter> 1373