]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/settings.cpp
fixing focus, fixes #9985
[wxWidgets.git] / src / gtk1 / settings.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
e7c80f9e 2// Name: src/gtk1/settings.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
9b0b5ba7 5// Modified by: Mart Raudsepp (GetMetric)
f96aa4d9
RR
6// Id: $Id$
7// Copyright: (c) 1998 Robert Roebling
65571936 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
14f355c2
VS
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
c801d85f 14#include "wx/settings.h"
e7c80f9e 15
ce5d92e1
WS
16#ifndef WX_PRECOMP
17 #include "wx/cmndata.h"
1832043f 18 #include "wx/toplevel.h"
ce5d92e1
WS
19#endif
20
2b5f62a0 21#include "wx/fontutil.h"
d06b34a7 22
aed8ac3f 23#include <gdk/gdk.h>
9b0b5ba7 24#include <gdk/gdkx.h>
d06b34a7 25#include <gdk/gdkprivate.h>
aed8ac3f 26#include <gtk/gtk.h>
83624f79 27
9b0b5ba7
RR
28#include <X11/Xatom.h>
29
c801d85f
KB
30#define SHIFT (8*(sizeof(short int)-sizeof(char)))
31
0ab5e0e8 32// ----------------------------------------------------------------------------
94a09ea5 33// wxSystemObjects
0ab5e0e8
VS
34// ----------------------------------------------------------------------------
35
94a09ea5 36struct wxSystemObjects
1ecc4d80 37{
c1ef87c3
VZ
38 wxColour m_colBtnFace,
39 m_colBtnShadow,
40 m_colBtnHighlight,
41 m_colHighlight,
42 m_colHighlightText,
43 m_colListBox,
9d6a9fdd 44 m_colBtnText,
c05cc2c7
RR
45 m_colMenuItemHighlight,
46 m_colTooltip,
47 m_colTooltipText;
c1ef87c3
VZ
48
49 wxFont m_fontSystem;
0ab5e0e8
VS
50};
51
94a09ea5 52static wxSystemObjects gs_objects;
c1ef87c3 53
0ab5e0e8
VS
54// ----------------------------------------------------------------------------
55// wxSystemSettings implementation
56// ----------------------------------------------------------------------------
a3622daa 57
643ccf62 58// kind of widget to use in GetColourFromGTKWidget
dbcbe229 59enum wxGtkWidgetType
643ccf62 60{
dbcbe229 61 wxGTK_BUTTON,
9d6a9fdd
RR
62 wxGTK_LIST,
63 wxGTK_MENUITEM
dbcbe229
VZ
64};
65
66// the colour we need
67enum wxGtkColourType
68{
69 wxGTK_FG,
70 wxGTK_BG,
71 wxGTK_BASE
643ccf62
VZ
72};
73
984152a6 74// wxSystemSettings::GetColour() helper: get the colours from a GTK+
643ccf62 75// widget style, return true if we did get them, false to use defaults
dbcbe229
VZ
76static bool GetColourFromGTKWidget(int& red, int& green, int& blue,
77 wxGtkWidgetType type = wxGTK_BUTTON,
78 GtkStateType state = GTK_STATE_NORMAL,
79 wxGtkColourType colour = wxGTK_BG)
643ccf62 80{
dbcbe229
VZ
81 GtkWidget *widget;
82 switch ( type )
83 {
84 default:
85 wxFAIL_MSG( _T("unexpected GTK widget type") );
86 // fall through
87
88 case wxGTK_BUTTON:
89 widget = gtk_button_new();
90 break;
91
92 case wxGTK_LIST:
93 widget = gtk_list_new();
e24b680c
VZ
94 break;
95
9d6a9fdd
RR
96 case wxGTK_MENUITEM:
97 widget = gtk_menu_item_new();
dbcbe229
VZ
98 }
99
643ccf62
VZ
100 GtkStyle *def = gtk_rc_get_style( widget );
101 if ( !def )
102 def = gtk_widget_get_default_style();
103
104 bool ok;
105 if ( def )
106 {
dbcbe229
VZ
107 GdkColor *col;
108 switch ( colour )
109 {
110 default:
111 wxFAIL_MSG( _T("unexpected GTK colour type") );
112 // fall through
113
114 case wxGTK_FG:
115 col = def->fg;
116 break;
117
118 case wxGTK_BG:
119 col = def->bg;
120 break;
121
122 case wxGTK_BASE:
123 col = def->base;
124 break;
125 }
126
3523b9cf
VZ
127 red = col[state].red;
128 green = col[state].green;
129 blue = col[state].blue;
643ccf62 130
e7c80f9e 131 ok = true;
643ccf62
VZ
132 }
133 else
134 {
e7c80f9e 135 ok = false;
643ccf62
VZ
136 }
137
138 gtk_widget_destroy( widget );
139
140 return ok;
141}
142
c05cc2c7
RR
143static void GetTooltipColors()
144{
145 GtkTooltips* tooltips = gtk_tooltips_new();
146 gtk_tooltips_force_window(tooltips);
147 gtk_widget_ensure_style(tooltips->tip_window);
148 GdkColor c = tooltips->tip_window->style->bg[GTK_STATE_NORMAL];
149 gs_objects.m_colTooltip = wxColor(c.red >> SHIFT, c.green >> SHIFT, c.blue >> SHIFT);
150 c = tooltips->tip_window->style->fg[GTK_STATE_NORMAL];
151 gs_objects.m_colTooltipText = wxColor(c.red >> SHIFT, c.green >> SHIFT, c.blue >> SHIFT);
152 gtk_object_sink(wx_reinterpret_cast(GtkObject*, tooltips));
153}
154
0ab5e0e8 155wxColour wxSystemSettingsNative::GetColour( wxSystemColour index )
c801d85f 156{
db434467 157 switch (index)
c801d85f 158 {
db434467
RR
159 case wxSYS_COLOUR_SCROLLBAR:
160 case wxSYS_COLOUR_BACKGROUND:
db434467
RR
161 case wxSYS_COLOUR_INACTIVECAPTION:
162 case wxSYS_COLOUR_MENU:
163 case wxSYS_COLOUR_WINDOWFRAME:
164 case wxSYS_COLOUR_ACTIVEBORDER:
165 case wxSYS_COLOUR_INACTIVEBORDER:
166 case wxSYS_COLOUR_BTNFACE:
221ed576 167 case wxSYS_COLOUR_MENUBAR:
5b211fbf 168 case wxSYS_COLOUR_3DLIGHT:
94a09ea5 169 if (!gs_objects.m_colBtnFace.Ok())
37d403aa 170 {
643ccf62 171 int red, green, blue;
dbcbe229 172 if ( !GetColourFromGTKWidget(red, green, blue) )
37d403aa 173 {
643ccf62
VZ
174 red =
175 green = 0;
176 blue = 0x9c40;
37d403aa 177 }
37d403aa 178
94a09ea5 179 gs_objects.m_colBtnFace = wxColour( red >> SHIFT,
c1ef87c3
VZ
180 green >> SHIFT,
181 blue >> SHIFT );
37d403aa 182 }
94a09ea5 183 return gs_objects.m_colBtnFace;
643ccf62 184
db434467 185 case wxSYS_COLOUR_WINDOW:
db434467 186 return *wxWHITE;
643ccf62 187
37d403aa 188 case wxSYS_COLOUR_3DDKSHADOW:
37d403aa 189 return *wxBLACK;
643ccf62 190
db434467
RR
191 case wxSYS_COLOUR_GRAYTEXT:
192 case wxSYS_COLOUR_BTNSHADOW:
37d403aa 193 //case wxSYS_COLOUR_3DSHADOW:
94a09ea5 194 if (!gs_objects.m_colBtnShadow.Ok())
37d403aa 195 {
984152a6 196 wxColour faceColour(GetColour(wxSYS_COLOUR_3DFACE));
94a09ea5 197 gs_objects.m_colBtnShadow =
c1ef87c3
VZ
198 wxColour((unsigned char) (faceColour.Red() * 0.666),
199 (unsigned char) (faceColour.Green() * 0.666),
200 (unsigned char) (faceColour.Blue() * 0.666));
db434467 201 }
643ccf62 202
94a09ea5 203 return gs_objects.m_colBtnShadow;
643ccf62 204
37d403aa
JS
205 case wxSYS_COLOUR_3DHIGHLIGHT:
206 //case wxSYS_COLOUR_BTNHIGHLIGHT:
37d403aa 207 return * wxWHITE;
643ccf62 208
db434467 209 case wxSYS_COLOUR_HIGHLIGHT:
94a09ea5 210 if (!gs_objects.m_colHighlight.Ok())
db434467 211 {
643ccf62 212 int red, green, blue;
dbcbe229
VZ
213 if ( !GetColourFromGTKWidget(red, green, blue,
214 wxGTK_BUTTON,
215 GTK_STATE_SELECTED) )
e6527f9d 216 {
643ccf62
VZ
217 red =
218 green = 0;
219 blue = 0x9c40;
e6527f9d 220 }
db434467 221
94a09ea5 222 gs_objects.m_colHighlight = wxColour( red >> SHIFT,
643ccf62
VZ
223 green >> SHIFT,
224 blue >> SHIFT );
db434467 225 }
94a09ea5 226 return gs_objects.m_colHighlight;
643ccf62 227
74f55195 228 case wxSYS_COLOUR_LISTBOX:
94a09ea5 229 if (!gs_objects.m_colListBox.Ok())
74f55195 230 {
643ccf62 231 int red, green, blue;
dbcbe229
VZ
232 if ( GetColourFromGTKWidget(red, green, blue,
233 wxGTK_LIST,
234 GTK_STATE_NORMAL,
235 wxGTK_BASE) )
74f55195 236 {
94a09ea5 237 gs_objects.m_colListBox = wxColour( red >> SHIFT,
643ccf62
VZ
238 green >> SHIFT,
239 blue >> SHIFT );
74f55195
VS
240 }
241 else
643ccf62 242 {
94a09ea5 243 gs_objects.m_colListBox = wxColour(*wxWHITE);
643ccf62 244 }
74f55195 245 }
94a09ea5 246 return gs_objects.m_colListBox;
643ccf62
VZ
247
248 case wxSYS_COLOUR_MENUTEXT:
249 case wxSYS_COLOUR_WINDOWTEXT:
250 case wxSYS_COLOUR_CAPTIONTEXT:
251 case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
252 case wxSYS_COLOUR_BTNTEXT:
94a09ea5 253 if (!gs_objects.m_colBtnText.Ok())
37d403aa 254 {
dbcbe229
VZ
255 int red, green, blue;
256 if ( !GetColourFromGTKWidget(red, green, blue,
257 wxGTK_BUTTON,
258 GTK_STATE_NORMAL,
259 wxGTK_FG) )
37d403aa 260 {
dbcbe229
VZ
261 red =
262 green =
263 blue = 0;
37d403aa 264 }
dbcbe229 265
94a09ea5 266 gs_objects.m_colBtnText = wxColour( red >> SHIFT,
dbcbe229
VZ
267 green >> SHIFT,
268 blue >> SHIFT );
37d403aa 269 }
94a09ea5 270 return gs_objects.m_colBtnText;
643ccf62 271
17d61cbf 272 case wxSYS_COLOUR_INFOBK:
c05cc2c7
RR
273 if (!gs_objects.m_colTooltip.Ok()) {
274 GetTooltipColors();
275 }
276 return gs_objects.m_colTooltip;
277
278 case wxSYS_COLOUR_INFOTEXT:
279 if (!gs_objects.m_colTooltipText.Ok()) {
280 GetTooltipColors();
281 }
282 return gs_objects.m_colTooltipText;
17d61cbf 283
643ccf62 284 case wxSYS_COLOUR_HIGHLIGHTTEXT:
94a09ea5 285 if (!gs_objects.m_colHighlightText.Ok())
643ccf62 286 {
984152a6 287 wxColour hclr = GetColour(wxSYS_COLOUR_HIGHLIGHT);
643ccf62 288 if (hclr.Red() > 200 && hclr.Green() > 200 && hclr.Blue() > 200)
94a09ea5 289 gs_objects.m_colHighlightText = wxColour(*wxBLACK);
643ccf62 290 else
94a09ea5 291 gs_objects.m_colHighlightText = wxColour(*wxWHITE);
643ccf62 292 }
94a09ea5 293 return gs_objects.m_colHighlightText;
643ccf62 294
643ccf62
VZ
295 case wxSYS_COLOUR_APPWORKSPACE:
296 return *wxWHITE; // ?
221ed576 297
9d6a9fdd
RR
298 case wxSYS_COLOUR_ACTIVECAPTION:
299 case wxSYS_COLOUR_MENUHILIGHT:
300 if (!gs_objects.m_colMenuItemHighlight.Ok())
301 {
302 int red, green, blue;
303 if ( !GetColourFromGTKWidget(red, green, blue,
304 wxGTK_MENUITEM,
305 GTK_STATE_SELECTED,
306 wxGTK_BG) )
307 {
308 red =
309 green =
310 blue = 0;
311 }
312
313 gs_objects.m_colMenuItemHighlight = wxColour( red >> SHIFT,
314 green >> SHIFT,
315 blue >> SHIFT );
316 }
317 return gs_objects.m_colMenuItemHighlight;
318
221ed576
VZ
319 case wxSYS_COLOUR_HOTLIGHT:
320 case wxSYS_COLOUR_GRADIENTACTIVECAPTION:
321 case wxSYS_COLOUR_GRADIENTINACTIVECAPTION:
221ed576
VZ
322 // TODO
323 return *wxBLACK;
324
325 case wxSYS_COLOUR_MAX:
326 default:
327 wxFAIL_MSG( _T("unknown system colour index") );
e24b680c 328 }
643ccf62 329
e24b680c 330 return *wxWHITE;
ff7b1510 331}
c801d85f 332
0ab5e0e8 333wxFont wxSystemSettingsNative::GetFont( wxSystemFont index )
c801d85f 334{
2d17d68f 335 switch (index)
c801d85f 336 {
2d17d68f
RR
337 case wxSYS_OEM_FIXED_FONT:
338 case wxSYS_ANSI_FIXED_FONT:
339 case wxSYS_SYSTEM_FIXED_FONT:
340 {
341 return *wxNORMAL_FONT;
342 }
343 case wxSYS_ANSI_VAR_FONT:
344 case wxSYS_SYSTEM_FONT:
345 case wxSYS_DEVICE_DEFAULT_FONT:
346 case wxSYS_DEFAULT_GUI_FONT:
347 {
94a09ea5 348 if (!gs_objects.m_fontSystem.Ok())
d06b34a7 349 {
94a09ea5 350 gs_objects.m_fontSystem = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
d06b34a7 351 }
94a09ea5 352 return gs_objects.m_fontSystem;
2d17d68f 353 }
c801d85f 354
0ab5e0e8
VS
355 default:
356 return wxNullFont;
357 }
c801d85f 358}
c801d85f 359
89954433
VZ
360int
361wxSystemSettingsNative::GetMetric(wxSystemMetric index, wxWindow* WXUNUSED(win))
c801d85f 362{
1ecc4d80
RR
363 switch (index)
364 {
9b0b5ba7
RR
365 case wxSYS_CURSOR_X:
366 case wxSYS_CURSOR_Y:
3cbab641 367 return 16;
9b0b5ba7 368
f618020a
MB
369 // MBN: ditto for icons
370 case wxSYS_ICON_X: return 32;
371 case wxSYS_ICON_Y: return 32;
9b0b5ba7
RR
372
373 case wxSYS_SCREEN_X:
3cbab641 374 return gdk_screen_width();
9b0b5ba7
RR
375
376 case wxSYS_SCREEN_Y:
3cbab641 377 return gdk_screen_height();
9b0b5ba7
RR
378
379 case wxSYS_HSCROLL_Y: return 15;
380 case wxSYS_VSCROLL_X: return 15;
381
382// a gtk1 implementation should be possible too if gtk2 efficiency/convenience functions aren't used
3cbab641 383#if 0
9b0b5ba7
RR
384 case wxSYS_CAPTION_Y:
385 if (!window)
386 // No realized window specified, and no implementation for that case yet.
387 return -1;
388
389 // Check if wm supports frame extents - we can't know the caption height if it does not.
390#if GTK_CHECK_VERSION(2,2,0)
391 if (!gtk_check_version(2,2,0))
392 {
393 if (!gdk_x11_screen_supports_net_wm_hint(
394 gdk_drawable_get_screen(window),
395 gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
396 return -1;
397 }
398 else
399#endif
400 {
401 if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
402 return -1;
403 }
404
405 wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
406 wxT("Asking for caption height of a non toplevel window") );
407
408 // Get the height of the top windowmanager border.
409 // This is the titlebar in most cases. The titlebar might be elsewhere, and
410 // we could check which is the thickest wm border to decide on which side the
411 // titlebar is, but this might lead to interesting behaviours in used code.
412 // Reconsider when we have a way to report to the user on which side it is.
413
414 Atom type;
415 gint format;
416 gulong nitems;
9b0b5ba7 417
5ac8ce9e
RR
418#if GTK_CHECK_VERSION(2,2,0)
419 if (!gtk_check_version(2,2,0))
420 {
421 gulong bytes_after;
422 success = (XGetWindowProperty (GDK_DISPLAY_XDISPLAY(gdk_drawable_get_display(window)),
9b0b5ba7
RR
423 GDK_WINDOW_XWINDOW(window),
424 gdk_x11_get_xatom_by_name_for_display (
425 gdk_drawable_get_display(window),
426 "_NET_FRAME_EXTENTS" ),
427 0, // left, right, top, bottom, CARDINAL[4]/32
428 G_MAXLONG, // size of long
429 false, // do not delete property
430 XA_CARDINAL, // 32 bit
431 &type, &format, &nitems, &bytes_after, &data
5ac8ce9e
RR
432 ) == Success);
433 }
434#endif
435 if (success)
9b0b5ba7
RR
436 {
437 int caption_height = -1;
438
439 if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 3) && (data))
440 {
441 long *borders;
442 borders = (long*)data;
443 caption_height = borders[2]; // top frame extent
444 }
445
446 if (data)
447 XFree(data);
448
449 return caption_height;
450 }
451
452 // Try a default approach without a window pointer, if possible
453 // ...
454
455 return -1;
456#endif // gtk2
457
458 case wxSYS_PENWINDOWS_PRESENT:
459 // No MS Windows for Pen computing extension available in X11 based gtk+.
460 return 0;
461
462 default:
1d451c5b 463 return -1; // metric is unknown
1ecc4d80 464 }
c67daf87 465}
253293c1 466
0ab5e0e8 467bool wxSystemSettingsNative::HasFeature(wxSystemFeature index)
253293c1
VS
468{
469 switch (index)
470 {
17a1ebd1 471 case wxSYS_CAN_ICONIZE_FRAME:
e7c80f9e 472 return false;
17a1ebd1 473
253293c1 474 case wxSYS_CAN_DRAW_FRAME_DECORATIONS:
e7c80f9e 475 return true;
17a1ebd1 476
253293c1 477 default:
e7c80f9e 478 return false;
253293c1
VS
479 }
480}