]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/toplevel.cpp
Implemented wxSpinButton for wxMotif.
[wxWidgets.git] / src / gtk1 / toplevel.cpp
CommitLineData
7d9f12f3
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: toplevel.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
18#ifdef __GNUG__
19 #pragma implementation "toplevel.h"
20#endif
21
22#ifdef __VMS
23#define XIconifyWindow XICONIFYWINDOW
24#endif
25
26#include "wx/defs.h"
27
28#include "wx/dialog.h"
29#include "wx/control.h"
30#include "wx/app.h"
31#include "wx/dcclient.h"
32
33#include <glib.h>
34#include <gdk/gdk.h>
35#include <gtk/gtk.h>
36#include <gdk/gdkkeysyms.h>
37#include <gdk/gdkx.h>
38
39#include "wx/gtk/win_gtk.h"
40
f618020a
MB
41#include "wx/unix/utilsx11.h"
42
7d9f12f3
VS
43// ----------------------------------------------------------------------------
44// idle system
45// ----------------------------------------------------------------------------
46
47extern void wxapp_install_idle_handler();
48extern bool g_isIdle;
7d9f12f3 49
7d9f12f3
VS
50// ----------------------------------------------------------------------------
51// data
52// ----------------------------------------------------------------------------
53
d7fa7eaa
RR
54extern wxList wxPendingDelete;
55
56extern int g_openDialogs;
57extern wxWindowGTK *g_delayedFocus;
7d9f12f3 58
7d9f12f3
VS
59//-----------------------------------------------------------------------------
60// "focus" from m_window
61//-----------------------------------------------------------------------------
62
63static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
64{
65 if (g_isIdle)
66 wxapp_install_idle_handler();
67
68 // This disables GTK's tab traversal
69 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
70 return TRUE;
71}
72
73//-----------------------------------------------------------------------------
74// "size_allocate"
75//-----------------------------------------------------------------------------
76
77static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxTopLevelWindowGTK *win )
78{
79 if (g_isIdle)
80 wxapp_install_idle_handler();
81
82 if (!win->m_hasVMT)
83 return;
84
85 if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
86 {
87/*
88 wxPrintf( "OnSize from " );
89 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
90 wxPrintf( win->GetClassInfo()->GetClassName() );
91 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
92 (int)alloc->y,
93 (int)alloc->width,
94 (int)alloc->height );
95*/
96
97 win->m_width = alloc->width;
98 win->m_height = alloc->height;
99 win->m_queuedFullRedraw = TRUE;
100 win->GtkUpdateSize();
101 }
102}
103
104//-----------------------------------------------------------------------------
105// "delete_event"
106//-----------------------------------------------------------------------------
107
108static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win )
109{
110 if (g_isIdle)
111 wxapp_install_idle_handler();
112
113 if (win->IsEnabled() &&
5152b0e5
JS
114 (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) ||
115 win->IsGrabbed()))
7d9f12f3
VS
116 win->Close();
117
118 return TRUE;
119}
120
121
122//-----------------------------------------------------------------------------
123// "configure_event"
124//-----------------------------------------------------------------------------
125
126static gint
7d9f12f3 127gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win )
7d9f12f3
VS
128{
129 if (g_isIdle)
130 wxapp_install_idle_handler();
131
48f72114 132 if (!win->m_hasVMT || !win->IsShown())
7d9f12f3
VS
133 return FALSE;
134
7d9f12f3
VS
135 int x = 0;
136 int y = 0;
137 gdk_window_get_root_origin( win->m_widget->window, &x, &y );
138 win->m_x = x;
139 win->m_y = y;
7d9f12f3
VS
140
141 wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
142 mevent.SetEventObject( win );
143 win->GetEventHandler()->ProcessEvent( mevent );
144
145 return FALSE;
146}
147
148//-----------------------------------------------------------------------------
149// "realize" from m_widget
150//-----------------------------------------------------------------------------
151
e1f14d22
RR
152// we cannot MWM hints and icons before the widget has been realized,
153// so we do this directly after realization
7d9f12f3
VS
154
155static void
6aeb6f2a
VZ
156gtk_frame_realized_callback( GtkWidget * WXUNUSED(widget),
157 wxTopLevelWindowGTK *win )
7d9f12f3
VS
158{
159 if (g_isIdle)
160 wxapp_install_idle_handler();
161
e1f14d22
RR
162 // All this is for Motif Window Manager "hints" and is supposed to be
163 // recognized by other WM as well. Not tested.
82c9f85c 164 gdk_window_set_decorations(win->m_widget->window,
f819b4a3 165 (GdkWMDecoration)win->m_gdkDecor);
82c9f85c 166 gdk_window_set_functions(win->m_widget->window,
f819b4a3 167 (GdkWMFunction)win->m_gdkFunc);
7d9f12f3 168
e1f14d22 169 // GTK's shrinking/growing policy
f819b4a3 170 if ((win->m_gdkFunc & GDK_FUNC_RESIZE) == 0)
7d9f12f3
VS
171 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
172 else
173 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
174
e1f14d22 175 // reset the icon
7efaed4d 176 wxIconBundle iconsOld = win->GetIcons();
6aeb6f2a 177 if ( iconsOld.GetIcon(-1).Ok() )
7d9f12f3 178 {
7d9f12f3 179 win->SetIcon( wxNullIcon );
7efaed4d 180 win->SetIcons( iconsOld );
7d9f12f3 181 }
7d9f12f3
VS
182}
183
184//-----------------------------------------------------------------------------
185// "map_event" from m_widget
186//-----------------------------------------------------------------------------
187
188static void
189gtk_frame_map_callback( GtkWidget * WXUNUSED(widget),
190 GdkEvent * WXUNUSED(event),
191 wxTopLevelWindow *win )
192{
193 win->SetIconizeState(FALSE);
194}
195
196//-----------------------------------------------------------------------------
197// "unmap_event" from m_widget
198//-----------------------------------------------------------------------------
199
200static void
201gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget),
202 GdkEvent * WXUNUSED(event),
203 wxTopLevelWindow *win )
204{
205 win->SetIconizeState(TRUE);
206}
207
208//-----------------------------------------------------------------------------
209// "expose_event" of m_client
210//-----------------------------------------------------------------------------
211
212static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
213{
214 GtkPizza *pizza = GTK_PIZZA(widget);
215
90350682
VZ
216 gtk_paint_flat_box (win->m_widget->style,
217 pizza->bin_window, GTK_STATE_NORMAL,
218 GTK_SHADOW_NONE,
219 &gdk_event->area,
220 win->m_widget,
221 (char *)"base",
222 0, 0, -1, -1);
7d9f12f3
VS
223
224 return TRUE;
225}
226
227//-----------------------------------------------------------------------------
228// "draw" of m_client
229//-----------------------------------------------------------------------------
230
52d6235d 231#ifndef __WXGTK20__
7d9f12f3
VS
232
233static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
234{
235 GtkPizza *pizza = GTK_PIZZA(widget);
236
90350682
VZ
237 gtk_paint_flat_box (win->m_widget->style,
238 pizza->bin_window, GTK_STATE_NORMAL,
239 GTK_SHADOW_NONE,
240 rect,
241 win->m_widget,
242 (char *)"base",
243 0, 0, -1, -1);
7d9f12f3
VS
244}
245
52d6235d
VZ
246#endif // GTK+ 1.x
247
7d9f12f3
VS
248// ----------------------------------------------------------------------------
249// wxTopLevelWindowGTK itself
250// ----------------------------------------------------------------------------
251
252//-----------------------------------------------------------------------------
253// InsertChild for wxTopLevelWindowGTK
254//-----------------------------------------------------------------------------
255
256/* Callback for wxTopLevelWindowGTK. This very strange beast has to be used because
257 * C++ has no virtual methods in a constructor. We have to emulate a
258 * virtual function here as wxWindows requires different ways to insert
259 * a child in container classes. */
260
261static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow* child )
262{
263 wxASSERT( GTK_IS_WIDGET(child->m_widget) );
264
265 if (!parent->m_insertInClientArea)
266 {
e1f14d22 267 // these are outside the client area
7d9f12f3
VS
268 wxTopLevelWindowGTK* frame = (wxTopLevelWindowGTK*) parent;
269 gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
270 GTK_WIDGET(child->m_widget),
271 child->m_x,
272 child->m_y,
273 child->m_width,
274 child->m_height );
275 }
276 else
277 {
e1f14d22 278 // these are inside the client area
7d9f12f3
VS
279 gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
280 GTK_WIDGET(child->m_widget),
e4b7b2b0
VS
281 child->m_x,
282 child->m_y,
7d9f12f3
VS
283 child->m_width,
284 child->m_height );
285 }
286
e1f14d22 287 // resize on OnInternalIdle
7d9f12f3
VS
288 parent->GtkUpdateSize();
289}
290
291// ----------------------------------------------------------------------------
292// wxTopLevelWindowGTK creation
293// ----------------------------------------------------------------------------
294
295void wxTopLevelWindowGTK::Init()
296{
297 m_sizeSet = FALSE;
298 m_miniEdge = 0;
299 m_miniTitle = 0;
300 m_mainWidget = (GtkWidget*) NULL;
301 m_insertInClientArea = TRUE;
7d9f12f3
VS
302 m_isIconized = FALSE;
303 m_fsIsShowing = FALSE;
304 m_themeEnabled = TRUE;
f819b4a3 305 m_gdkDecor = m_gdkFunc = 0;
5152b0e5 306 m_grabbed = FALSE;
7d9f12f3
VS
307}
308
309bool wxTopLevelWindowGTK::Create( wxWindow *parent,
f819b4a3
VS
310 wxWindowID id,
311 const wxString& title,
312 const wxPoint& pos,
313 const wxSize& sizeOrig,
314 long style,
315 const wxString &name )
7d9f12f3
VS
316{
317 // always create a frame of some reasonable, even if arbitrary, size (at
318 // least for MSW compatibility)
319 wxSize size = sizeOrig;
320 if ( size.x == -1 || size.y == -1 )
321 {
322 wxSize sizeDpy = wxGetDisplaySize();
323 if ( size.x == -1 )
324 size.x = sizeDpy.x / 3;
325 if ( size.y == -1 )
326 size.y = sizeDpy.y / 5;
327 }
328
329 wxTopLevelWindows.Append( this );
330
331 m_needParent = FALSE;
6aeb6f2a 332
7d9f12f3
VS
333 if (!PreCreation( parent, pos, size ) ||
334 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
335 {
336 wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") );
337 return FALSE;
338 }
339
340 m_title = title;
341
342 m_insertCallback = (wxInsertChildFunction) wxInsertChildInTopLevelWindow;
343
344 GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
345
346 if (style & wxFRAME_TOOL_WINDOW)
347 win_type = GTK_WINDOW_POPUP;
82c9f85c 348
f819b4a3 349 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
9e691f46
VZ
350 {
351 // there is no more GTK_WINDOW_DIALOG in 2.0
352#ifdef __WXGTK20__
353 win_type = GTK_WINDOW_TOPLEVEL;
354#else
7d9f12f3 355 win_type = GTK_WINDOW_DIALOG;
9e691f46
VZ
356#endif
357 }
7d9f12f3
VS
358
359 m_widget = gtk_window_new( win_type );
360
7cd95599 361 if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)) &&
2c990ec0 362 (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG))
7cd95599 363 {
7d9f12f3 364 gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
7cd95599 365 }
7d9f12f3
VS
366
367 if (!name.IsEmpty())
368 gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
369
7d9f12f3
VS
370 gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
371 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
372
373 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
374 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
375
e1f14d22 376 // m_mainWidget holds the toolbar, the menubar and the client area
7d9f12f3
VS
377 m_mainWidget = gtk_pizza_new();
378 gtk_widget_show( m_mainWidget );
379 GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
380 gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
381
e1f14d22 382 // for m_mainWidget themes
7d9f12f3
VS
383 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event",
384 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
4e5a4c69 385#ifndef __WXGTK20__
7d9f12f3
VS
386 gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw",
387 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
4e5a4c69 388#endif
7d9f12f3 389
e1f14d22 390 // m_wxwindow only represents the client area without toolbar and menubar
7d9f12f3
VS
391 m_wxwindow = gtk_pizza_new();
392 gtk_widget_show( m_wxwindow );
393 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
394
e1f14d22
RR
395 // we donm't allow the frame to get the focus as otherwise
396 // the frame will grab it at arbitrary focus changes
7d9f12f3
VS
397 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
398
399 if (m_parent) m_parent->AddChild( this );
400
e1f14d22 401 // the user resized the frame by dragging etc.
7d9f12f3
VS
402 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
403 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
404
405 PostCreation();
406
407 if ((m_x != -1) || (m_y != -1))
408 gtk_widget_set_uposition( m_widget, m_x, m_y );
6aeb6f2a 409
e1f14d22 410 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3 411
e1f14d22
RR
412 // we cannot set MWM hints and icons before the widget has
413 // been realized, so we do this directly after realization
7d9f12f3
VS
414 gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
415 GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
416
e1f14d22 417 // the only way to get the window size is to connect to this event
7d9f12f3
VS
418 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
419 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
420
e1f14d22 421 // map and unmap for iconized state
7d9f12f3
VS
422 gtk_signal_connect( GTK_OBJECT(m_widget), "map_event",
423 GTK_SIGNAL_FUNC(gtk_frame_map_callback), (gpointer)this );
424 gtk_signal_connect( GTK_OBJECT(m_widget), "unmap_event",
425 GTK_SIGNAL_FUNC(gtk_frame_unmap_callback), (gpointer)this );
426
e1f14d22 427 // the only way to get the window size is to connect to this event
7d9f12f3
VS
428 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
429 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
430
e1f14d22 431 // disable native tab traversal
7d9f12f3
VS
432 gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
433 GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
434
e1f14d22 435 // decorations
f819b4a3
VS
436 if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
437 {
438 m_gdkDecor = 0;
439 m_gdkFunc = 0;
440 }
441 else
442 {
443 m_gdkDecor = (long) GDK_DECOR_BORDER;
444 m_gdkFunc = (long) GDK_FUNC_MOVE;
82c9f85c 445
f819b4a3 446 // All this is for Motif Window Manager "hints" and is supposed to be
e1f14d22 447 // recognized by other WMs as well.
f819b4a3
VS
448 if ((style & wxCAPTION) != 0)
449 m_gdkDecor |= GDK_DECOR_TITLE;
450 if ((style & wxSYSTEM_MENU) != 0)
451 {
452 m_gdkFunc |= GDK_FUNC_CLOSE;
453 m_gdkDecor |= GDK_DECOR_MENU;
454 }
455 if ((style & wxMINIMIZE_BOX) != 0)
456 {
457 m_gdkFunc |= GDK_FUNC_MINIMIZE;
458 m_gdkDecor |= GDK_DECOR_MINIMIZE;
459 }
460 if ((style & wxMAXIMIZE_BOX) != 0)
461 {
462 m_gdkFunc |= GDK_FUNC_MAXIMIZE;
463 m_gdkDecor |= GDK_DECOR_MAXIMIZE;
464 }
465 if ((style & wxRESIZE_BORDER) != 0)
466 {
467 m_gdkFunc |= GDK_FUNC_RESIZE;
468 m_gdkDecor |= GDK_DECOR_RESIZEH;
469 }
470 }
471
7d9f12f3
VS
472 return TRUE;
473}
474
475wxTopLevelWindowGTK::~wxTopLevelWindowGTK()
476{
5152b0e5
JS
477 if (m_grabbed)
478 {
479 wxASSERT_MSG( FALSE, "Window still grabbed");
480 RemoveGrab();
481 }
482
7d9f12f3 483 m_isBeingDeleted = TRUE;
6aeb6f2a 484
710968c3
VZ
485 // it may also be GtkScrolledWindow in the case of an MDI child
486 if (GTK_IS_WINDOW(m_widget))
487 {
488 gtk_window_set_focus( GTK_WINDOW(m_widget), NULL );
489 }
7d9f12f3
VS
490
491 wxTopLevelWindows.DeleteObject( this );
492
493 if (wxTheApp->GetTopWindow() == this)
494 wxTheApp->SetTopWindow( (wxWindow*) NULL );
495
496 if ((wxTopLevelWindows.Number() == 0) &&
497 (wxTheApp->GetExitOnFrameDelete()))
498 {
499 wxTheApp->ExitMainLoop();
500 }
501}
502
503bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style )
504{
505 if (show == m_fsIsShowing) return FALSE; // return what?
506
507 m_fsIsShowing = show;
508
509 if (show)
510 {
82f2d919
VS
511 m_fsSaveGdkFunc = m_gdkFunc;
512 m_fsSaveGdkDecor = m_gdkDecor;
7d9f12f3
VS
513 m_fsSaveFlag = style;
514 GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y );
515 GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height );
516
517 gtk_widget_hide( m_widget );
518 gtk_widget_unrealize( m_widget );
519
82f2d919
VS
520 m_gdkDecor = (long) GDK_DECOR_BORDER;
521 m_gdkFunc = (long) GDK_FUNC_MOVE;
7d9f12f3
VS
522
523 int x;
524 int y;
525 wxDisplaySize( &x, &y );
526 SetSize( 0, 0, x, y );
527
528 gtk_widget_realize( m_widget );
529 gtk_widget_show( m_widget );
530 }
531 else
532 {
533 gtk_widget_hide( m_widget );
534 gtk_widget_unrealize( m_widget );
535
82f2d919
VS
536 m_gdkFunc = m_fsSaveGdkFunc;
537 m_gdkDecor = m_fsSaveGdkDecor;
7d9f12f3
VS
538
539 SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height );
540
541 gtk_widget_realize( m_widget );
542 gtk_widget_show( m_widget );
543 }
544
545 return TRUE;
546}
547
548// ----------------------------------------------------------------------------
549// overridden wxWindow methods
550// ----------------------------------------------------------------------------
551
552bool wxTopLevelWindowGTK::Show( bool show )
553{
554 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
555
556 if (show && !m_sizeSet)
557 {
558 /* by calling GtkOnSize here, we don't have to call
559 either after showing the frame, which would entail
560 much ugly flicker or from within the size_allocate
561 handler, because GTK 1.1.X forbids that. */
562
563 GtkOnSize( m_x, m_y, m_width, m_height );
564 }
565
566 return wxWindow::Show( show );
567}
568
569void wxTopLevelWindowGTK::DoMoveWindow(int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(width), int WXUNUSED(height) )
570{
571 wxFAIL_MSG( wxT("DoMoveWindow called for wxTopLevelWindowGTK") );
572}
573
574void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
575{
576 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
577
e1f14d22 578 // this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow
7d9f12f3
VS
579 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
580
e1f14d22 581 // avoid recursions
7d9f12f3
VS
582 if (m_resizing)
583 return;
584 m_resizing = TRUE;
585
586 int old_x = m_x;
587 int old_y = m_y;
588
589 int old_width = m_width;
590 int old_height = m_height;
591
592 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
593 {
594 if (x != -1) m_x = x;
595 if (y != -1) m_y = y;
7d9f12f3
VS
596 }
597 else
598 {
599 m_x = x;
600 m_y = y;
7d9f12f3 601 }
d44c23ce
RR
602 if (width != -1) m_width = width;
603 if (height != -1) m_height = height;
7d9f12f3
VS
604
605/*
606 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
607 {
608 if (width == -1) m_width = 80;
609 }
610
611 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
612 {
613 if (height == -1) m_height = 26;
614 }
615*/
616
e7dda1ff
VS
617 int minWidth = GetMinWidth(),
618 minHeight = GetMinHeight(),
619 maxWidth = GetMaxWidth(),
620 maxHeight = GetMaxHeight();
621
622 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
623 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
624 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
625 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
626
627 if ((m_x != -1) || (m_y != -1))
628 {
629 if ((m_x != old_x) || (m_y != old_y))
630 {
631 gtk_widget_set_uposition( m_widget, m_x, m_y );
632 }
633 }
634
635 if ((m_width != old_width) || (m_height != old_height))
636 {
e1f14d22
RR
637 if (m_widget->window)
638 gdk_window_resize( m_widget->window, m_width, m_height );
639 else
640 gtk_window_set_default_size( GTK_WINDOW(m_widget), m_width, m_height );
7d9f12f3
VS
641
642 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
643 done either directly before the frame is shown or in idle time
644 so that different calls to SetSize() don't lead to flicker. */
645 m_sizeSet = FALSE;
646 }
647
648 m_resizing = FALSE;
649}
650
651void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
652{
653 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
654
655 wxWindow::DoGetClientSize( width, height );
656 if (height)
657 {
e1f14d22 658 // mini edge
7d9f12f3
VS
659 *height -= m_miniEdge*2 + m_miniTitle;
660 }
661 if (width)
662 {
663 *width -= m_miniEdge*2;
664 }
665}
666
667void wxTopLevelWindowGTK::DoSetClientSize( int width, int height )
668{
669 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
670
82c9f85c 671 DoSetSize(-1, -1,
7d9f12f3
VS
672 width + m_miniEdge*2, height + m_miniEdge*2 + m_miniTitle, 0);
673}
674
675void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
82c9f85c 676 int width, int height )
7d9f12f3
VS
677{
678 // due to a bug in gtk, x,y are always 0
679 // m_x = x;
680 // m_y = y;
681
e1f14d22 682 // avoid recursions
7d9f12f3
VS
683 if (m_resizing) return;
684 m_resizing = TRUE;
685
686 if ( m_wxwindow == NULL ) return;
687
688 m_width = width;
689 m_height = height;
690
0d53fc34 691 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
7d9f12f3 692 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
0d53fc34 693 set in wxFrame::Create so it is used to check what kind of frame we
7d9f12f3
VS
694 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
695 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
696 importantly) m_mainWidget */
697
e7dda1ff
VS
698 int minWidth = GetMinWidth(),
699 minHeight = GetMinHeight(),
700 maxWidth = GetMaxWidth(),
701 maxHeight = GetMaxHeight();
702
703 if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth;
704 if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
705 if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth;
706 if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;
7d9f12f3
VS
707
708 if (m_mainWidget)
709 {
e1f14d22 710 // set size hints
801225c1
RL
711 gint flag = 0; // GDK_HINT_POS;
712 GdkGeometry geom;
713
e7dda1ff
VS
714 if ((minWidth != -1) || (minHeight != -1)) flag |= GDK_HINT_MIN_SIZE;
715 if ((maxWidth != -1) || (maxHeight != -1)) flag |= GDK_HINT_MAX_SIZE;
801225c1 716
e7dda1ff
VS
717 geom.min_width = minWidth;
718 geom.min_height = minHeight;
801225c1
RL
719
720 // Because of the way we set GDK_HINT_MAX_SIZE above, if either of
721 // maxHeight or maxWidth is set, we must set them both, else the
722 // remaining -1 will be taken literally.
723
724 // I'm certain this also happens elsewhere, and is the probable
725 // cause of other such things as:
726 // Gtk-WARNING **: gtk_widget_size_allocate():
727 // attempt to allocate widget with width 65535 and height 600
728 // but I don't have time to track them all now..
729 //
730 // Really we need to encapulate all this height/width business and
731 // stop any old method from ripping at the members directly and
732 // scattering -1's without regard for who might resolve them later.
733
734 geom.max_width = ( maxHeight == -1 ) ? maxWidth
735 : ( maxWidth == -1 ) ? wxGetDisplaySize().GetWidth()
736 : maxWidth ;
737
738 geom.max_height = ( maxWidth == -1 ) ? maxHeight // ( == -1 here )
739 : ( maxHeight == -1 ) ? wxGetDisplaySize().GetHeight()
740 : maxHeight ;
741
7d9f12f3
VS
742 gtk_window_set_geometry_hints( GTK_WINDOW(m_widget),
743 (GtkWidget*) NULL,
744 &geom,
745 (GdkWindowHints) flag );
746
747 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
748 * menubar, the toolbar and the client area, which is represented by
749 * m_wxwindow.
750 * this hurts in the eye, but I don't want to call SetSize()
751 * because I don't want to call any non-native functions here. */
752
753 int client_x = m_miniEdge;
754 int client_y = m_miniEdge + m_miniTitle;
755 int client_w = m_width - 2*m_miniEdge;
756 int client_h = m_height - 2*m_miniEdge - m_miniTitle;
801225c1 757
7d9f12f3
VS
758 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
759 m_wxwindow,
760 client_x, client_y, client_w, client_h );
761 }
762 else
763 {
e1f14d22
RR
764 // If there is no m_mainWidget between m_widget and m_wxwindow there
765 // is no need to set the size or position of m_wxwindow.
7d9f12f3
VS
766 }
767
768 m_sizeSet = TRUE;
769
770 // send size event to frame
771 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
772 event.SetEventObject( this );
773 GetEventHandler()->ProcessEvent( event );
774
775 m_resizing = FALSE;
776}
777
778void wxTopLevelWindowGTK::OnInternalIdle()
779{
780 if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
781 {
782 GtkOnSize( m_x, m_y, m_width, m_height );
783
784 // we'll come back later
785 if (g_isIdle)
786 wxapp_install_idle_handler();
787 return;
788 }
789
6aeb6f2a
VZ
790 // set the focus if not done yet and if we can already do it
791 if ( GTK_WIDGET_REALIZED(m_wxwindow) )
792 {
cc06fe74
MB
793 if ( g_delayedFocus &&
794 wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this )
6aeb6f2a
VZ
795 {
796 g_delayedFocus->SetFocus();
797 g_delayedFocus = NULL;
798 }
799 }
800
7d9f12f3
VS
801 wxWindow::OnInternalIdle();
802}
803
7d9f12f3
VS
804// ----------------------------------------------------------------------------
805// frame title/icon
806// ----------------------------------------------------------------------------
807
808void wxTopLevelWindowGTK::SetTitle( const wxString &title )
809{
810 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
811
812 m_title = title;
813 gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
814}
815
f618020a 816void wxTopLevelWindowGTK::DoSetIcon( const wxIcon &icon )
7d9f12f3 817{
f618020a 818 if ( !icon.Ok() )
7d9f12f3
VS
819 return;
820
821 if (!m_widget->window)
822 return;
823
824 wxMask *mask = icon.GetMask();
825 GdkBitmap *bm = (GdkBitmap *) NULL;
826 if (mask) bm = mask->GetBitmap();
827
828 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
829}
830
f618020a
MB
831void wxTopLevelWindowGTK::SetIcon( const wxIcon &icon )
832{
833 SetIcons( wxIconBundle( icon ) );
834}
835
836void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons )
837{
838 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
839 GdkWindow* window = m_widget->window;
f618020a
MB
840
841 wxTopLevelWindowBase::SetIcons( icons );
842
843 DoSetIcon( icons.GetIcon( -1 ) );
52d6235d
VZ
844 if ( window )
845 {
7efaed4d
MB
846 wxSetIconsX11( (WXDisplay*)GDK_WINDOW_XDISPLAY( window ),
847 (WXWindow)GDK_WINDOW_XWINDOW( window ), icons );
52d6235d 848 }
f618020a
MB
849}
850
7d9f12f3
VS
851// ----------------------------------------------------------------------------
852// frame state: maximized/iconized/normal
853// ----------------------------------------------------------------------------
854
855void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize))
856{
857 wxFAIL_MSG( _T("not implemented") );
858}
859
860bool wxTopLevelWindowGTK::IsMaximized() const
861{
862 // wxFAIL_MSG( _T("not implemented") );
863
864 // This is an approximation
865 return FALSE;
866}
867
868void wxTopLevelWindowGTK::Restore()
869{
870 wxFAIL_MSG( _T("not implemented") );
871}
872
873void wxTopLevelWindowGTK::Iconize( bool iconize )
874{
875 if (iconize)
876 {
877 GdkWindow *window = m_widget->window;
878
879 // you should do it later, for example from OnCreate() handler
880 wxCHECK_RET( window, _T("frame not created yet - can't iconize") );
881
882 XIconifyWindow( GDK_WINDOW_XDISPLAY( window ),
883 GDK_WINDOW_XWINDOW( window ),
884 DefaultScreen( GDK_DISPLAY() ) );
885 }
886}
887
888bool wxTopLevelWindowGTK::IsIconized() const
889{
890 return m_isIconized;
891}
892
893void wxTopLevelWindowGTK::SetIconizeState(bool iconize)
894{
895 if ( iconize != m_isIconized )
896 {
897 m_isIconized = iconize;
898 (void)SendIconizeEvent(iconize);
899 }
900}
901
5152b0e5
JS
902void wxTopLevelWindowGTK::AddGrab()
903{
904 if (!m_grabbed)
905 {
906 m_grabbed = TRUE;
907 gtk_grab_add( m_widget );
908 gtk_main();
909 gtk_grab_remove( m_widget );
910 }
911}
912
913void wxTopLevelWindowGTK::RemoveGrab()
914{
915 if (m_grabbed)
916 {
917 gtk_main_quit();
918 m_grabbed = FALSE;
919 }
920}
801225c1
RL
921
922// vi:sts=4:sw=4:et