void wxTopLevelWindowGTK::GTKConfigureEvent(int x, int y) { wxPoint point; #ifdef GDK_WINDOWING_X11 if (gs_decorCacheValid) { const DecorSize& decorSize = GetCachedDecorSize(); point.x = x - decorSize.left; point.y = y - decorSize.top; } else #endif { gtk_window_get_position(GTK_WINDOW(m_widget), &point.x, &point.y); } if (m_x != point.x || m_y != point.y) { m_x = point.x; m_y = point.y; wxMoveEvent event(point, GetId()); event.SetEventObject(this); HandleWindowEvent(event); } }
void wxTopLevelWindowGTK::GTKUpdateDecorSize(const DecorSize& decorSize) { if (!IsMaximized() && !IsFullScreen()) GetCachedDecorSize() = decorSize; if (m_updateDecorSize && memcmp(&m_decorSize, &decorSize, sizeof(DecorSize))) { m_useCachedClientSize = false; const wxSize diff( decorSize.left - m_decorSize.left + decorSize.right - m_decorSize.right, decorSize.top - m_decorSize.top + decorSize.bottom - m_decorSize.bottom); m_decorSize = decorSize; bool resized = false; if (m_minWidth > 0 || m_minHeight > 0 || m_maxWidth > 0 || m_maxHeight > 0) { // update size hints, they depend on m_decorSize DoSetSizeHints(m_minWidth, m_minHeight, m_maxWidth, m_maxHeight, m_incWidth, m_incHeight); } if (m_deferShow) { // keep overall size unchanged by shrinking m_widget int w, h; GTKDoGetSize(&w, &h); // but not if size would be less than minimum, it won't take effect if (w >= m_minWidth - (decorSize.left + decorSize.right) && h >= m_minHeight - (decorSize.top + decorSize.bottom)) { gtk_window_resize(GTK_WINDOW(m_widget), w, h); if (!gtk_window_get_resizable(GTK_WINDOW(m_widget))) gtk_widget_set_size_request(GTK_WIDGET(m_widget), w, h); resized = true; } } if (!resized) { // adjust overall size to match change in frame extents m_width += diff.x; m_height += diff.y; if (m_width < 1) m_width = 1; if (m_height < 1) m_height = 1; m_clientWidth = 0; gtk_widget_queue_resize(m_wxwindow); } } if (m_deferShow) { // gtk_widget_show() was deferred, do it now m_deferShow = false; DoGetClientSize(&m_clientWidth, &m_clientHeight); wxSizeEvent sizeEvent(GetSize(), GetId()); sizeEvent.SetEventObject(this); HandleWindowEvent(sizeEvent); gtk_widget_show(m_widget); wxShowEvent showEvent(GetId(), true); showEvent.SetEventObject(this); HandleWindowEvent(showEvent); } }
void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize) { if (!IsMaximized() && !IsFullScreen()) GetCachedDecorSize() = decorSize; if (m_updateDecorSize && m_decorSize != decorSize) { const wxSize diff = decorSize - m_decorSize; m_decorSize = decorSize; bool resized = false; if (m_deferShow) { // keep overall size unchanged by shrinking m_widget int w, h; GTKDoGetSize(&w, &h); // but not if size would be less than minimum, it won't take effect const wxSize minSize = GetMinSize(); if (w >= minSize.x && h >= minSize.y) { gtk_window_resize(GTK_WINDOW(m_widget), w, h); resized = true; } } if (!resized) { // adjust overall size to match change in frame extents m_width += diff.x; m_height += diff.y; if (m_width < 0) m_width = 0; if (m_height < 0) m_height = 0; m_oldClientWidth = 0; gtk_widget_queue_resize(m_wxwindow); } } if (m_deferShow) { // gtk_widget_show() was deferred, do it now m_deferShow = false; GetClientSize(&m_oldClientWidth, &m_oldClientHeight); wxSizeEvent sizeEvent(GetSize(), GetId()); sizeEvent.SetEventObject(this); HandleWindowEvent(sizeEvent); gtk_widget_show(m_widget); wxShowEvent showEvent(GetId(), true); showEvent.SetEventObject(this); HandleWindowEvent(showEvent); } }
bool wxTopLevelWindowGTK::Create( wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& sizeOrig, long style, const wxString &name ) { // always create a frame of some reasonable, even if arbitrary, size (at // least for MSW compatibility) wxSize size = sizeOrig; size.x = WidthDefault(size.x); size.y = HeightDefault(size.y); wxTopLevelWindows.Append( this ); if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); return false; } m_title = title; // NB: m_widget may be !=NULL if it was created by derived class' Create, // e.g. in wxTaskBarIconAreaGTK if (m_widget == NULL) { #if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 // we must create HildonWindow and not a normal GtkWindow as the latter // doesn't look correctly in Maemo environment and it must also be // registered with the main program object m_widget = hildon_window_new(); hildon_program_add_window(wxTheApp->GetHildonProgram(), HILDON_WINDOW(m_widget)); #else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) { // Tell WM that this is a dialog window and make it center // on parent by default (this is what GtkDialog ctor does): gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_position(GTK_WINDOW(m_widget), GTK_WIN_POS_CENTER_ON_PARENT); } else { if (style & wxFRAME_TOOL_WINDOW) { gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_UTILITY); // On some WMs, like KDE, a TOOL_WINDOW will still show // on the taskbar, but on Gnome a TOOL_WINDOW will not. // For consistency between WMs and with Windows, we // should set the NO_TASKBAR flag which will apply // the set_skip_taskbar_hint if it is available, // ensuring no taskbar entry will appear. style |= wxFRAME_NO_TASKBAR; } } #endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 g_object_ref(m_widget); } wxWindow *topParent = wxGetTopLevelParent(m_parent); if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) && (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) || (style & wxFRAME_FLOAT_ON_PARENT))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(topParent->m_widget) ); } if (style & wxFRAME_NO_TASKBAR) { gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE); } if (style & wxSTAY_ON_TOP) { gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE); } if (style & wxMAXIMIZE) gtk_window_maximize(GTK_WINDOW(m_widget)); #if 0 if (!name.empty()) gtk_window_set_role( GTK_WINDOW(m_widget), wxGTK_CONV( name ) ); #endif gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) ); gtk_widget_set_can_focus(m_widget, false); g_signal_connect (m_widget, "delete_event", G_CALLBACK (gtk_frame_delete_callback), this); // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow) m_mainWidget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show( m_mainWidget ); gtk_widget_set_can_focus(m_mainWidget, false); gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget ); // m_wxwindow is the client area m_wxwindow = wxPizza::New(); gtk_widget_show( m_wxwindow ); gtk_box_pack_start(GTK_BOX(m_mainWidget), m_wxwindow, true, true, 0); // we donm't allow the frame to get the focus as otherwise // the frame will grab it at arbitrary focus changes gtk_widget_set_can_focus(m_wxwindow, false); if (m_parent) m_parent->AddChild( this ); g_signal_connect(m_wxwindow, "size_allocate", G_CALLBACK(size_allocate), this); PostCreation(); #ifndef __WXGTK3__ if ((m_x != -1) || (m_y != -1)) gtk_widget_set_uposition( m_widget, m_x, m_y ); #endif // for some reported size corrections g_signal_connect (m_widget, "map_event", G_CALLBACK (gtk_frame_map_callback), this); // for iconized state g_signal_connect (m_widget, "window_state_event", G_CALLBACK (gtk_frame_window_state_callback), this); // for wxMoveEvent g_signal_connect (m_widget, "configure_event", G_CALLBACK (gtk_frame_configure_callback), this); // activation g_signal_connect_after (m_widget, "focus_in_event", G_CALLBACK (gtk_frame_focus_in_callback), this); g_signal_connect_after (m_widget, "focus_out_event", G_CALLBACK (gtk_frame_focus_out_callback), this); // GTK processes key events at the top level first, which handles for // menu accelerators and shortcuts before passing the event on to the // focus child window to begin propagation. We want to propagate // first, so we connect gtk_window_propagate_key_event to // key_press_event. g_signal_connect (m_widget, "key_press_event", G_CALLBACK (gtk_window_propagate_key_event), NULL); #ifdef GDK_WINDOWING_X11 #ifdef __WXGTK3__ if (GDK_IS_X11_SCREEN(gtk_window_get_screen(GTK_WINDOW(m_widget)))) #endif { gtk_widget_add_events(m_widget, GDK_PROPERTY_CHANGE_MASK); g_signal_connect(m_widget, "property_notify_event", G_CALLBACK(property_notify_event), this); } #endif // GDK_WINDOWING_X11 // translate wx decorations styles into Motif WM hints (they are recognized // by other WMs as well) // always enable moving the window as we have no separate flag for enabling // it m_gdkFunc = GDK_FUNC_MOVE; if ( style & wxCLOSE_BOX ) m_gdkFunc |= GDK_FUNC_CLOSE; if ( style & wxMINIMIZE_BOX ) m_gdkFunc |= GDK_FUNC_MINIMIZE; if ( style & wxMAXIMIZE_BOX ) m_gdkFunc |= GDK_FUNC_MAXIMIZE; if ( (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER) ) { m_gdkDecor = 0; } else // have border { m_gdkDecor = GDK_DECOR_BORDER; if ( style & wxCAPTION ) m_gdkDecor |= GDK_DECOR_TITLE; if ( style & wxSYSTEM_MENU ) m_gdkDecor |= GDK_DECOR_MENU; if ( style & wxMINIMIZE_BOX ) m_gdkDecor |= GDK_DECOR_MINIMIZE; if ( style & wxMAXIMIZE_BOX ) m_gdkDecor |= GDK_DECOR_MAXIMIZE; if ( style & wxRESIZE_BORDER ) { m_gdkFunc |= GDK_FUNC_RESIZE; m_gdkDecor |= GDK_DECOR_RESIZEH; } } // GTK sometimes chooses very small size if max size hint is not explicitly set DoSetSizeHints(m_minWidth, m_minHeight, m_maxWidth, m_maxHeight, m_incWidth, m_incHeight); m_decorSize = GetCachedDecorSize(); int w, h; GTKDoGetSize(&w, &h); gtk_window_set_default_size(GTK_WINDOW(m_widget), w, h); return true; }
bool wxTopLevelWindowGTK::Create( wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& sizeOrig, long style, const wxString &name ) { wxSize size(sizeOrig); if (!size.IsFullySpecified()) size.SetDefaults(GetDefaultSize()); wxTopLevelWindows.Append( this ); if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) { wxFAIL_MSG( wxT("wxTopLevelWindowGTK creation failed") ); return false; } m_title = title; // NB: m_widget may be !=NULL if it was created by derived class' Create, // e.g. in wxTaskBarIconAreaGTK if (m_widget == NULL) { m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) { // Tell WM that this is a dialog window and make it center // on parent by default (this is what GtkDialog ctor does): gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_window_set_position(GTK_WINDOW(m_widget), GTK_WIN_POS_CENTER_ON_PARENT); } else { if (style & wxFRAME_TOOL_WINDOW) { gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_UTILITY); // On some WMs, like KDE, a TOOL_WINDOW will still show // on the taskbar, but on Gnome a TOOL_WINDOW will not. // For consistency between WMs and with Windows, we // should set the NO_TASKBAR flag which will apply // the set_skip_taskbar_hint if it is available, // ensuring no taskbar entry will appear. style |= wxFRAME_NO_TASKBAR; } } g_object_ref(m_widget); } wxWindow *topParent = wxGetTopLevelParent(m_parent); if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) && (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) || (style & wxFRAME_FLOAT_ON_PARENT))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(topParent->m_widget) ); } if (style & wxFRAME_NO_TASKBAR) { gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE); } if (style & wxSTAY_ON_TOP) { gtk_window_set_keep_above(GTK_WINDOW(m_widget), TRUE); } if (style & wxMAXIMIZE) gtk_window_maximize(GTK_WINDOW(m_widget)); #if 0 if (!name.empty()) gtk_window_set_role( GTK_WINDOW(m_widget), wxGTK_CONV( name ) ); #endif gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) ); gtk_widget_set_can_focus(m_widget, false); g_signal_connect (m_widget, "delete_event", G_CALLBACK (gtk_frame_delete_callback), this); // m_mainWidget is a GtkVBox, holding the bars and client area (m_wxwindow) m_mainWidget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_widget_show( m_mainWidget ); gtk_widget_set_can_focus(m_mainWidget, false); gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget ); // m_wxwindow is the client area m_wxwindow = wxPizza::New(); gtk_widget_show( m_wxwindow ); gtk_box_pack_start(GTK_BOX(m_mainWidget), m_wxwindow, true, true, 0); // we donm't allow the frame to get the focus as otherwise // the frame will grab it at arbitrary focus changes gtk_widget_set_can_focus(m_wxwindow, false); if (m_parent) m_parent->AddChild( this ); g_signal_connect(m_wxwindow, "size_allocate", G_CALLBACK(size_allocate), this); PostCreation(); #ifndef __WXGTK3__ if (pos != wxDefaultPosition) gtk_widget_set_uposition( m_widget, m_x, m_y ); #endif // for some reported size corrections g_signal_connect (m_widget, "map_event", G_CALLBACK (gtk_frame_map_callback), this); // for iconized state g_signal_connect (m_widget, "window_state_event", G_CALLBACK (gtk_frame_window_state_callback), this); // for wxMoveEvent g_signal_connect (m_widget, "configure_event", G_CALLBACK (gtk_frame_configure_callback), this); // activation g_signal_connect_after (m_widget, "focus_in_event", G_CALLBACK (gtk_frame_focus_in_callback), this); g_signal_connect_after (m_widget, "focus_out_event", G_CALLBACK (gtk_frame_focus_out_callback), this); // We need to customize the default GTK+ logic for key processing to make // it conforming to wxWidgets event processing order. g_signal_connect (m_widget, "key_press_event", G_CALLBACK (wxgtk_tlw_key_press_event), NULL); #ifdef GDK_WINDOWING_X11 #ifdef __WXGTK3__ if (GDK_IS_X11_SCREEN(gtk_window_get_screen(GTK_WINDOW(m_widget)))) #endif { gtk_widget_add_events(m_widget, GDK_PROPERTY_CHANGE_MASK); g_signal_connect(m_widget, "property_notify_event", G_CALLBACK(property_notify_event), this); } #endif // GDK_WINDOWING_X11 // translate wx decorations styles into Motif WM hints (they are recognized // by other WMs as well) // always enable moving the window as we have no separate flag for enabling // it m_gdkFunc = GDK_FUNC_MOVE; if ( style & wxCLOSE_BOX ) m_gdkFunc |= GDK_FUNC_CLOSE; if ( style & wxMINIMIZE_BOX ) m_gdkFunc |= GDK_FUNC_MINIMIZE; if ( style & wxMAXIMIZE_BOX ) m_gdkFunc |= GDK_FUNC_MAXIMIZE; if ( (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER) ) { m_gdkDecor = 0; gtk_window_set_decorated(GTK_WINDOW(m_widget), false); } else // have border { m_gdkDecor = GDK_DECOR_BORDER; if ( style & wxCAPTION ) m_gdkDecor |= GDK_DECOR_TITLE; #if defined(GDK_WINDOWING_WAYLAND) && GTK_CHECK_VERSION(3,10,0) else if ( GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(m_widget)) && gtk_check_version(3,10,0) == NULL) { gtk_window_set_titlebar(GTK_WINDOW(m_widget), gtk_header_bar_new()); } #endif if ( style & wxSYSTEM_MENU ) m_gdkDecor |= GDK_DECOR_MENU; if ( style & wxMINIMIZE_BOX ) m_gdkDecor |= GDK_DECOR_MINIMIZE; if ( style & wxMAXIMIZE_BOX ) m_gdkDecor |= GDK_DECOR_MAXIMIZE; if ( style & wxRESIZE_BORDER ) { m_gdkFunc |= GDK_FUNC_RESIZE; m_gdkDecor |= GDK_DECOR_RESIZEH; } } m_decorSize = GetCachedDecorSize(); int w, h; GTKDoGetSize(&w, &h); if (style & wxRESIZE_BORDER) { gtk_window_set_default_size(GTK_WINDOW(m_widget), w, h); #ifndef __WXGTK3__ gtk_window_set_policy(GTK_WINDOW(m_widget), 1, 1, 1); #endif } else { gtk_window_set_resizable(GTK_WINDOW(m_widget), false); // gtk_window_set_default_size() does not work for un-resizable windows, // unless you set the size hints, but that causes Ubuntu's WM to make // the window resizable even though GDK_FUNC_RESIZE is not set. gtk_widget_set_size_request(m_widget, w, h); } return true; }